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