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