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
This commit is contained in:
Adrien Destugues 2010-07-08 15:40:49 +00:00
parent fbb6335d2a
commit 27d84b482c
4 changed files with 199 additions and 39 deletions

View File

@ -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 <Alignment.h>
#include <Archivable.h>
#include <List.h>
#include <Size.h>
@ -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);

View File

@ -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 <Alignment.h>
#include <Archivable.h>
#include <Rect.h>
#include <Size.h>
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;

View File

@ -1,48 +1,72 @@
/*
* Copyright 2010, Haiku Inc.
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <Layout.h>
#include <new>
#include <Message.h>
#include <View.h>
#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<BLayoutItem*>(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)
{

View File

@ -1,4 +1,5 @@
/*
* Copyright 2010, Haiku, Inc.
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -9,26 +10,36 @@
#include <LayoutUtils.h>
// 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)
{