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 22class SATWindow; 23class Tab; 24class WindowArea; 25 26typedef BObjectList<SATWindow> SATWindowList; 27 28 29class Corner { 30public: 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 54class Crossing : public BReferenceable { 55public: 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; 76private: 77 Corner fCorners[4]; 78 79 BReference<Tab> fVerticalTab; 80 BReference<Tab> fHorizontalTab; 81}; 82 83 84typedef BObjectList<Constraint> ConstraintList; 85class SATGroup; 86 87typedef BObjectList<Crossing> CrossingList; 88 89 90// make all coordinates positive needed for the solver 91const float kMakePositiveOffset = 5000; 92 93 94class Tab : public BReferenceable { 95public: 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 126private: 127 SATGroup* fGroup; 128 Variable* fVariable; 129 orientation_t fOrientation; 130 131 CrossingList fCrossingList; 132}; 133 134 135class WindowArea : public BReferenceable { 136public: 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 180private: 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* fWidthConstraint; 224 Constraint* fHeightConstraint; 225 226 MagneticBorder fMagneticBorder; 227}; 228 229 230typedef BObjectList<WindowArea> WindowAreaList; 231typedef BObjectList<Tab> TabList; 232 233class BMessage; 234class StackAndTile; 235 236 237class SATGroup : public BReferenceable { 238public: 239 friend class Tab; 240 friend class WindowArea; 241 friend class GroupCookie; 242 243 SATGroup(); 244 ~SATGroup(); 245 246 LinearSpec* GetLinearSpec() { return &fLinearSpec; } 247 248 /*! Create a new WindowArea from the crossing and add the window. */ 249 bool AddWindow(SATWindow* window, Tab* left, Tab* top, 250 Tab* right, Tab* bottom); 251 /*! Add a window to an existing window area. */ 252 bool AddWindow(SATWindow* window, WindowArea* area, 253 SATWindow* after = NULL); 254 /*! If stayBelowMouse is true move the removed window below the 255 cursor if necessary. */ 256 bool RemoveWindow(SATWindow* window, 257 bool stayBelowMouse = true); 258 int32 CountItems(); 259 SATWindow* WindowAt(int32 index); 260 261 const WindowAreaList& GetAreaList() { return fWindowAreaList; } 262 263 /*! \return a sorted tab list. */ 264 const TabList* HorizontalTabs(); 265 const TabList* VerticalTabs(); 266 267 Tab* FindHorizontalTab(float position); 268 Tab* FindVerticalTab(float position); 269 270 void WindowAreaRemoved(WindowArea* area); 271 272 static status_t RestoreGroup(const BMessage& archive, 273 StackAndTile* sat); 274 status_t ArchiveGroup(BMessage& archive); 275 276private: 277 BReference<Tab> _AddHorizontalTab(float position = 0); 278 BReference<Tab> _AddVerticalTab(float position = 0); 279 280 bool _RemoveHorizontalTab(Tab* tab); 281 bool _RemoveVerticalTab(Tab* tab); 282 283 Tab* _FindTab(const TabList& list, float position); 284 285 void _SplitGroupIfNecessary( 286 WindowArea* removedArea); 287 void _FillNeighbourList( 288 WindowAreaList& neighbourWindows, 289 WindowArea* area); 290 void _LeftNeighbours( 291 WindowAreaList& neighbourWindows, 292 WindowArea* window); 293 void _TopNeighbours( 294 WindowAreaList& neighbourWindows, 295 WindowArea* window); 296 void _RightNeighbours( 297 WindowAreaList& neighbourWindows, 298 WindowArea* window); 299 void _BottomNeighbours( 300 WindowAreaList& neighbourWindows, 301 WindowArea* window); 302 bool _FindConnectedGroup(WindowAreaList& seedList, 303 WindowArea* removedArea, 304 WindowAreaList& newGroup); 305 void _FollowSeed(WindowArea* area, WindowArea* veto, 306 WindowAreaList& seedList, 307 WindowAreaList& newGroup); 308 void _SpawnNewGroup(const WindowAreaList& newGroup); 309 310 void _EnsureGroupIsOnScreen(SATGroup* group); 311 inline void _CallculateXOffset(BPoint& offset, BRect& frame, 312 BRect& screen); 313 inline void _CallculateYOffset(BPoint& offset, BRect& frame, 314 BRect& screen); 315 316protected: 317 WindowAreaList fWindowAreaList; 318 SATWindowList fSATWindowList; 319 320 LinearSpec fLinearSpec; 321 322private: 323 TabList fHorizontalTabs; 324 bool fHorizontalTabsSorted; 325 TabList fVerticalTabs; 326 bool fVerticalTabsSorted; 327}; 328 329 330typedef BObjectList<SATGroup> SATGroupList; 331 332#endif 333