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