xref: /haiku/src/servers/app/stackandtile/SATGroup.h (revision d99d8dbdd291ce586abc97b973626acfe138f12f)
127f5d579SClemens Zeidler /*
2fb6ab24aSJohn Scipione  * Copyright 2010-2014 Haiku, Inc. All rights reserved.
327f5d579SClemens Zeidler  * Distributed under the terms of the MIT License.
427f5d579SClemens Zeidler  *
527f5d579SClemens Zeidler  * Authors:
6fb6ab24aSJohn Scipione  *		John Scipione, jscipione@gmail.com
7fb6ab24aSJohn Scipione  *		Clemens Zeidler, haiku@clemens-zeidler.de
827f5d579SClemens Zeidler  */
927f5d579SClemens Zeidler #ifndef SAT_GROUP_H
1027f5d579SClemens Zeidler #define SAT_GROUP_H
1127f5d579SClemens Zeidler 
1227f5d579SClemens Zeidler 
1327f5d579SClemens Zeidler #include <Rect.h>
1427f5d579SClemens Zeidler 
15*d99d8dbdSX512 #include <AutoDeleter.h>
1627f5d579SClemens Zeidler #include "ObjectList.h"
1727f5d579SClemens Zeidler #include "Referenceable.h"
1827f5d579SClemens Zeidler 
19e0bc3d9eSClemens Zeidler #include "MagneticBorder.h"
20e0bc3d9eSClemens Zeidler 
2127f5d579SClemens Zeidler #include "LinearSpec.h"
2227f5d579SClemens Zeidler 
2327f5d579SClemens Zeidler 
2427f5d579SClemens Zeidler class SATWindow;
2527f5d579SClemens Zeidler class Tab;
2627f5d579SClemens Zeidler class WindowArea;
2727f5d579SClemens Zeidler 
2827f5d579SClemens Zeidler typedef BObjectList<SATWindow> SATWindowList;
2927f5d579SClemens Zeidler 
3027f5d579SClemens Zeidler 
3127f5d579SClemens Zeidler class Corner {
3227f5d579SClemens Zeidler public:
3327f5d579SClemens Zeidler 		enum info_t
3427f5d579SClemens Zeidler 		{
3527f5d579SClemens Zeidler 			kFree,
3627f5d579SClemens Zeidler 			kUsed,
3727f5d579SClemens Zeidler 			kNotDockable
3827f5d579SClemens Zeidler 		};
3927f5d579SClemens Zeidler 
4027f5d579SClemens Zeidler 		enum position_t
4127f5d579SClemens Zeidler 		{
4227f5d579SClemens Zeidler 			kLeftTop = 0,
4327f5d579SClemens Zeidler 			kRightTop = 1,
4427f5d579SClemens Zeidler 			kLeftBottom = 2,
4527f5d579SClemens Zeidler 			kRightBottom = 3
4627f5d579SClemens Zeidler 		};
4727f5d579SClemens Zeidler 
4827f5d579SClemens Zeidler 						Corner();
4927f5d579SClemens Zeidler 		void			Trace() const;
5027f5d579SClemens Zeidler 
5127f5d579SClemens Zeidler 		info_t			status;
5227f5d579SClemens Zeidler 		WindowArea*		windowArea;
5327f5d579SClemens Zeidler };
5427f5d579SClemens Zeidler 
5527f5d579SClemens Zeidler 
5627f5d579SClemens Zeidler class Crossing : public BReferenceable {
5727f5d579SClemens Zeidler public:
5827f5d579SClemens Zeidler 								Crossing(Tab* vertical, Tab* horizontal);
5927f5d579SClemens Zeidler 								~Crossing();
6027f5d579SClemens Zeidler 
6127f5d579SClemens Zeidler 			Corner*				GetCorner(Corner::position_t corner) const;
6227f5d579SClemens Zeidler 			Corner*				GetOppositeCorner(
6327f5d579SClemens Zeidler 									Corner::position_t corner) const;
6427f5d579SClemens Zeidler 
LeftTopCorner()6527f5d579SClemens Zeidler 			Corner*				LeftTopCorner()
6627f5d579SClemens Zeidler 									{ return &fCorners[Corner::kLeftTop]; }
RightTopCorner()6727f5d579SClemens Zeidler 			Corner*				RightTopCorner()
6827f5d579SClemens Zeidler 									{ return &fCorners[Corner::kRightTop]; }
LeftBottomCorner()6927f5d579SClemens Zeidler 			Corner*				LeftBottomCorner()
7027f5d579SClemens Zeidler 									{ return &fCorners[Corner::kLeftBottom]; }
RightBottomCorner()7127f5d579SClemens Zeidler 			Corner*				RightBottomCorner()
7227f5d579SClemens Zeidler 									{ return &fCorners[Corner::kRightBottom]; }
7327f5d579SClemens Zeidler 
7427f5d579SClemens Zeidler 			Tab*				VerticalTab() const;
7527f5d579SClemens Zeidler 			Tab*				HorizontalTab() const;
7627f5d579SClemens Zeidler 
7727f5d579SClemens Zeidler 			void				Trace() const;
7827f5d579SClemens Zeidler private:
7927f5d579SClemens Zeidler 			Corner				fCorners[4];
8027f5d579SClemens Zeidler 
81e0bc3d9eSClemens Zeidler 			BReference<Tab>		fVerticalTab;
82e0bc3d9eSClemens Zeidler 			BReference<Tab>		fHorizontalTab;
8327f5d579SClemens Zeidler };
8427f5d579SClemens Zeidler 
8527f5d579SClemens Zeidler 
8627f5d579SClemens Zeidler typedef BObjectList<Constraint> ConstraintList;
8727f5d579SClemens Zeidler class SATGroup;
8827f5d579SClemens Zeidler 
8927f5d579SClemens Zeidler typedef BObjectList<Crossing> CrossingList;
9027f5d579SClemens Zeidler 
9127f5d579SClemens Zeidler 
9227f5d579SClemens Zeidler // make all coordinates positive needed for the solver
9327f5d579SClemens Zeidler const float kMakePositiveOffset = 5000;
9427f5d579SClemens Zeidler 
9527f5d579SClemens Zeidler 
9627f5d579SClemens Zeidler class Tab : public BReferenceable {
9727f5d579SClemens Zeidler public:
9827f5d579SClemens Zeidler 		enum orientation_t
9927f5d579SClemens Zeidler 		{
10027f5d579SClemens Zeidler 			kVertical,
10127f5d579SClemens Zeidler 			kHorizontal
10227f5d579SClemens Zeidler 		};
10327f5d579SClemens Zeidler 
10427f5d579SClemens Zeidler 								Tab(SATGroup* group, Variable* variable,
10527f5d579SClemens Zeidler 									orientation_t orientation);
10627f5d579SClemens Zeidler 								~Tab();
10727f5d579SClemens Zeidler 
10827f5d579SClemens Zeidler 			float				Position() const;
10927f5d579SClemens Zeidler 			void				SetPosition(float position);
11027f5d579SClemens Zeidler 			orientation_t		Orientation() const;
Var()111*d99d8dbdSX512 			Variable*			Var() {	return fVariable.Get(); }
11227f5d579SClemens Zeidler 
11327f5d579SClemens Zeidler 			//! Caller takes ownership of the constraint.
11427f5d579SClemens Zeidler 			Constraint*			Connect(Variable* variable);
11527f5d579SClemens Zeidler 
11627f5d579SClemens Zeidler 			BReference<Crossing>	AddCrossing(Tab* tab);
11727f5d579SClemens Zeidler 			bool				RemoveCrossing(Crossing* crossing);
11827f5d579SClemens Zeidler 			int32				FindCrossingIndex(Tab* tab);
11927f5d579SClemens Zeidler 			int32				FindCrossingIndex(float tabPosition);
12027f5d579SClemens Zeidler 			Crossing*			FindCrossing(Tab* tab);
12127f5d579SClemens Zeidler 			Crossing*			FindCrossing(float tabPosition);
12227f5d579SClemens Zeidler 
12327f5d579SClemens Zeidler 			const CrossingList*	GetCrossingList() const;
12427f5d579SClemens Zeidler 
12527f5d579SClemens Zeidler 	static	int					CompareFunction(const Tab* tab1,
12627f5d579SClemens Zeidler 									const Tab* tab2);
12727f5d579SClemens Zeidler 
12827f5d579SClemens Zeidler private:
12927f5d579SClemens Zeidler 			SATGroup*			fGroup;
130*d99d8dbdSX512 			ObjectDeleter<Variable>
131*d99d8dbdSX512 								fVariable;
13227f5d579SClemens Zeidler 			orientation_t		fOrientation;
13327f5d579SClemens Zeidler 
13427f5d579SClemens Zeidler 			CrossingList		fCrossingList;
13527f5d579SClemens Zeidler };
13627f5d579SClemens Zeidler 
13727f5d579SClemens Zeidler 
13827f5d579SClemens Zeidler class WindowArea : public BReferenceable {
13927f5d579SClemens Zeidler public:
14027f5d579SClemens Zeidler 								WindowArea(Crossing* leftTop,
14127f5d579SClemens Zeidler 									Crossing* rightTop, Crossing* leftBottom,
14227f5d579SClemens Zeidler 									Crossing* rightBottom);
14327f5d579SClemens Zeidler 								~WindowArea();
14427f5d579SClemens Zeidler 
145e0bc3d9eSClemens Zeidler 			bool				Init(SATGroup* group);
Group()146e0bc3d9eSClemens Zeidler 			SATGroup*			Group() { return fGroup; }
147e0bc3d9eSClemens Zeidler 
148e0bc3d9eSClemens Zeidler 			void				DoGroupLayout();
149e0bc3d9eSClemens Zeidler 			void				UpdateSizeLimits();
150e0bc3d9eSClemens Zeidler 			void				UpdateSizeConstaints(const BRect& frame);
15127f5d579SClemens Zeidler 
WindowList()15227f5d579SClemens Zeidler 	const	SATWindowList&		WindowList() { return fWindowList; }
LayerOrder()15327f5d579SClemens Zeidler 	const	SATWindowList&		LayerOrder() { return fWindowLayerOrder; }
15427f5d579SClemens Zeidler 			bool				MoveWindowToPosition(SATWindow* window,
15527f5d579SClemens Zeidler 									int32 index);
15627f5d579SClemens Zeidler 			SATWindow*			TopWindow();
15727f5d579SClemens Zeidler 
LeftTopCrossing()15827f5d579SClemens Zeidler 			Crossing*			LeftTopCrossing()
15927f5d579SClemens Zeidler 									{ return fLeftTopCrossing.Get(); }
RightTopCrossing()16027f5d579SClemens Zeidler 			Crossing*			RightTopCrossing()
16127f5d579SClemens Zeidler 									{ return fRightTopCrossing.Get(); }
LeftBottomCrossing()16227f5d579SClemens Zeidler 			Crossing*			LeftBottomCrossing()
16327f5d579SClemens Zeidler 									{ return fLeftBottomCrossing.Get(); }
RightBottomCrossing()16427f5d579SClemens Zeidler 			Crossing*			RightBottomCrossing()
16527f5d579SClemens Zeidler 									{ return fRightBottomCrossing.Get(); }
16627f5d579SClemens Zeidler 
16727f5d579SClemens Zeidler 			Tab*				LeftTab();
16827f5d579SClemens Zeidler 			Tab*				RightTab();
16927f5d579SClemens Zeidler 			Tab*				TopTab();
17027f5d579SClemens Zeidler 			Tab*				BottomTab();
17127f5d579SClemens Zeidler 
LeftVar()172e0bc3d9eSClemens Zeidler 			Variable*			LeftVar() { return LeftTab()->Var(); }
RightVar()173e0bc3d9eSClemens Zeidler 			Variable*			RightVar() { return RightTab()->Var(); }
TopVar()174e0bc3d9eSClemens Zeidler 			Variable*			TopVar() { return TopTab()->Var(); }
BottomVar()175e0bc3d9eSClemens Zeidler 			Variable*			BottomVar() { return BottomTab()->Var(); }
176e0bc3d9eSClemens Zeidler 
17727f5d579SClemens Zeidler 			BRect				Frame();
17827f5d579SClemens Zeidler 
17927f5d579SClemens Zeidler 			bool				PropagateToGroup(SATGroup* group);
18027f5d579SClemens Zeidler 
18127f5d579SClemens Zeidler 			bool				MoveToTopLayer(SATWindow* window);
18227f5d579SClemens Zeidler 
18327f5d579SClemens Zeidler private:
18427f5d579SClemens Zeidler 		friend class SATGroup;
185e0bc3d9eSClemens Zeidler 			void				_UninitConstraints();
186e0bc3d9eSClemens Zeidler 			void				_UpdateConstraintValues();
187e0bc3d9eSClemens Zeidler 
18827f5d579SClemens Zeidler 			/*! SATGroup adds new windows to the area. */
18927f5d579SClemens Zeidler 			bool				_AddWindow(SATWindow* window,
19027f5d579SClemens Zeidler 									SATWindow* after = NULL);
19127f5d579SClemens Zeidler 			/*! After the last window has been removed the WindowArea delete
19227f5d579SClemens Zeidler 			himself and clean up all crossings. */
19327f5d579SClemens Zeidler 			bool				_RemoveWindow(SATWindow* window);
19427f5d579SClemens Zeidler 
19527f5d579SClemens Zeidler 	inline	void				_InitCorners();
19627f5d579SClemens Zeidler 	inline	void				_CleanupCorners();
19727f5d579SClemens Zeidler 	inline	void				_SetToWindowCorner(Corner* corner);
19827f5d579SClemens Zeidler 	inline	void				_SetToNeighbourCorner(Corner* neighbour);
19927f5d579SClemens Zeidler 	inline	void				_UnsetWindowCorner(Corner* corner);
20027f5d579SClemens Zeidler 		//! opponent is the other neighbour of the neighbour
20127f5d579SClemens Zeidler 	inline	void				_UnsetNeighbourCorner(Corner* neighbour,
20227f5d579SClemens Zeidler 									Corner* opponent);
20327f5d579SClemens Zeidler 
20427f5d579SClemens Zeidler 			// Find crossing by tab position in group and if not exist create
20527f5d579SClemens Zeidler 			// it.
20627f5d579SClemens Zeidler 			BReference<Crossing>	_CrossingByPosition(Crossing* crossing,
20727f5d579SClemens Zeidler 										SATGroup* group);
20827f5d579SClemens Zeidler 
209e0bc3d9eSClemens Zeidler 			void				_MoveToSAT(SATWindow* topWindow);
210e0bc3d9eSClemens Zeidler 
211e0bc3d9eSClemens Zeidler 			BReference<SATGroup>	fGroup;
21227f5d579SClemens Zeidler 
21327f5d579SClemens Zeidler 			SATWindowList		fWindowList;
21427f5d579SClemens Zeidler 
21527f5d579SClemens Zeidler 			SATWindowList		fWindowLayerOrder;
21627f5d579SClemens Zeidler 
21727f5d579SClemens Zeidler 			BReference<Crossing>	fLeftTopCrossing;
21827f5d579SClemens Zeidler 			BReference<Crossing>	fRightTopCrossing;
21927f5d579SClemens Zeidler 			BReference<Crossing>	fLeftBottomCrossing;
22027f5d579SClemens Zeidler 			BReference<Crossing>	fRightBottomCrossing;
221e0bc3d9eSClemens Zeidler 
222e0bc3d9eSClemens Zeidler 			Constraint*			fMinWidthConstraint;
223e0bc3d9eSClemens Zeidler 			Constraint*			fMinHeightConstraint;
224e0bc3d9eSClemens Zeidler 			Constraint*			fMaxWidthConstraint;
225e0bc3d9eSClemens Zeidler 			Constraint*			fMaxHeightConstraint;
226e0bc3d9eSClemens Zeidler 			Constraint*			fWidthConstraint;
227e0bc3d9eSClemens Zeidler 			Constraint*			fHeightConstraint;
228e0bc3d9eSClemens Zeidler 
229e0bc3d9eSClemens Zeidler 			MagneticBorder		fMagneticBorder;
23027f5d579SClemens Zeidler };
23127f5d579SClemens Zeidler 
23227f5d579SClemens Zeidler 
23327f5d579SClemens Zeidler typedef BObjectList<WindowArea> WindowAreaList;
23427f5d579SClemens Zeidler typedef BObjectList<Tab> TabList;
23527f5d579SClemens Zeidler 
23627f5d579SClemens Zeidler class BMessage;
23727f5d579SClemens Zeidler class StackAndTile;
23827f5d579SClemens Zeidler 
23927f5d579SClemens Zeidler 
24027f5d579SClemens Zeidler class SATGroup : public BReferenceable {
24127f5d579SClemens Zeidler public:
24227f5d579SClemens Zeidler 		friend class Tab;
24327f5d579SClemens Zeidler 		friend class WindowArea;
24427f5d579SClemens Zeidler 		friend class GroupCookie;
24527f5d579SClemens Zeidler 
24627f5d579SClemens Zeidler 								SATGroup();
24727f5d579SClemens Zeidler 								~SATGroup();
24827f5d579SClemens Zeidler 
GetLinearSpec()2498bcd6904SAdrien Destugues 			LinearSpec*			GetLinearSpec() { return fLinearSpec; }
25027f5d579SClemens Zeidler 
25127f5d579SClemens Zeidler 			/*! Create a new WindowArea from the crossing and add the window. */
2523779f5cfSJohn Scipione 			bool				AddWindow(SATWindow* window, Tab* left,
2533779f5cfSJohn Scipione 									Tab* top, Tab* right, Tab* bottom);
25427f5d579SClemens Zeidler 			/*! Add a window to an existing window area. */
25527f5d579SClemens Zeidler 			bool				AddWindow(SATWindow* window, WindowArea* area,
25627f5d579SClemens Zeidler 									SATWindow* after = NULL);
25727f5d579SClemens Zeidler 			/*! If stayBelowMouse is true move the removed window below the
25827f5d579SClemens Zeidler 			cursor if necessary. */
25927f5d579SClemens Zeidler 			bool				RemoveWindow(SATWindow* window,
26027f5d579SClemens Zeidler 									bool stayBelowMouse = true);
26127f5d579SClemens Zeidler 			int32				CountItems();
26227f5d579SClemens Zeidler 			SATWindow*			WindowAt(int32 index);
26327f5d579SClemens Zeidler 
26494d4c319SJohn Scipione 			SATWindow*			ActiveWindow() const;
26594d4c319SJohn Scipione 			void				SetActiveWindow(SATWindow* window);
26694d4c319SJohn Scipione 
GetAreaList()26727f5d579SClemens Zeidler 			const WindowAreaList&	GetAreaList() { return fWindowAreaList; }
26827f5d579SClemens Zeidler 
26927f5d579SClemens Zeidler 			/*! \return a sorted tab list. */
27027f5d579SClemens Zeidler 			const TabList*		HorizontalTabs();
27127f5d579SClemens Zeidler 			const TabList*		VerticalTabs();
27227f5d579SClemens Zeidler 
27327f5d579SClemens Zeidler 			Tab*				FindHorizontalTab(float position);
27427f5d579SClemens Zeidler 			Tab*				FindVerticalTab(float position);
27527f5d579SClemens Zeidler 
27627f5d579SClemens Zeidler 			void				WindowAreaRemoved(WindowArea* area);
27727f5d579SClemens Zeidler 
27827f5d579SClemens Zeidler 	static	status_t			RestoreGroup(const BMessage& archive,
27927f5d579SClemens Zeidler 									StackAndTile* sat);
28027f5d579SClemens Zeidler 			status_t			ArchiveGroup(BMessage& archive);
28127f5d579SClemens Zeidler 
28227f5d579SClemens Zeidler private:
28327f5d579SClemens Zeidler 			BReference<Tab>		_AddHorizontalTab(float position = 0);
28427f5d579SClemens Zeidler 			BReference<Tab>		_AddVerticalTab(float position = 0);
28527f5d579SClemens Zeidler 
28627f5d579SClemens Zeidler 			bool				_RemoveHorizontalTab(Tab* tab);
28727f5d579SClemens Zeidler 			bool				_RemoveVerticalTab(Tab* tab);
28827f5d579SClemens Zeidler 
28927f5d579SClemens Zeidler 			Tab*				_FindTab(const TabList& list, float position);
29027f5d579SClemens Zeidler 
29127f5d579SClemens Zeidler 			void				_SplitGroupIfNecessary(
29227f5d579SClemens Zeidler 									WindowArea* removedArea);
29327f5d579SClemens Zeidler 			void				_FillNeighbourList(
29427f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
29527f5d579SClemens Zeidler 									WindowArea* area);
29627f5d579SClemens Zeidler 			void				_LeftNeighbours(
29727f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
29827f5d579SClemens Zeidler 									WindowArea* window);
29927f5d579SClemens Zeidler 			void				_TopNeighbours(
30027f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
30127f5d579SClemens Zeidler 									WindowArea* window);
30227f5d579SClemens Zeidler 			void				_RightNeighbours(
30327f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
30427f5d579SClemens Zeidler 									WindowArea* window);
30527f5d579SClemens Zeidler 			void				_BottomNeighbours(
30627f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
30727f5d579SClemens Zeidler 									WindowArea* window);
30827f5d579SClemens Zeidler 			bool				_FindConnectedGroup(WindowAreaList& seedList,
30927f5d579SClemens Zeidler 									WindowArea* removedArea,
31027f5d579SClemens Zeidler 									WindowAreaList& newGroup);
31127f5d579SClemens Zeidler 			void				_FollowSeed(WindowArea* area, WindowArea* veto,
31227f5d579SClemens Zeidler 									WindowAreaList& seedList,
31327f5d579SClemens Zeidler 									WindowAreaList& newGroup);
31427f5d579SClemens Zeidler 			void				_SpawnNewGroup(const WindowAreaList& newGroup);
31527f5d579SClemens Zeidler 
31627f5d579SClemens Zeidler 			void				_EnsureGroupIsOnScreen(SATGroup* group);
31727f5d579SClemens Zeidler 	inline	void				_CallculateXOffset(BPoint& offset, BRect& frame,
31827f5d579SClemens Zeidler 									BRect& screen);
31927f5d579SClemens Zeidler 	inline	void				_CallculateYOffset(BPoint& offset, BRect& frame,
32027f5d579SClemens Zeidler 									BRect& screen);
32127f5d579SClemens Zeidler 
32227f5d579SClemens Zeidler protected:
32327f5d579SClemens Zeidler 			WindowAreaList		fWindowAreaList;
32427f5d579SClemens Zeidler 			SATWindowList		fSATWindowList;
32527f5d579SClemens Zeidler 
3268bcd6904SAdrien Destugues 			LinearSpec*			fLinearSpec;
32727f5d579SClemens Zeidler 
32827f5d579SClemens Zeidler private:
32927f5d579SClemens Zeidler 			TabList				fHorizontalTabs;
33027f5d579SClemens Zeidler 			bool				fHorizontalTabsSorted;
33127f5d579SClemens Zeidler 			TabList				fVerticalTabs;
33227f5d579SClemens Zeidler 			bool				fVerticalTabsSorted;
33394d4c319SJohn Scipione 
33494d4c319SJohn Scipione 			SATWindow*			fActiveWindow;
33527f5d579SClemens Zeidler };
33627f5d579SClemens Zeidler 
33727f5d579SClemens Zeidler 
33827f5d579SClemens Zeidler typedef BObjectList<SATGroup> SATGroupList;
33927f5d579SClemens Zeidler 
34027f5d579SClemens Zeidler #endif
341