diff --git a/src/add-ons/decorators/SATDecorator/SATGroup.cpp b/src/add-ons/decorators/SATDecorator/SATGroup.cpp index af0ab7b6a6..8862f37399 100644 --- a/src/add-ons/decorators/SATDecorator/SATGroup.cpp +++ b/src/add-ons/decorators/SATDecorator/SATGroup.cpp @@ -9,13 +9,19 @@ #include "SATGroup.h" +#include + #include +#include #include "SATWindow.h" #include "StackAndTile.h" #include "Window.h" +using namespace std; + + WindowArea::WindowArea(Crossing* leftTop, Crossing* rightTop, Crossing* leftBottom, Crossing* rightBottom) : @@ -46,6 +52,9 @@ WindowArea::SetGroup(SATGroup* group) WindowArea::~WindowArea() { + if (fGroup) + fGroup->WindowAreaRemoved(this); + _CleanupCorners(); SetGroup(NULL); } @@ -706,8 +715,6 @@ SATGroup::RemoveWindow(SATWindow* window) if (!fSATWindowList.RemoveItem(window)) return false; - _SplitGroupIfNecessary(window); - WindowArea* area = window->GetWindowArea(); if (area) area->_RemoveWindow(window); @@ -784,6 +791,119 @@ SATGroup::AdjustWindows(SATWindow* triggerWindow) } +void +SATGroup::WindowAreaRemoved(WindowArea* area) +{ + _SplitGroupIfNecessary(area); +} + + +status_t +SATGroup::RestoreGroup(const BMessage& archive, StackAndTile* sat) +{ + // create new group + SATGroup* group = new (std::nothrow)SATGroup; + if (!group) + return B_NO_MEMORY; + BReference groupRef; + groupRef.SetTo(group, true); + + int32 nHTabs, nVTabs; + status_t status; + status = archive.FindInt32("htab_count", &nHTabs); + if (status != B_OK) + return status; + status = archive.FindInt32("vtab_count", &nVTabs); + if (status != B_OK) + return status; + + vector > tempHTabs; + for (int i = 0; i < nHTabs; i++) { + BReference tab = group->_AddHorizontalTab(); + if (!tab) + return B_NO_MEMORY; + tempHTabs.push_back(tab); + } + vector > tempVTabs; + for (int i = 0; i < nVTabs; i++) { + BReference tab = group->_AddVerticalTab(); + if (!tab) + return B_NO_MEMORY; + tempVTabs.push_back(tab); + } + + BMessage areaArchive; + for (int32 i = 0; archive.FindMessage("area", i, &areaArchive) == B_OK; + i++) { + uint32 leftTab, rightTab, topTab, bottomTab; + if (areaArchive.FindInt32("left_tab", (int32*)&leftTab) != B_OK + || areaArchive.FindInt32("right_tab", (int32*)&rightTab) != B_OK + || areaArchive.FindInt32("top_tab", (int32*)&topTab) != B_OK + || areaArchive.FindInt32("bottom_tab", (int32*)&bottomTab) != B_OK) + return B_ERROR; + + if (leftTab >= tempVTabs.size() || rightTab >= tempVTabs.size()) + return B_BAD_VALUE; + if (topTab >= tempHTabs.size() || bottomTab >= tempHTabs.size()) + return B_BAD_VALUE; + + Tab* left = tempVTabs[leftTab]; + Tab* right = tempVTabs[rightTab]; + Tab* top = tempHTabs[topTab]; + Tab* bottom = tempHTabs[bottomTab]; + + // adding windows to area + int64 windowId; + WindowArea* area = NULL; + for (int32 i = 0; + areaArchive.FindInt64("window", i, &windowId) == B_OK; i++) { + SATWindow* window = sat->FindSATWindow(windowId); + if (!window) + continue; + + if (area == NULL) { + if (!group->AddWindow(window, left, top, right, bottom)) + return B_ERROR; + area = window->GetWindowArea(); + } else { + if (!group->AddWindow(window, area)) + return B_ERROR; + } + } + } + return B_OK; +} + + +status_t +SATGroup::ArchiveGroup(BMessage& archive) +{ + archive.AddInt32("htab_count", fHorizontalTabs.CountItems()); + archive.AddInt32("vtab_count", fVerticalTabs.CountItems()); + + for (int i = 0; i < fWindowAreaList.CountItems(); i++) { + WindowArea* area = fWindowAreaList.ItemAt(i); + int32 leftTab = fVerticalTabs.IndexOf(area->LeftTab()); + int32 rightTab = fVerticalTabs.IndexOf(area->RightTab()); + int32 topTab = fHorizontalTabs.IndexOf(area->TopTab()); + int32 bottomTab = fHorizontalTabs.IndexOf(area->BottomTab()); + + BMessage areaMessage; + areaMessage.AddInt32("left_tab", leftTab); + areaMessage.AddInt32("right_tab", rightTab); + areaMessage.AddInt32("top_tab", topTab); + areaMessage.AddInt32("bottom_tab", bottomTab); + + const SATWindowList& windowList = area->WindowList(); + for (int a = 0; a < windowList.CountItems(); a++) + areaMessage.AddInt64("window", windowList.ItemAt(a)->Id()); + + archive.AddMessage("area", &areaMessage); + } + return B_OK; +} + + BReference SATGroup::_AddHorizontalTab(float position) { @@ -860,20 +980,19 @@ SATGroup::_FindTab(const TabList& list, float position) void -SATGroup::_SplitGroupIfNecessary(SATWindow* removedWindow) +SATGroup::_SplitGroupIfNecessary(WindowArea* removedArea) { // if there are windows stacked in the area we don't need to split - WindowArea* area = removedWindow->GetWindowArea(); - if (!area || area->WindowList().CountItems() > 1) + if (!removedArea || removedArea->WindowList().CountItems() > 1) return; WindowAreaList neighbourWindows; - _FillNeighbourList(neighbourWindows, removedWindow->GetWindowArea()); + _FillNeighbourList(neighbourWindows, removedArea); bool ownGroupProcessed = false; WindowAreaList newGroup; - while (_FindConnectedGroup(neighbourWindows, removedWindow, newGroup)) { + while (_FindConnectedGroup(neighbourWindows, removedArea, newGroup)) { STRACE_SAT("Connected group found; %i windows:\n", (int)newGroup.CountItems()); for (int i = 0; i < newGroup.CountItems(); i++) { @@ -903,8 +1022,6 @@ void SATGroup::_FillNeighbourList(WindowAreaList& neighbourWindows, WindowArea* area) { - if (!area) - return; _LeftNeighbours(neighbourWindows, area); _RightNeighbours(neighbourWindows, area); _TopNeighbours(neighbourWindows, area); @@ -1018,19 +1135,16 @@ SATGroup::_BottomNeighbours(WindowAreaList& neighbourWindows, bool -SATGroup::_FindConnectedGroup(WindowAreaList& seedList, - SATWindow* removedWindow, WindowAreaList& newGroup) +SATGroup::_FindConnectedGroup(WindowAreaList& seedList, WindowArea* removedArea, + WindowAreaList& newGroup) { if (seedList.CountItems() == 0) return false; - WindowArea* vetoArea = removedWindow->GetWindowArea(); - if (!vetoArea) - return false; WindowArea* area = seedList.RemoveItemAt(0); newGroup.AddItem(area); - _FollowSeed(area, vetoArea, seedList, newGroup); + _FollowSeed(area, removedArea, seedList, newGroup); return true; } diff --git a/src/add-ons/decorators/SATDecorator/SATGroup.h b/src/add-ons/decorators/SATDecorator/SATGroup.h index 8a36046bd5..df2b625094 100644 --- a/src/add-ons/decorators/SATDecorator/SATGroup.h +++ b/src/add-ons/decorators/SATDecorator/SATGroup.h @@ -133,7 +133,7 @@ public: Crossing* rightBottom); ~WindowArea(); - bool SetGroup(SATGroup* group); + bool SetGroup(SATGroup* group); const SATWindowList& WindowList() { return fWindowList; } const SATWindowList& LayerOrder() { return fWindowLayerOrder; } @@ -200,6 +200,9 @@ private: typedef BObjectList WindowAreaList; typedef BObjectList TabList; +class BMessage; +class StackAndTile; + class SATGroup : public BReferenceable { public: @@ -233,6 +236,12 @@ public: Tab* FindHorizontalTab(float position); Tab* FindVerticalTab(float position); + void WindowAreaRemoved(WindowArea* area); + + static status_t RestoreGroup(const BMessage& archive, + StackAndTile* sat); + status_t ArchiveGroup(BMessage& archive); + private: BReference _AddHorizontalTab(float position = 0); BReference _AddVerticalTab(float position = 0); @@ -243,7 +252,7 @@ private: Tab* _FindTab(const TabList& list, float position); void _SplitGroupIfNecessary( - SATWindow* removedWindow); + WindowArea* removedArea); void _FillNeighbourList( WindowAreaList& neighbourWindows, WindowArea* area); @@ -260,7 +269,7 @@ private: WindowAreaList& neighbourWindows, WindowArea* window); bool _FindConnectedGroup(WindowAreaList& seedList, - SATWindow* removedWindow, + WindowArea* removedArea, WindowAreaList& newGroup); void _FollowSeed(WindowArea* area, WindowArea* veto, WindowAreaList& seedList, diff --git a/src/add-ons/decorators/SATDecorator/SATWindow.cpp b/src/add-ons/decorators/SATDecorator/SATWindow.cpp index 366d284549..468c58b58b 100644 --- a/src/add-ons/decorators/SATDecorator/SATWindow.cpp +++ b/src/add-ons/decorators/SATDecorator/SATWindow.cpp @@ -289,6 +289,8 @@ SATWindow::SATWindow(StackAndTile* sat, Window* window) fSATTiling(this), fShutdown(false) { + fId = _GenerateId(); + fDesktop = fWindow->Desktop(); fGroupCookie = &fOwnGroupCookie; @@ -680,6 +682,29 @@ SATWindow::TabLocationMoved(float location, bool shifting) } +uint64 +SATWindow::Id() +{ + return fId; +} + + +bool +SATWindow::SetSettings(const BMessage& message) +{ + if (message.FindInt64("window_id", (int64*)&fId) != B_OK) + return false; + return true; +} + + +void +SATWindow::GetSettings(BMessage& message) +{ + message.AddInt64("window_id", fId); +} + + void SATWindow::_InitGroup() { @@ -744,3 +769,13 @@ SATWindow::_UpdateSizeLimits() fGroupCookie->SetSizeLimits(minWidth, B_SIZE_UNLIMITED, minHeight, B_SIZE_UNLIMITED); } + + +uint64 +SATWindow::_GenerateId() +{ + bigtime_t time = real_time_clock_usecs(); + srand(time); + int16 randNumber = rand(); + return (time & ~0xFFFF) | randNumber; +} diff --git a/src/add-ons/decorators/SATDecorator/SATWindow.h b/src/add-ons/decorators/SATDecorator/SATWindow.h index 69db21eca2..cb0120f97a 100644 --- a/src/add-ons/decorators/SATDecorator/SATWindow.h +++ b/src/add-ons/decorators/SATDecorator/SATWindow.h @@ -128,9 +128,14 @@ public: bool SetStackedTabMoving(bool moving = true); void TabLocationMoved(float location, bool shifting); + uint64 Id(); + + bool SetSettings(const BMessage& message); + void GetSettings(BMessage& message); private: void _InitGroup(); void _UpdateSizeLimits(); + uint64 _GenerateId(); Window* fWindow; StackAndTile* fStackAndTile; @@ -158,6 +163,8 @@ private: float fOriginalWidth; float fOriginalHeight; + + uint64 fId; }; diff --git a/src/add-ons/decorators/SATDecorator/StackAndTile.cpp b/src/add-ons/decorators/SATDecorator/StackAndTile.cpp index 97b9d933d2..ee7d49103b 100644 --- a/src/add-ons/decorators/SATDecorator/StackAndTile.cpp +++ b/src/add-ons/decorators/SATDecorator/StackAndTile.cpp @@ -334,8 +334,7 @@ StackAndTile::SetDecoratorSettings(Window* window, const BMessage& settings) if (!satWindow) return false; - //return satWindow->SetSettings(settings); - return false; + return satWindow->SetSettings(settings); } @@ -346,7 +345,7 @@ StackAndTile::GetDecoratorSettings(Window* window, BMessage& settings) if (!satWindow) return; - //satWindow->GetSettings(&settings); + satWindow->GetSettings(settings); } @@ -358,16 +357,26 @@ StackAndTile::GetSATWindow(Window* window) if (it != fSATWindowMap.end()) return it->second; - // for now don't create window on the fly - return NULL; // If we don't know this window, memory allocation might has been failed - // previously. Try to add window now -/* SATWindow* satWindow = new (std::nothrow)SATWindow( - window, this); + // previously. Try to add the window now. + SATWindow* satWindow = new (std::nothrow)SATWindow(this, window); if (satWindow) fSATWindowMap[window] = satWindow; - return satWindow;*/ + return satWindow; +} + + +SATWindow* +StackAndTile::FindSATWindow(uint64 id) +{ + for (SATWindowMap::const_iterator it = fSATWindowMap.begin(); + it != fSATWindowMap.end(); it++) { + SATWindow* window = it->second; + if (window->Id() == id) + return window; + } + return NULL; } diff --git a/src/add-ons/decorators/SATDecorator/StackAndTile.h b/src/add-ons/decorators/SATDecorator/StackAndTile.h index a8813ff643..b5f44b01de 100644 --- a/src/add-ons/decorators/SATDecorator/StackAndTile.h +++ b/src/add-ons/decorators/SATDecorator/StackAndTile.h @@ -89,6 +89,7 @@ public: { return fSATKeyPressed; } SATWindow* GetSATWindow(Window* window); + SATWindow* FindSATWindow(uint64 id); private: void _StartSAT();