xref: /haiku/src/servers/app/stackandtile/SATGroup.h (revision 27f5d579244cd1e43a1469782e08642fdc14b7f2)
1*27f5d579SClemens Zeidler /*
2*27f5d579SClemens Zeidler  * Copyright 2010, Haiku.
3*27f5d579SClemens Zeidler  * Distributed under the terms of the MIT License.
4*27f5d579SClemens Zeidler  *
5*27f5d579SClemens Zeidler  * Authors:
6*27f5d579SClemens Zeidler  *		Clemens Zeidler <haiku@clemens-zeidler.de>
7*27f5d579SClemens Zeidler  */
8*27f5d579SClemens Zeidler #ifndef SAT_GROUP_H
9*27f5d579SClemens Zeidler #define SAT_GROUP_H
10*27f5d579SClemens Zeidler 
11*27f5d579SClemens Zeidler 
12*27f5d579SClemens Zeidler #include <Rect.h>
13*27f5d579SClemens Zeidler 
14*27f5d579SClemens Zeidler #include "ObjectList.h"
15*27f5d579SClemens Zeidler #include "Referenceable.h"
16*27f5d579SClemens Zeidler 
17*27f5d579SClemens Zeidler #include "LinearSpec.h"
18*27f5d579SClemens Zeidler 
19*27f5d579SClemens Zeidler 
20*27f5d579SClemens Zeidler class SATWindow;
21*27f5d579SClemens Zeidler class Tab;
22*27f5d579SClemens Zeidler class WindowArea;
23*27f5d579SClemens Zeidler 
24*27f5d579SClemens Zeidler typedef BObjectList<SATWindow> SATWindowList;
25*27f5d579SClemens Zeidler 
26*27f5d579SClemens Zeidler 
27*27f5d579SClemens Zeidler class Corner {
28*27f5d579SClemens Zeidler public:
29*27f5d579SClemens Zeidler 		enum info_t
30*27f5d579SClemens Zeidler 		{
31*27f5d579SClemens Zeidler 			kFree,
32*27f5d579SClemens Zeidler 			kUsed,
33*27f5d579SClemens Zeidler 			kNotDockable
34*27f5d579SClemens Zeidler 		};
35*27f5d579SClemens Zeidler 
36*27f5d579SClemens Zeidler 		enum position_t
37*27f5d579SClemens Zeidler 		{
38*27f5d579SClemens Zeidler 			kLeftTop = 0,
39*27f5d579SClemens Zeidler 			kRightTop = 1,
40*27f5d579SClemens Zeidler 			kLeftBottom = 2,
41*27f5d579SClemens Zeidler 			kRightBottom = 3
42*27f5d579SClemens Zeidler 		};
43*27f5d579SClemens Zeidler 
44*27f5d579SClemens Zeidler 						Corner();
45*27f5d579SClemens Zeidler 		void			Trace() const;
46*27f5d579SClemens Zeidler 
47*27f5d579SClemens Zeidler 		info_t			status;
48*27f5d579SClemens Zeidler 		WindowArea*		windowArea;
49*27f5d579SClemens Zeidler };
50*27f5d579SClemens Zeidler 
51*27f5d579SClemens Zeidler 
52*27f5d579SClemens Zeidler class Crossing : public BReferenceable {
53*27f5d579SClemens Zeidler public:
54*27f5d579SClemens Zeidler 								Crossing(Tab* vertical, Tab* horizontal);
55*27f5d579SClemens Zeidler 								~Crossing();
56*27f5d579SClemens Zeidler 
57*27f5d579SClemens Zeidler 			Corner*				GetCorner(Corner::position_t corner) const;
58*27f5d579SClemens Zeidler 			Corner*				GetOppositeCorner(
59*27f5d579SClemens Zeidler 									Corner::position_t corner) const;
60*27f5d579SClemens Zeidler 
61*27f5d579SClemens Zeidler 			Corner*				LeftTopCorner()
62*27f5d579SClemens Zeidler 									{ return &fCorners[Corner::kLeftTop]; }
63*27f5d579SClemens Zeidler 			Corner*				RightTopCorner()
64*27f5d579SClemens Zeidler 									{ return &fCorners[Corner::kRightTop]; }
65*27f5d579SClemens Zeidler 			Corner*				LeftBottomCorner()
66*27f5d579SClemens Zeidler 									{ return &fCorners[Corner::kLeftBottom]; }
67*27f5d579SClemens Zeidler 			Corner*				RightBottomCorner()
68*27f5d579SClemens Zeidler 									{ return &fCorners[Corner::kRightBottom]; }
69*27f5d579SClemens Zeidler 
70*27f5d579SClemens Zeidler 			Tab*				VerticalTab() const;
71*27f5d579SClemens Zeidler 			Tab*				HorizontalTab() const;
72*27f5d579SClemens Zeidler 
73*27f5d579SClemens Zeidler 			void				Trace() const;
74*27f5d579SClemens Zeidler private:
75*27f5d579SClemens Zeidler 		Corner		fCorners[4];
76*27f5d579SClemens Zeidler 
77*27f5d579SClemens Zeidler 		Tab*		fVerticalTab;
78*27f5d579SClemens Zeidler 		Tab*		fHorizontalTab;
79*27f5d579SClemens Zeidler };
80*27f5d579SClemens Zeidler 
81*27f5d579SClemens Zeidler 
82*27f5d579SClemens Zeidler typedef BObjectList<Constraint> ConstraintList;
83*27f5d579SClemens Zeidler class SATGroup;
84*27f5d579SClemens Zeidler 
85*27f5d579SClemens Zeidler typedef BObjectList<Crossing> CrossingList;
86*27f5d579SClemens Zeidler 
87*27f5d579SClemens Zeidler 
88*27f5d579SClemens Zeidler // make all coordinates positive needed for the solver
89*27f5d579SClemens Zeidler const float kMakePositiveOffset = 5000;
90*27f5d579SClemens Zeidler 
91*27f5d579SClemens Zeidler 
92*27f5d579SClemens Zeidler class Tab : public BReferenceable {
93*27f5d579SClemens Zeidler public:
94*27f5d579SClemens Zeidler 		enum orientation_t
95*27f5d579SClemens Zeidler 		{
96*27f5d579SClemens Zeidler 			kVertical,
97*27f5d579SClemens Zeidler 			kHorizontal
98*27f5d579SClemens Zeidler 		};
99*27f5d579SClemens Zeidler 
100*27f5d579SClemens Zeidler 								Tab(SATGroup* group, Variable* variable,
101*27f5d579SClemens Zeidler 									orientation_t orientation);
102*27f5d579SClemens Zeidler 								~Tab();
103*27f5d579SClemens Zeidler 
104*27f5d579SClemens Zeidler 			float				Position() const;
105*27f5d579SClemens Zeidler 			void				SetPosition(float position);
106*27f5d579SClemens Zeidler 			orientation_t		Orientation() const;
107*27f5d579SClemens Zeidler 			Variable*			Var() {	return fVariable;	}
108*27f5d579SClemens Zeidler 
109*27f5d579SClemens Zeidler 			//! Caller takes ownership of the constraint.
110*27f5d579SClemens Zeidler 			Constraint*			Connect(Variable* variable);
111*27f5d579SClemens Zeidler 
112*27f5d579SClemens Zeidler 			BReference<Crossing>	AddCrossing(Tab* tab);
113*27f5d579SClemens Zeidler 			bool				RemoveCrossing(Crossing* crossing);
114*27f5d579SClemens Zeidler 			int32				FindCrossingIndex(Tab* tab);
115*27f5d579SClemens Zeidler 			int32				FindCrossingIndex(float tabPosition);
116*27f5d579SClemens Zeidler 			Crossing*			FindCrossing(Tab* tab);
117*27f5d579SClemens Zeidler 			Crossing*			FindCrossing(float tabPosition);
118*27f5d579SClemens Zeidler 
119*27f5d579SClemens Zeidler 			const CrossingList*	GetCrossingList() const;
120*27f5d579SClemens Zeidler 
121*27f5d579SClemens Zeidler 	static	int					CompareFunction(const Tab* tab1,
122*27f5d579SClemens Zeidler 									const Tab* tab2);
123*27f5d579SClemens Zeidler 
124*27f5d579SClemens Zeidler private:
125*27f5d579SClemens Zeidler 			SATGroup*			fGroup;
126*27f5d579SClemens Zeidler 			Variable*			fVariable;
127*27f5d579SClemens Zeidler 			orientation_t		fOrientation;
128*27f5d579SClemens Zeidler 
129*27f5d579SClemens Zeidler 			CrossingList		fCrossingList;
130*27f5d579SClemens Zeidler };
131*27f5d579SClemens Zeidler 
132*27f5d579SClemens Zeidler 
133*27f5d579SClemens Zeidler class WindowArea : public BReferenceable {
134*27f5d579SClemens Zeidler public:
135*27f5d579SClemens Zeidler 								WindowArea(Crossing* leftTop,
136*27f5d579SClemens Zeidler 									Crossing* rightTop, Crossing* leftBottom,
137*27f5d579SClemens Zeidler 									Crossing* rightBottom);
138*27f5d579SClemens Zeidler 								~WindowArea();
139*27f5d579SClemens Zeidler 
140*27f5d579SClemens Zeidler 			bool				SetGroup(SATGroup* group);
141*27f5d579SClemens Zeidler 
142*27f5d579SClemens Zeidler 	const	SATWindowList&		WindowList() { return fWindowList; }
143*27f5d579SClemens Zeidler 	const	SATWindowList&		LayerOrder() { return fWindowLayerOrder; }
144*27f5d579SClemens Zeidler 			bool				MoveWindowToPosition(SATWindow* window,
145*27f5d579SClemens Zeidler 									int32 index);
146*27f5d579SClemens Zeidler 			SATWindow*			TopWindow();
147*27f5d579SClemens Zeidler 
148*27f5d579SClemens Zeidler 			Crossing*			LeftTopCrossing()
149*27f5d579SClemens Zeidler 									{ return fLeftTopCrossing.Get(); }
150*27f5d579SClemens Zeidler 			Crossing*			RightTopCrossing()
151*27f5d579SClemens Zeidler 									{ return fRightTopCrossing.Get(); }
152*27f5d579SClemens Zeidler 			Crossing*			LeftBottomCrossing()
153*27f5d579SClemens Zeidler 									{ return fLeftBottomCrossing.Get(); }
154*27f5d579SClemens Zeidler 			Crossing*			RightBottomCrossing()
155*27f5d579SClemens Zeidler 									{ return fRightBottomCrossing.Get(); }
156*27f5d579SClemens Zeidler 
157*27f5d579SClemens Zeidler 			Tab*				LeftTab();
158*27f5d579SClemens Zeidler 			Tab*				RightTab();
159*27f5d579SClemens Zeidler 			Tab*				TopTab();
160*27f5d579SClemens Zeidler 			Tab*				BottomTab();
161*27f5d579SClemens Zeidler 
162*27f5d579SClemens Zeidler 			BRect				Frame();
163*27f5d579SClemens Zeidler 
164*27f5d579SClemens Zeidler 			bool				PropagateToGroup(SATGroup* group);
165*27f5d579SClemens Zeidler 
166*27f5d579SClemens Zeidler 			bool				MoveToTopLayer(SATWindow* window);
167*27f5d579SClemens Zeidler 
168*27f5d579SClemens Zeidler private:
169*27f5d579SClemens Zeidler 		friend class SATGroup;
170*27f5d579SClemens Zeidler 			/*! SATGroup adds new windows to the area. */
171*27f5d579SClemens Zeidler 			bool				_AddWindow(SATWindow* window,
172*27f5d579SClemens Zeidler 									SATWindow* after = NULL);
173*27f5d579SClemens Zeidler 			/*! After the last window has been removed the WindowArea delete
174*27f5d579SClemens Zeidler 			himself and clean up all crossings. */
175*27f5d579SClemens Zeidler 			bool				_RemoveWindow(SATWindow* window);
176*27f5d579SClemens Zeidler 
177*27f5d579SClemens Zeidler 	inline	void				_InitCorners();
178*27f5d579SClemens Zeidler 	inline	void				_CleanupCorners();
179*27f5d579SClemens Zeidler 	inline	void				_SetToWindowCorner(Corner* corner);
180*27f5d579SClemens Zeidler 	inline	void				_SetToNeighbourCorner(Corner* neighbour);
181*27f5d579SClemens Zeidler 	inline	void				_UnsetWindowCorner(Corner* corner);
182*27f5d579SClemens Zeidler 		//! opponent is the other neighbour of the neighbour
183*27f5d579SClemens Zeidler 	inline	void				_UnsetNeighbourCorner(Corner* neighbour,
184*27f5d579SClemens Zeidler 									Corner* opponent);
185*27f5d579SClemens Zeidler 
186*27f5d579SClemens Zeidler 			// Find crossing by tab position in group and if not exist create
187*27f5d579SClemens Zeidler 			// it.
188*27f5d579SClemens Zeidler 			BReference<Crossing>	_CrossingByPosition(Crossing* crossing,
189*27f5d579SClemens Zeidler 										SATGroup* group);
190*27f5d579SClemens Zeidler 
191*27f5d579SClemens Zeidler 			SATGroup*			fGroup;
192*27f5d579SClemens Zeidler 
193*27f5d579SClemens Zeidler 			SATWindowList		fWindowList;
194*27f5d579SClemens Zeidler 
195*27f5d579SClemens Zeidler 			SATWindowList		fWindowLayerOrder;
196*27f5d579SClemens Zeidler 
197*27f5d579SClemens Zeidler 			BReference<Crossing>	fLeftTopCrossing;
198*27f5d579SClemens Zeidler 			BReference<Crossing>	fRightTopCrossing;
199*27f5d579SClemens Zeidler 			BReference<Crossing>	fLeftBottomCrossing;
200*27f5d579SClemens Zeidler 			BReference<Crossing>	fRightBottomCrossing;
201*27f5d579SClemens Zeidler };
202*27f5d579SClemens Zeidler 
203*27f5d579SClemens Zeidler 
204*27f5d579SClemens Zeidler typedef BObjectList<WindowArea> WindowAreaList;
205*27f5d579SClemens Zeidler typedef BObjectList<Tab> TabList;
206*27f5d579SClemens Zeidler 
207*27f5d579SClemens Zeidler class BMessage;
208*27f5d579SClemens Zeidler class StackAndTile;
209*27f5d579SClemens Zeidler 
210*27f5d579SClemens Zeidler 
211*27f5d579SClemens Zeidler class SATGroup : public BReferenceable {
212*27f5d579SClemens Zeidler public:
213*27f5d579SClemens Zeidler 		friend class Tab;
214*27f5d579SClemens Zeidler 		friend class WindowArea;
215*27f5d579SClemens Zeidler 		friend class GroupCookie;
216*27f5d579SClemens Zeidler 
217*27f5d579SClemens Zeidler 								SATGroup();
218*27f5d579SClemens Zeidler 								~SATGroup();
219*27f5d579SClemens Zeidler 
220*27f5d579SClemens Zeidler 			LinearSpec*			GetLinearSpec() { return &fLinearSpec; }
221*27f5d579SClemens Zeidler 
222*27f5d579SClemens Zeidler 			void				AdjustWindows(SATWindow* triggerWindow);
223*27f5d579SClemens Zeidler 
224*27f5d579SClemens Zeidler 			/*! Create a new WindowArea from the crossing and add the window. */
225*27f5d579SClemens Zeidler 			bool				AddWindow(SATWindow* window, Tab* left, Tab* top,
226*27f5d579SClemens Zeidler 									Tab* right, Tab* bottom);
227*27f5d579SClemens Zeidler 			/*! Add a window to an existing window area. */
228*27f5d579SClemens Zeidler 			bool				AddWindow(SATWindow* window, WindowArea* area,
229*27f5d579SClemens Zeidler 									SATWindow* after = NULL);
230*27f5d579SClemens Zeidler 			/*! If stayBelowMouse is true move the removed window below the
231*27f5d579SClemens Zeidler 			cursor if necessary. */
232*27f5d579SClemens Zeidler 			bool				RemoveWindow(SATWindow* window,
233*27f5d579SClemens Zeidler 									bool stayBelowMouse = true);
234*27f5d579SClemens Zeidler 			int32				CountItems();
235*27f5d579SClemens Zeidler 			SATWindow*			WindowAt(int32 index);
236*27f5d579SClemens Zeidler 
237*27f5d579SClemens Zeidler 			const WindowAreaList&	GetAreaList() { return fWindowAreaList; }
238*27f5d579SClemens Zeidler 
239*27f5d579SClemens Zeidler 			/*! \return a sorted tab list. */
240*27f5d579SClemens Zeidler 			const TabList*		HorizontalTabs();
241*27f5d579SClemens Zeidler 			const TabList*		VerticalTabs();
242*27f5d579SClemens Zeidler 
243*27f5d579SClemens Zeidler 			Tab*				FindHorizontalTab(float position);
244*27f5d579SClemens Zeidler 			Tab*				FindVerticalTab(float position);
245*27f5d579SClemens Zeidler 
246*27f5d579SClemens Zeidler 			void				WindowAreaRemoved(WindowArea* area);
247*27f5d579SClemens Zeidler 
248*27f5d579SClemens Zeidler 	static	status_t			RestoreGroup(const BMessage& archive,
249*27f5d579SClemens Zeidler 									StackAndTile* sat);
250*27f5d579SClemens Zeidler 			status_t			ArchiveGroup(BMessage& archive);
251*27f5d579SClemens Zeidler 
252*27f5d579SClemens Zeidler private:
253*27f5d579SClemens Zeidler 			BReference<Tab>		_AddHorizontalTab(float position = 0);
254*27f5d579SClemens Zeidler 			BReference<Tab>		_AddVerticalTab(float position = 0);
255*27f5d579SClemens Zeidler 
256*27f5d579SClemens Zeidler 			bool				_RemoveHorizontalTab(Tab* tab);
257*27f5d579SClemens Zeidler 			bool				_RemoveVerticalTab(Tab* tab);
258*27f5d579SClemens Zeidler 
259*27f5d579SClemens Zeidler 			Tab*				_FindTab(const TabList& list, float position);
260*27f5d579SClemens Zeidler 
261*27f5d579SClemens Zeidler 			void				_SplitGroupIfNecessary(
262*27f5d579SClemens Zeidler 									WindowArea* removedArea);
263*27f5d579SClemens Zeidler 			void				_FillNeighbourList(
264*27f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
265*27f5d579SClemens Zeidler 									WindowArea* area);
266*27f5d579SClemens Zeidler 			void				_LeftNeighbours(
267*27f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
268*27f5d579SClemens Zeidler 									WindowArea* window);
269*27f5d579SClemens Zeidler 			void				_TopNeighbours(
270*27f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
271*27f5d579SClemens Zeidler 									WindowArea* window);
272*27f5d579SClemens Zeidler 			void				_RightNeighbours(
273*27f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
274*27f5d579SClemens Zeidler 									WindowArea* window);
275*27f5d579SClemens Zeidler 			void				_BottomNeighbours(
276*27f5d579SClemens Zeidler 									WindowAreaList& neighbourWindows,
277*27f5d579SClemens Zeidler 									WindowArea* window);
278*27f5d579SClemens Zeidler 			bool				_FindConnectedGroup(WindowAreaList& seedList,
279*27f5d579SClemens Zeidler 									WindowArea* removedArea,
280*27f5d579SClemens Zeidler 									WindowAreaList& newGroup);
281*27f5d579SClemens Zeidler 			void				_FollowSeed(WindowArea* area, WindowArea* veto,
282*27f5d579SClemens Zeidler 									WindowAreaList& seedList,
283*27f5d579SClemens Zeidler 									WindowAreaList& newGroup);
284*27f5d579SClemens Zeidler 			void				_SpawnNewGroup(const WindowAreaList& newGroup);
285*27f5d579SClemens Zeidler 
286*27f5d579SClemens Zeidler 			void				_EnsureGroupIsOnScreen(SATGroup* group);
287*27f5d579SClemens Zeidler 	inline	void				_CallculateXOffset(BPoint& offset, BRect& frame,
288*27f5d579SClemens Zeidler 									BRect& screen);
289*27f5d579SClemens Zeidler 	inline	void				_CallculateYOffset(BPoint& offset, BRect& frame,
290*27f5d579SClemens Zeidler 									BRect& screen);
291*27f5d579SClemens Zeidler 
292*27f5d579SClemens Zeidler protected:
293*27f5d579SClemens Zeidler 			WindowAreaList		fWindowAreaList;
294*27f5d579SClemens Zeidler 			SATWindowList		fSATWindowList;
295*27f5d579SClemens Zeidler 
296*27f5d579SClemens Zeidler 			LinearSpec			fLinearSpec;
297*27f5d579SClemens Zeidler 
298*27f5d579SClemens Zeidler private:
299*27f5d579SClemens Zeidler 			TabList				fHorizontalTabs;
300*27f5d579SClemens Zeidler 			bool				fHorizontalTabsSorted;
301*27f5d579SClemens Zeidler 			TabList				fVerticalTabs;
302*27f5d579SClemens Zeidler 			bool				fVerticalTabsSorted;
303*27f5d579SClemens Zeidler };
304*27f5d579SClemens Zeidler 
305*27f5d579SClemens Zeidler 
306*27f5d579SClemens Zeidler typedef BObjectList<SATGroup> SATGroupList;
307*27f5d579SClemens Zeidler 
308*27f5d579SClemens Zeidler #endif
309