127f5d579SClemens Zeidler /* 2fb6ab24aSJohn Scipione * Copyright 2010-2014 Haiku, Inc. All rights reserved. 327f5d579SClemens Zeidler * Distributed under the terms of the MIT License. 427f5d579SClemens Zeidler * 527f5d579SClemens Zeidler * Authors: 6fb6ab24aSJohn Scipione * John Scipione, jscipione@gmail.com 7fb6ab24aSJohn Scipione * Clemens Zeidler, haiku@clemens-zeidler.de 827f5d579SClemens Zeidler */ 927f5d579SClemens Zeidler #ifndef SAT_GROUP_H 1027f5d579SClemens Zeidler #define SAT_GROUP_H 1127f5d579SClemens Zeidler 1227f5d579SClemens Zeidler 1327f5d579SClemens Zeidler #include <Rect.h> 1427f5d579SClemens Zeidler 15*d99d8dbdSX512 #include <AutoDeleter.h> 1627f5d579SClemens Zeidler #include "ObjectList.h" 1727f5d579SClemens Zeidler #include "Referenceable.h" 1827f5d579SClemens Zeidler 19e0bc3d9eSClemens Zeidler #include "MagneticBorder.h" 20e0bc3d9eSClemens Zeidler 2127f5d579SClemens Zeidler #include "LinearSpec.h" 2227f5d579SClemens Zeidler 2327f5d579SClemens Zeidler 2427f5d579SClemens Zeidler class SATWindow; 2527f5d579SClemens Zeidler class Tab; 2627f5d579SClemens Zeidler class WindowArea; 2727f5d579SClemens Zeidler 2827f5d579SClemens Zeidler typedef BObjectList<SATWindow> SATWindowList; 2927f5d579SClemens Zeidler 3027f5d579SClemens Zeidler 3127f5d579SClemens Zeidler class Corner { 3227f5d579SClemens Zeidler public: 3327f5d579SClemens Zeidler enum info_t 3427f5d579SClemens Zeidler { 3527f5d579SClemens Zeidler kFree, 3627f5d579SClemens Zeidler kUsed, 3727f5d579SClemens Zeidler kNotDockable 3827f5d579SClemens Zeidler }; 3927f5d579SClemens Zeidler 4027f5d579SClemens Zeidler enum position_t 4127f5d579SClemens Zeidler { 4227f5d579SClemens Zeidler kLeftTop = 0, 4327f5d579SClemens Zeidler kRightTop = 1, 4427f5d579SClemens Zeidler kLeftBottom = 2, 4527f5d579SClemens Zeidler kRightBottom = 3 4627f5d579SClemens Zeidler }; 4727f5d579SClemens Zeidler 4827f5d579SClemens Zeidler Corner(); 4927f5d579SClemens Zeidler void Trace() const; 5027f5d579SClemens Zeidler 5127f5d579SClemens Zeidler info_t status; 5227f5d579SClemens Zeidler WindowArea* windowArea; 5327f5d579SClemens Zeidler }; 5427f5d579SClemens Zeidler 5527f5d579SClemens Zeidler 5627f5d579SClemens Zeidler class Crossing : public BReferenceable { 5727f5d579SClemens Zeidler public: 5827f5d579SClemens Zeidler Crossing(Tab* vertical, Tab* horizontal); 5927f5d579SClemens Zeidler ~Crossing(); 6027f5d579SClemens Zeidler 6127f5d579SClemens Zeidler Corner* GetCorner(Corner::position_t corner) const; 6227f5d579SClemens Zeidler Corner* GetOppositeCorner( 6327f5d579SClemens Zeidler Corner::position_t corner) const; 6427f5d579SClemens Zeidler LeftTopCorner()6527f5d579SClemens Zeidler Corner* LeftTopCorner() 6627f5d579SClemens Zeidler { return &fCorners[Corner::kLeftTop]; } RightTopCorner()6727f5d579SClemens Zeidler Corner* RightTopCorner() 6827f5d579SClemens Zeidler { return &fCorners[Corner::kRightTop]; } LeftBottomCorner()6927f5d579SClemens Zeidler Corner* LeftBottomCorner() 7027f5d579SClemens Zeidler { return &fCorners[Corner::kLeftBottom]; } RightBottomCorner()7127f5d579SClemens Zeidler Corner* RightBottomCorner() 7227f5d579SClemens Zeidler { return &fCorners[Corner::kRightBottom]; } 7327f5d579SClemens Zeidler 7427f5d579SClemens Zeidler Tab* VerticalTab() const; 7527f5d579SClemens Zeidler Tab* HorizontalTab() const; 7627f5d579SClemens Zeidler 7727f5d579SClemens Zeidler void Trace() const; 7827f5d579SClemens Zeidler private: 7927f5d579SClemens Zeidler Corner fCorners[4]; 8027f5d579SClemens Zeidler 81e0bc3d9eSClemens Zeidler BReference<Tab> fVerticalTab; 82e0bc3d9eSClemens Zeidler BReference<Tab> fHorizontalTab; 8327f5d579SClemens Zeidler }; 8427f5d579SClemens Zeidler 8527f5d579SClemens Zeidler 8627f5d579SClemens Zeidler typedef BObjectList<Constraint> ConstraintList; 8727f5d579SClemens Zeidler class SATGroup; 8827f5d579SClemens Zeidler 8927f5d579SClemens Zeidler typedef BObjectList<Crossing> CrossingList; 9027f5d579SClemens Zeidler 9127f5d579SClemens Zeidler 9227f5d579SClemens Zeidler // make all coordinates positive needed for the solver 9327f5d579SClemens Zeidler const float kMakePositiveOffset = 5000; 9427f5d579SClemens Zeidler 9527f5d579SClemens Zeidler 9627f5d579SClemens Zeidler class Tab : public BReferenceable { 9727f5d579SClemens Zeidler public: 9827f5d579SClemens Zeidler enum orientation_t 9927f5d579SClemens Zeidler { 10027f5d579SClemens Zeidler kVertical, 10127f5d579SClemens Zeidler kHorizontal 10227f5d579SClemens Zeidler }; 10327f5d579SClemens Zeidler 10427f5d579SClemens Zeidler Tab(SATGroup* group, Variable* variable, 10527f5d579SClemens Zeidler orientation_t orientation); 10627f5d579SClemens Zeidler ~Tab(); 10727f5d579SClemens Zeidler 10827f5d579SClemens Zeidler float Position() const; 10927f5d579SClemens Zeidler void SetPosition(float position); 11027f5d579SClemens Zeidler orientation_t Orientation() const; Var()111*d99d8dbdSX512 Variable* Var() { return fVariable.Get(); } 11227f5d579SClemens Zeidler 11327f5d579SClemens Zeidler //! Caller takes ownership of the constraint. 11427f5d579SClemens Zeidler Constraint* Connect(Variable* variable); 11527f5d579SClemens Zeidler 11627f5d579SClemens Zeidler BReference<Crossing> AddCrossing(Tab* tab); 11727f5d579SClemens Zeidler bool RemoveCrossing(Crossing* crossing); 11827f5d579SClemens Zeidler int32 FindCrossingIndex(Tab* tab); 11927f5d579SClemens Zeidler int32 FindCrossingIndex(float tabPosition); 12027f5d579SClemens Zeidler Crossing* FindCrossing(Tab* tab); 12127f5d579SClemens Zeidler Crossing* FindCrossing(float tabPosition); 12227f5d579SClemens Zeidler 12327f5d579SClemens Zeidler const CrossingList* GetCrossingList() const; 12427f5d579SClemens Zeidler 12527f5d579SClemens Zeidler static int CompareFunction(const Tab* tab1, 12627f5d579SClemens Zeidler const Tab* tab2); 12727f5d579SClemens Zeidler 12827f5d579SClemens Zeidler private: 12927f5d579SClemens Zeidler SATGroup* fGroup; 130*d99d8dbdSX512 ObjectDeleter<Variable> 131*d99d8dbdSX512 fVariable; 13227f5d579SClemens Zeidler orientation_t fOrientation; 13327f5d579SClemens Zeidler 13427f5d579SClemens Zeidler CrossingList fCrossingList; 13527f5d579SClemens Zeidler }; 13627f5d579SClemens Zeidler 13727f5d579SClemens Zeidler 13827f5d579SClemens Zeidler class WindowArea : public BReferenceable { 13927f5d579SClemens Zeidler public: 14027f5d579SClemens Zeidler WindowArea(Crossing* leftTop, 14127f5d579SClemens Zeidler Crossing* rightTop, Crossing* leftBottom, 14227f5d579SClemens Zeidler Crossing* rightBottom); 14327f5d579SClemens Zeidler ~WindowArea(); 14427f5d579SClemens Zeidler 145e0bc3d9eSClemens Zeidler bool Init(SATGroup* group); Group()146e0bc3d9eSClemens Zeidler SATGroup* Group() { return fGroup; } 147e0bc3d9eSClemens Zeidler 148e0bc3d9eSClemens Zeidler void DoGroupLayout(); 149e0bc3d9eSClemens Zeidler void UpdateSizeLimits(); 150e0bc3d9eSClemens Zeidler void UpdateSizeConstaints(const BRect& frame); 15127f5d579SClemens Zeidler WindowList()15227f5d579SClemens Zeidler const SATWindowList& WindowList() { return fWindowList; } LayerOrder()15327f5d579SClemens Zeidler const SATWindowList& LayerOrder() { return fWindowLayerOrder; } 15427f5d579SClemens Zeidler bool MoveWindowToPosition(SATWindow* window, 15527f5d579SClemens Zeidler int32 index); 15627f5d579SClemens Zeidler SATWindow* TopWindow(); 15727f5d579SClemens Zeidler LeftTopCrossing()15827f5d579SClemens Zeidler Crossing* LeftTopCrossing() 15927f5d579SClemens Zeidler { return fLeftTopCrossing.Get(); } RightTopCrossing()16027f5d579SClemens Zeidler Crossing* RightTopCrossing() 16127f5d579SClemens Zeidler { return fRightTopCrossing.Get(); } LeftBottomCrossing()16227f5d579SClemens Zeidler Crossing* LeftBottomCrossing() 16327f5d579SClemens Zeidler { return fLeftBottomCrossing.Get(); } RightBottomCrossing()16427f5d579SClemens Zeidler Crossing* RightBottomCrossing() 16527f5d579SClemens Zeidler { return fRightBottomCrossing.Get(); } 16627f5d579SClemens Zeidler 16727f5d579SClemens Zeidler Tab* LeftTab(); 16827f5d579SClemens Zeidler Tab* RightTab(); 16927f5d579SClemens Zeidler Tab* TopTab(); 17027f5d579SClemens Zeidler Tab* BottomTab(); 17127f5d579SClemens Zeidler LeftVar()172e0bc3d9eSClemens Zeidler Variable* LeftVar() { return LeftTab()->Var(); } RightVar()173e0bc3d9eSClemens Zeidler Variable* RightVar() { return RightTab()->Var(); } TopVar()174e0bc3d9eSClemens Zeidler Variable* TopVar() { return TopTab()->Var(); } BottomVar()175e0bc3d9eSClemens Zeidler Variable* BottomVar() { return BottomTab()->Var(); } 176e0bc3d9eSClemens Zeidler 17727f5d579SClemens Zeidler BRect Frame(); 17827f5d579SClemens Zeidler 17927f5d579SClemens Zeidler bool PropagateToGroup(SATGroup* group); 18027f5d579SClemens Zeidler 18127f5d579SClemens Zeidler bool MoveToTopLayer(SATWindow* window); 18227f5d579SClemens Zeidler 18327f5d579SClemens Zeidler private: 18427f5d579SClemens Zeidler friend class SATGroup; 185e0bc3d9eSClemens Zeidler void _UninitConstraints(); 186e0bc3d9eSClemens Zeidler void _UpdateConstraintValues(); 187e0bc3d9eSClemens Zeidler 18827f5d579SClemens Zeidler /*! SATGroup adds new windows to the area. */ 18927f5d579SClemens Zeidler bool _AddWindow(SATWindow* window, 19027f5d579SClemens Zeidler SATWindow* after = NULL); 19127f5d579SClemens Zeidler /*! After the last window has been removed the WindowArea delete 19227f5d579SClemens Zeidler himself and clean up all crossings. */ 19327f5d579SClemens Zeidler bool _RemoveWindow(SATWindow* window); 19427f5d579SClemens Zeidler 19527f5d579SClemens Zeidler inline void _InitCorners(); 19627f5d579SClemens Zeidler inline void _CleanupCorners(); 19727f5d579SClemens Zeidler inline void _SetToWindowCorner(Corner* corner); 19827f5d579SClemens Zeidler inline void _SetToNeighbourCorner(Corner* neighbour); 19927f5d579SClemens Zeidler inline void _UnsetWindowCorner(Corner* corner); 20027f5d579SClemens Zeidler //! opponent is the other neighbour of the neighbour 20127f5d579SClemens Zeidler inline void _UnsetNeighbourCorner(Corner* neighbour, 20227f5d579SClemens Zeidler Corner* opponent); 20327f5d579SClemens Zeidler 20427f5d579SClemens Zeidler // Find crossing by tab position in group and if not exist create 20527f5d579SClemens Zeidler // it. 20627f5d579SClemens Zeidler BReference<Crossing> _CrossingByPosition(Crossing* crossing, 20727f5d579SClemens Zeidler SATGroup* group); 20827f5d579SClemens Zeidler 209e0bc3d9eSClemens Zeidler void _MoveToSAT(SATWindow* topWindow); 210e0bc3d9eSClemens Zeidler 211e0bc3d9eSClemens Zeidler BReference<SATGroup> fGroup; 21227f5d579SClemens Zeidler 21327f5d579SClemens Zeidler SATWindowList fWindowList; 21427f5d579SClemens Zeidler 21527f5d579SClemens Zeidler SATWindowList fWindowLayerOrder; 21627f5d579SClemens Zeidler 21727f5d579SClemens Zeidler BReference<Crossing> fLeftTopCrossing; 21827f5d579SClemens Zeidler BReference<Crossing> fRightTopCrossing; 21927f5d579SClemens Zeidler BReference<Crossing> fLeftBottomCrossing; 22027f5d579SClemens Zeidler BReference<Crossing> fRightBottomCrossing; 221e0bc3d9eSClemens Zeidler 222e0bc3d9eSClemens Zeidler Constraint* fMinWidthConstraint; 223e0bc3d9eSClemens Zeidler Constraint* fMinHeightConstraint; 224e0bc3d9eSClemens Zeidler Constraint* fMaxWidthConstraint; 225e0bc3d9eSClemens Zeidler Constraint* fMaxHeightConstraint; 226e0bc3d9eSClemens Zeidler Constraint* fWidthConstraint; 227e0bc3d9eSClemens Zeidler Constraint* fHeightConstraint; 228e0bc3d9eSClemens Zeidler 229e0bc3d9eSClemens Zeidler MagneticBorder fMagneticBorder; 23027f5d579SClemens Zeidler }; 23127f5d579SClemens Zeidler 23227f5d579SClemens Zeidler 23327f5d579SClemens Zeidler typedef BObjectList<WindowArea> WindowAreaList; 23427f5d579SClemens Zeidler typedef BObjectList<Tab> TabList; 23527f5d579SClemens Zeidler 23627f5d579SClemens Zeidler class BMessage; 23727f5d579SClemens Zeidler class StackAndTile; 23827f5d579SClemens Zeidler 23927f5d579SClemens Zeidler 24027f5d579SClemens Zeidler class SATGroup : public BReferenceable { 24127f5d579SClemens Zeidler public: 24227f5d579SClemens Zeidler friend class Tab; 24327f5d579SClemens Zeidler friend class WindowArea; 24427f5d579SClemens Zeidler friend class GroupCookie; 24527f5d579SClemens Zeidler 24627f5d579SClemens Zeidler SATGroup(); 24727f5d579SClemens Zeidler ~SATGroup(); 24827f5d579SClemens Zeidler GetLinearSpec()2498bcd6904SAdrien Destugues LinearSpec* GetLinearSpec() { return fLinearSpec; } 25027f5d579SClemens Zeidler 25127f5d579SClemens Zeidler /*! Create a new WindowArea from the crossing and add the window. */ 2523779f5cfSJohn Scipione bool AddWindow(SATWindow* window, Tab* left, 2533779f5cfSJohn Scipione Tab* top, Tab* right, Tab* bottom); 25427f5d579SClemens Zeidler /*! Add a window to an existing window area. */ 25527f5d579SClemens Zeidler bool AddWindow(SATWindow* window, WindowArea* area, 25627f5d579SClemens Zeidler SATWindow* after = NULL); 25727f5d579SClemens Zeidler /*! If stayBelowMouse is true move the removed window below the 25827f5d579SClemens Zeidler cursor if necessary. */ 25927f5d579SClemens Zeidler bool RemoveWindow(SATWindow* window, 26027f5d579SClemens Zeidler bool stayBelowMouse = true); 26127f5d579SClemens Zeidler int32 CountItems(); 26227f5d579SClemens Zeidler SATWindow* WindowAt(int32 index); 26327f5d579SClemens Zeidler 26494d4c319SJohn Scipione SATWindow* ActiveWindow() const; 26594d4c319SJohn Scipione void SetActiveWindow(SATWindow* window); 26694d4c319SJohn Scipione GetAreaList()26727f5d579SClemens Zeidler const WindowAreaList& GetAreaList() { return fWindowAreaList; } 26827f5d579SClemens Zeidler 26927f5d579SClemens Zeidler /*! \return a sorted tab list. */ 27027f5d579SClemens Zeidler const TabList* HorizontalTabs(); 27127f5d579SClemens Zeidler const TabList* VerticalTabs(); 27227f5d579SClemens Zeidler 27327f5d579SClemens Zeidler Tab* FindHorizontalTab(float position); 27427f5d579SClemens Zeidler Tab* FindVerticalTab(float position); 27527f5d579SClemens Zeidler 27627f5d579SClemens Zeidler void WindowAreaRemoved(WindowArea* area); 27727f5d579SClemens Zeidler 27827f5d579SClemens Zeidler static status_t RestoreGroup(const BMessage& archive, 27927f5d579SClemens Zeidler StackAndTile* sat); 28027f5d579SClemens Zeidler status_t ArchiveGroup(BMessage& archive); 28127f5d579SClemens Zeidler 28227f5d579SClemens Zeidler private: 28327f5d579SClemens Zeidler BReference<Tab> _AddHorizontalTab(float position = 0); 28427f5d579SClemens Zeidler BReference<Tab> _AddVerticalTab(float position = 0); 28527f5d579SClemens Zeidler 28627f5d579SClemens Zeidler bool _RemoveHorizontalTab(Tab* tab); 28727f5d579SClemens Zeidler bool _RemoveVerticalTab(Tab* tab); 28827f5d579SClemens Zeidler 28927f5d579SClemens Zeidler Tab* _FindTab(const TabList& list, float position); 29027f5d579SClemens Zeidler 29127f5d579SClemens Zeidler void _SplitGroupIfNecessary( 29227f5d579SClemens Zeidler WindowArea* removedArea); 29327f5d579SClemens Zeidler void _FillNeighbourList( 29427f5d579SClemens Zeidler WindowAreaList& neighbourWindows, 29527f5d579SClemens Zeidler WindowArea* area); 29627f5d579SClemens Zeidler void _LeftNeighbours( 29727f5d579SClemens Zeidler WindowAreaList& neighbourWindows, 29827f5d579SClemens Zeidler WindowArea* window); 29927f5d579SClemens Zeidler void _TopNeighbours( 30027f5d579SClemens Zeidler WindowAreaList& neighbourWindows, 30127f5d579SClemens Zeidler WindowArea* window); 30227f5d579SClemens Zeidler void _RightNeighbours( 30327f5d579SClemens Zeidler WindowAreaList& neighbourWindows, 30427f5d579SClemens Zeidler WindowArea* window); 30527f5d579SClemens Zeidler void _BottomNeighbours( 30627f5d579SClemens Zeidler WindowAreaList& neighbourWindows, 30727f5d579SClemens Zeidler WindowArea* window); 30827f5d579SClemens Zeidler bool _FindConnectedGroup(WindowAreaList& seedList, 30927f5d579SClemens Zeidler WindowArea* removedArea, 31027f5d579SClemens Zeidler WindowAreaList& newGroup); 31127f5d579SClemens Zeidler void _FollowSeed(WindowArea* area, WindowArea* veto, 31227f5d579SClemens Zeidler WindowAreaList& seedList, 31327f5d579SClemens Zeidler WindowAreaList& newGroup); 31427f5d579SClemens Zeidler void _SpawnNewGroup(const WindowAreaList& newGroup); 31527f5d579SClemens Zeidler 31627f5d579SClemens Zeidler void _EnsureGroupIsOnScreen(SATGroup* group); 31727f5d579SClemens Zeidler inline void _CallculateXOffset(BPoint& offset, BRect& frame, 31827f5d579SClemens Zeidler BRect& screen); 31927f5d579SClemens Zeidler inline void _CallculateYOffset(BPoint& offset, BRect& frame, 32027f5d579SClemens Zeidler BRect& screen); 32127f5d579SClemens Zeidler 32227f5d579SClemens Zeidler protected: 32327f5d579SClemens Zeidler WindowAreaList fWindowAreaList; 32427f5d579SClemens Zeidler SATWindowList fSATWindowList; 32527f5d579SClemens Zeidler 3268bcd6904SAdrien Destugues LinearSpec* fLinearSpec; 32727f5d579SClemens Zeidler 32827f5d579SClemens Zeidler private: 32927f5d579SClemens Zeidler TabList fHorizontalTabs; 33027f5d579SClemens Zeidler bool fHorizontalTabsSorted; 33127f5d579SClemens Zeidler TabList fVerticalTabs; 33227f5d579SClemens Zeidler bool fVerticalTabsSorted; 33394d4c319SJohn Scipione 33494d4c319SJohn Scipione SATWindow* fActiveWindow; 33527f5d579SClemens Zeidler }; 33627f5d579SClemens Zeidler 33727f5d579SClemens Zeidler 33827f5d579SClemens Zeidler typedef BObjectList<SATGroup> SATGroupList; 33927f5d579SClemens Zeidler 34027f5d579SClemens Zeidler #endif 341