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