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