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