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