From b7630c4c985e7b351678608448aa1d61ec7ff6b5 Mon Sep 17 00:00:00 2001 From: czeidler Date: Tue, 10 Jan 2012 17:43:58 +1300 Subject: [PATCH] Save and restore layout. --- headers/libs/alm/ALMLayout.h | 4 + src/libs/alm/ALMLayout.cpp | 149 +++++++++++++++++++++++++++++++++-- 2 files changed, 146 insertions(+), 7 deletions(-) diff --git a/headers/libs/alm/ALMLayout.h b/headers/libs/alm/ALMLayout.h index c542e36cce..e76ab143c9 100644 --- a/headers/libs/alm/ALMLayout.h +++ b/headers/libs/alm/ALMLayout.h @@ -67,6 +67,7 @@ public: Area* AreaFor(const BView* view) const; Area* AreaFor(const BLayoutItem* item) const; + int32 CountAreas() const; Area* AreaAt(int32 index) const; Area* CurrentArea() const; bool SetCurrentArea(const Area* area); @@ -122,6 +123,9 @@ public: YTab* bottom = NULL, XTab* left = NULL, XTab* right = NULL); + bool SaveLayout(BMessage* archive) const; + bool RestoreLayout(const BMessage* archive); + virtual BSize BaseMinSize(); virtual BSize BaseMaxSize(); virtual BSize BasePreferredSize(); diff --git a/src/libs/alm/ALMLayout.cpp b/src/libs/alm/ALMLayout.cpp index cf08519f98..dd569e225e 100644 --- a/src/libs/alm/ALMLayout.cpp +++ b/src/libs/alm/ALMLayout.cpp @@ -11,6 +11,7 @@ #include // for floor #include #include +#include #include "RowColumnManager.h" #include "ViewLayoutItem.h" @@ -129,8 +130,8 @@ BALMLayout::YTabAt(int32 index) const } -int -CompareXTabFunc(const XTab* tab1, const XTab* tab2) +static int +compare_x_tab_func(const XTab* tab1, const XTab* tab2) { if (tab1->Value() < tab2->Value()) return -1; @@ -140,8 +141,8 @@ CompareXTabFunc(const XTab* tab1, const XTab* tab2) } -int -CompareYTabFunc(const YTab* tab1, const YTab* tab2) +static int +compare_y_tab_func(const YTab* tab1, const YTab* tab2) { if (tab1->Value() < tab2->Value()) return -1; @@ -151,11 +152,10 @@ CompareYTabFunc(const YTab* tab1, const YTab* tab2) } - const XTabList& BALMLayout::OrderedXTabs() { - fXTabList.SortItems(CompareXTabFunc); + fXTabList.SortItems(compare_x_tab_func); return fXTabList; } @@ -163,7 +163,7 @@ BALMLayout::OrderedXTabs() const YTabList& BALMLayout::OrderedYTabs() { - fYTabList.SortItems(CompareYTabFunc); + fYTabList.SortItems(compare_y_tab_func); return fYTabList; } @@ -230,6 +230,13 @@ BALMLayout::AreaFor(const BLayoutItem* item) const } +int32 +BALMLayout::CountAreas() const +{ + return CountItems(); +} + + Area* BALMLayout::AreaAt(int32 index) const { @@ -670,6 +677,134 @@ BALMLayout::AddItemToBottom(BLayoutItem* item, YTab* _bottom, XTab* left, } +enum { + kLeftBorderIndex = -2, + kTopBorderIndex = -3, + kRightBorderIndex = -4, + kBottomBorderIndex = -5, +}; + + +bool +BALMLayout::SaveLayout(BMessage* archive) const +{ + archive->MakeEmpty(); + + archive->AddInt32("nXTabs", CountXTabs()); + archive->AddInt32("nYTabs", CountYTabs()); + + XTabList xTabs = fXTabList; + xTabs.RemoveItem(fLeft); + xTabs.RemoveItem(fRight); + YTabList yTabs = fYTabList; + yTabs.RemoveItem(fTop); + yTabs.RemoveItem(fBottom); + + int32 nAreas = CountAreas(); + for (int32 i = 0; i < nAreas; i++) { + Area* area = AreaAt(i); + if (area->Left() == fLeft) + archive->AddInt32("left", kLeftBorderIndex); + else + archive->AddInt32("left", xTabs.IndexOf(area->Left())); + if (area->Top() == fTop) + archive->AddInt32("top", kTopBorderIndex); + else + archive->AddInt32("top", yTabs.IndexOf(area->Top())); + if (area->Right() == fRight) + archive->AddInt32("right", kRightBorderIndex); + else + archive->AddInt32("right", xTabs.IndexOf(area->Right())); + if (area->Bottom() == fBottom) + archive->AddInt32("bottom", kBottomBorderIndex); + else + archive->AddInt32("bottom", yTabs.IndexOf(area->Bottom())); + } + return true; +} + + +bool +BALMLayout::RestoreLayout(const BMessage* archive) +{ + int32 neededXTabs; + int32 neededYTabs; + if (archive->FindInt32("nXTabs", &neededXTabs) != B_OK) + return false; + if (archive->FindInt32("nYTabs", &neededYTabs) != B_OK) + return false; + // First store a reference to all needed tabs otherwise they might get lost + // while editing the layout + std::vector > newXTabs; + std::vector > newYTabs; + int32 existingXTabs = fXTabList.CountItems(); + for (int32 i = 0; i < neededXTabs; i++) { + if (i < existingXTabs) + newXTabs.push_back(BReference(fXTabList.ItemAt(i))); + else + newXTabs.push_back(AddXTab()); + } + int32 existingYTabs = fYTabList.CountItems(); + for (int32 i = 0; i < neededYTabs; i++) { + if (i < existingYTabs) + newYTabs.push_back(BReference(fYTabList.ItemAt(i))); + else + newYTabs.push_back(AddYTab()); + } + + XTabList xTabs = fXTabList; + xTabs.RemoveItem(fLeft); + xTabs.RemoveItem(fRight); + YTabList yTabs = fYTabList; + yTabs.RemoveItem(fTop); + yTabs.RemoveItem(fBottom); + + int32 nAreas = CountAreas(); + for (int32 i = 0; i < nAreas; i++) { + Area* area = AreaAt(i); + if (area == NULL) + return false; + int32 left = -1; + if (archive->FindInt32("left", i, &left) != B_OK) + break; + int32 top = archive->FindInt32("top", i); + int32 right = archive->FindInt32("right", i); + int32 bottom = archive->FindInt32("bottom", i); + + XTab* leftTab = NULL; + YTab* topTab = NULL; + XTab* rightTab = NULL; + YTab* bottomTab = NULL; + + if (left == kLeftBorderIndex) + leftTab = fLeft; + else + leftTab = xTabs.ItemAt(left); + if (top == kTopBorderIndex) + topTab = fTop; + else + topTab = yTabs.ItemAt(top); + if (right == kRightBorderIndex) + rightTab = fRight; + else + rightTab = xTabs.ItemAt(right); + if (bottom == kBottomBorderIndex) + bottomTab = fBottom; + else + bottomTab = yTabs.ItemAt(bottom); + if (leftTab == NULL || topTab == NULL || rightTab == NULL + || bottomTab == NULL) + return false; + + area->SetLeft(leftTab); + area->SetTop(topTab); + area->SetRight(rightTab); + area->SetBottom(bottomTab); + } + return true; +} + + /** * Gets the left variable. */