From 27d84b482cddb07e4dee8ee345d3b9a61000d2ec Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Thu, 8 Jul 2010 15:40:49 +0000 Subject: [PATCH] Patch by Alex Wilson as part of GSoC 2010 : Archiving of Layouted BViews hierarchy. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37433 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/Layout.h | 16 +++- headers/os/interface/LayoutItem.h | 11 ++- src/kits/interface/Layout.cpp | 146 +++++++++++++++++++++++++----- src/kits/interface/LayoutItem.cpp | 65 ++++++++++--- 4 files changed, 199 insertions(+), 39 deletions(-) diff --git a/headers/os/interface/Layout.h b/headers/os/interface/Layout.h index 80fc504787..a2fcc94701 100644 --- a/headers/os/interface/Layout.h +++ b/headers/os/interface/Layout.h @@ -1,11 +1,12 @@ /* - * Copyright 2006, Haiku, Inc. All rights reserved. + * Copyright 2006-2010, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _LAYOUT_H #define _LAYOUT_H #include +#include #include #include @@ -13,9 +14,10 @@ class BLayoutItem; class BView; -class BLayout { +class BLayout: public BArchivable { public: BLayout(); + BLayout(BMessage* archive); virtual ~BLayout(); BView* View() const; @@ -32,7 +34,7 @@ public: BLayoutItem* ItemAt(int32 index) const; int32 CountItems() const; - int32 IndexOfItem(BLayoutItem* item) const; + int32 IndexOfItem(const BLayoutItem* item) const; int32 IndexOfView(BView* child) const; virtual BSize MinSize() = 0; @@ -48,7 +50,15 @@ public: virtual void LayoutView() = 0; + virtual status_t Archive(BMessage* into, bool deep = true) const; + virtual status_t AllUnarchived(const BMessage* from); + virtual status_t ArchiveLayoutData(BMessage* into, + const BLayoutItem* of) const; + virtual status_t RestoreItemAndData(const BMessage* from, + BLayoutItem* item); + protected: + // TODO: Since memory allocations can fail, we should return a bool and // undo the addition, if false. virtual void ItemAdded(BLayoutItem* item); diff --git a/headers/os/interface/LayoutItem.h b/headers/os/interface/LayoutItem.h index a02fc52a55..391a2ff2b7 100644 --- a/headers/os/interface/LayoutItem.h +++ b/headers/os/interface/LayoutItem.h @@ -1,20 +1,22 @@ /* - * Copyright 2006, Haiku, Inc. All rights reserved. + * Copyright 2006-2010, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _LAYOUT_ITEM_H #define _LAYOUT_ITEM_H #include +#include #include #include class BLayout; class BView; -class BLayoutItem { +class BLayoutItem: public BArchivable { public: BLayoutItem(); + BLayoutItem(BMessage* from); virtual ~BLayoutItem(); BLayout* Layout() const; @@ -47,6 +49,11 @@ public: void SetLayoutData(void* data); void AlignInFrame(BRect frame); + + virtual status_t Archive(BMessage* into, bool deep = true) const; + virtual status_t AllArchived(BMessage* into) const; + virtual status_t AllUnarchived(const BMessage* from); + private: friend class BLayout; diff --git a/src/kits/interface/Layout.cpp b/src/kits/interface/Layout.cpp index d4254280c4..3fae634b6d 100644 --- a/src/kits/interface/Layout.cpp +++ b/src/kits/interface/Layout.cpp @@ -1,48 +1,72 @@ /* + * Copyright 2010, Haiku Inc. * Copyright 2006, Ingo Weinhold . * All rights reserved. Distributed under the terms of the MIT License. */ + #include #include +#include #include #include "ViewLayoutItem.h" + using std::nothrow; +namespace { + const char* kLayoutItemField = "BLayout:_items"; + const char* kLayoutDataField = "BLayout:_data"; +} + // constructor BLayout::BLayout() - : fView(NULL), - fItems(20) + : + fView(NULL), + fItems(20) { } -// destructor + +BLayout::BLayout(BMessage* from) + : + BArchivable(BUnarchiver::PrepareArchive(from)), + fView(NULL), + fItems(20) +{ + BUnarchiver unarchiver(from); + + int32 i = 0; + while (unarchiver.EnsureUnarchived(kLayoutItemField, i++) == B_OK) + ; +} + + BLayout::~BLayout() { // this deletes all items SetView(NULL); } -// View + BView* BLayout::View() const { return fView; } -// AddView + BLayoutItem* BLayout::AddView(BView* child) { return AddView(-1, child); } -// AddView + BLayoutItem* BLayout::AddView(int32 index, BView* child) { @@ -54,21 +78,21 @@ BLayout::AddView(int32 index, BView* child) return NULL; } -// AddItem + bool BLayout::AddItem(BLayoutItem* item) { return AddItem(-1, item); } -// AddItem + bool BLayout::AddItem(int32 index, BLayoutItem* item) { if (!fView || !item || fItems.HasItem(item)) return false; - // if the item refers to a BView, we make sure, it is added to the parent + // if the item refers to a BView, we make sure it is added to the parent // view BView* view = item->View(); if (view && view->fParent != fView && !fView->_AddChild(view, NULL)) @@ -86,7 +110,7 @@ BLayout::AddItem(int32 index, BLayoutItem* item) return true; } -// RemoveView + bool BLayout::RemoveView(BView* child) { @@ -107,7 +131,7 @@ BLayout::RemoveView(BView* child) return removed; } -// RemoveItem + bool BLayout::RemoveItem(BLayoutItem* item) { @@ -115,7 +139,7 @@ BLayout::RemoveItem(BLayoutItem* item) return (index >= 0 ? RemoveItem(index) : false); } -// RemoveItem + BLayoutItem* BLayout::RemoveItem(int32 index) { @@ -137,28 +161,28 @@ BLayout::RemoveItem(int32 index) return item; } -// ItemAt + BLayoutItem* BLayout::ItemAt(int32 index) const { return (BLayoutItem*)fItems.ItemAt(index); } -// CountItems + int32 BLayout::CountItems() const { return fItems.CountItems(); } -// IndexOfItem + int32 -BLayout::IndexOfItem(BLayoutItem* item) const +BLayout::IndexOfItem(const BLayoutItem* item) const { return fItems.IndexOf(item); } -// IndexOfView + int32 BLayout::IndexOfView(BView* child) const { @@ -172,7 +196,7 @@ BLayout::IndexOfView(BView* child) const return -1; } -// InvalidateLayout + void BLayout::InvalidateLayout() { @@ -180,19 +204,99 @@ BLayout::InvalidateLayout() fView->InvalidateLayout(); } -// ItemAdded + +status_t +BLayout::Archive(BMessage* into, bool deep) const +{ + BArchiver archiver(into); + status_t err = BArchivable::Archive(into, deep); + + if (err != B_OK) + return err; + + if (deep) { + int32 count = CountItems(); + for (int32 i = 0; i < count; i++) { + err = archiver.AddArchivable(kLayoutItemField, ItemAt(i), deep); + + if (err == B_OK) { + BMessage data; + err = ArchiveLayoutData(&data, ItemAt(i)); + if (err == B_OK) + err = into->AddMessage(kLayoutDataField, &data); + } + + if (err != B_OK) + return err; + } + } + + return archiver.Finish(); +} + + +status_t +BLayout::AllUnarchived(const BMessage* from) +{ + status_t err = BArchivable::AllUnarchived(from); + BUnarchiver unarchiver(from); + + if (err != B_OK) + return err; + + for (int32 i = 0; ; i++) { + BArchivable* retriever; + err = unarchiver.FindArchivable(kLayoutItemField, i, &retriever); + + if (err == B_BAD_INDEX) + break; + + if (err == B_OK) { + BMessage layoutData; + err = from->FindMessage(kLayoutDataField, i, &layoutData); + + if (err == B_OK) { + BLayoutItem* item = dynamic_cast(retriever); + err = RestoreItemAndData(&layoutData, item); + } + } + + if (err != B_OK) + return err; + } + + return B_OK; +} + + +status_t +BLayout::ArchiveLayoutData(BMessage* into, const BLayoutItem* of) const +{ + return B_OK; +} + + +status_t +BLayout::RestoreItemAndData(const BMessage* from, BLayoutItem* item) +{ + if (item && AddItem(item)) + return B_OK; + return B_ERROR; +} + + void BLayout::ItemAdded(BLayoutItem* item) { } -// ItemRemoved + void BLayout::ItemRemoved(BLayoutItem* item) { } -// SetView + void BLayout::SetView(BView* view) { diff --git a/src/kits/interface/LayoutItem.cpp b/src/kits/interface/LayoutItem.cpp index 14c059ccf4..fb16551585 100644 --- a/src/kits/interface/LayoutItem.cpp +++ b/src/kits/interface/LayoutItem.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2010, Haiku, Inc. * Copyright 2006, Ingo Weinhold . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -9,26 +10,36 @@ #include -// constructor BLayoutItem::BLayoutItem() - : fLayout(NULL), - fLayoutData(NULL) + : + fLayout(NULL), + fLayoutData(NULL) { } -// destructor + +BLayoutItem::BLayoutItem(BMessage* from) + : + BArchivable(BUnarchiver::PrepareArchive(from)), + fLayout(NULL), + fLayoutData(NULL) +{ + BUnarchiver(from).Finish(); +} + + BLayoutItem::~BLayoutItem() { } -// Layout + BLayout* BLayoutItem::Layout() const { return fLayout; } -// HasHeightForWidth + bool BLayoutItem::HasHeightForWidth() { @@ -36,7 +47,7 @@ BLayoutItem::HasHeightForWidth() return false; } -// GetHeightForWidth + void BLayoutItem::GetHeightForWidth(float width, float* min, float* max, float* preferred) @@ -44,14 +55,14 @@ BLayoutItem::GetHeightForWidth(float width, float* min, float* max, // no "height for width" by default } -// View + BView* BLayoutItem::View() { return NULL; } -// InvalidateLayout + void BLayoutItem::InvalidateLayout() { @@ -59,21 +70,21 @@ BLayoutItem::InvalidateLayout() fLayout->InvalidateLayout(); } -// LayoutData + void* BLayoutItem::LayoutData() const { return fLayoutData; } -// SetLayoutData + void BLayoutItem::SetLayoutData(void* data) { fLayoutData = data; } -// AlignInFrame + void BLayoutItem::AlignInFrame(BRect frame) { @@ -101,7 +112,35 @@ BLayoutItem::AlignInFrame(BRect frame) SetFrame(BLayoutUtils::AlignInFrame(frame, maxSize, alignment)); } -// SetLayout + +status_t +BLayoutItem::Archive(BMessage* into, bool deep) const +{ + BArchiver archiver(into); + status_t err = BArchivable::Archive(into, deep); + + if (err == B_OK) + err = archiver.Finish(); + + return err; +} + + +status_t +BLayoutItem::AllArchived(BMessage* into) const +{ + BArchiver archiver(into); + return BArchivable::AllArchived(into); +} + + +status_t +BLayoutItem::AllUnarchived(const BMessage* from) +{ + return BArchivable::AllUnarchived(from); +} + + void BLayoutItem::SetLayout(BLayout* layout) {