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