Patch by Alex Wilson (with small style changes by myself): Added support for

archiving/unarchiving.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37541 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2010-07-16 18:11:24 +00:00
parent 7ed1644c55
commit 80c2bbd8ae
2 changed files with 195 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006, Haiku, Inc. All rights reserved.
* Copyright 2006-2010, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _TWO_DIMENSIONAL_LAYOUT_H
@ -14,6 +14,7 @@ class BLayoutContext;
class BTwoDimensionalLayout : public BLayout {
public:
BTwoDimensionalLayout();
BTwoDimensionalLayout(BMessage* from);
virtual ~BTwoDimensionalLayout();
void SetInsets(float left, float top, float right,
@ -37,6 +38,10 @@ public:
virtual void LayoutView();
virtual status_t Archive(BMessage* into, bool deep = true) const;
virtual status_t AllArchived(BMessage* into) const;
virtual status_t AllUnarchived(const BMessage* from);
protected:
struct ColumnRowConstraints {
float weight;
@ -66,7 +71,7 @@ protected:
enum orientation orientation,
int32 index,
ColumnRowConstraints* constraints) = 0;
virtual void GetItemDimensions(BLayoutItem* item,
virtual void GetItemDimensions(BLayoutItem* item,
Dimensions* dimensions) = 0;
private:

View File

@ -12,6 +12,7 @@
#include <LayoutItem.h>
#include <LayoutUtils.h>
#include <List.h>
#include <Message.h>
#include <View.h>
#include <Referenceable.h>
@ -21,6 +22,13 @@
#include "SimpleLayouter.h"
// Archiving constants
namespace {
const char* kHAlignedLayoutField = "B2DLayout:halignedlayout";
const char* kVAlignedLayoutField = "B2DLayout:valignedlayout";
}
// Some words of explanation:
//
// This class is the base class for BLayouts that organize their items
@ -67,6 +75,9 @@ public:
void RemoveLocalLayouter(
LocalLayouter* localLayouter);
status_t AddAlignedLayoutsToArchive(BArchiver* archiver,
LocalLayouter* requestedBy);
void AbsorbCompoundLayouter(CompoundLayouter* other);
virtual void InvalidateLayout();
@ -164,6 +175,14 @@ public:
void AlignWith(LocalLayouter* other,
enum orientation orientation);
// Archiving stuff
status_t AddAlignedLayoutsToArchive(BArchiver* archiver);
status_t AddOwnerToArchive(BArchiver* archiver,
CompoundLayouter* requestedBy,
bool& _wasAvailable);
status_t AlignLayoutsFromArchive(BUnarchiver* unarchiver,
orientation posture);
// interface for the compound layout context
@ -197,7 +216,7 @@ public:
// implementation private
private:
BTwoDimensionalLayout* fLayout;
BTwoDimensionalLayout* fLayout;
CompoundLayouter* fHLayouter;
VerticalCompoundLayouter* fVLayouter;
BList fHeightForWidthItems;
@ -217,6 +236,16 @@ private:
// #pragma mark -
// archiving constants
namespace {
const char* kLeftInsetField = "B2Dlayout:leftInset";
const char* kRightInsetField = "B2Dlayout:rightInset";
const char* kTopInsetField = "B2Dlayout:topInset";
const char* kBottomInsetField = "B2Dlayout:bottomInset";
const char* kHSpacingField = "B2Dlayout:hspacing";
const char* kVSpacingField = "B2Dlayout:vspacing";
}
BTwoDimensionalLayout::BTwoDimensionalLayout()
:
@ -231,6 +260,32 @@ BTwoDimensionalLayout::BTwoDimensionalLayout()
}
BTwoDimensionalLayout::BTwoDimensionalLayout(BMessage* from)
:
BLayout(from),
fLeftInset(0),
fRightInset(0),
fTopInset(0),
fBottomInset(0),
fHSpacing(0),
fVSpacing(0),
fLocalLayouter(new LocalLayouter(this))
{
float leftInset;
float rightInset;
float topInset;
float bottomInset;
if (from->FindFloat(kLeftInsetField, &leftInset) == B_OK
&& from->FindFloat(kRightInsetField, &rightInset) == B_OK
&& from->FindFloat(kTopInsetField, &topInset) == B_OK
&& from->FindFloat(kBottomInsetField, &bottomInset) == B_OK)
SetInsets(leftInset, topInset, rightInset, bottomInset);
from->FindFloat(kHSpacingField, &fHSpacing);
from->FindFloat(kVSpacingField, &fVSpacing);
}
BTwoDimensionalLayout::~BTwoDimensionalLayout()
{
delete fLocalLayouter;
@ -393,6 +448,62 @@ frame.PrintToStream();
}
status_t
BTwoDimensionalLayout::Archive(BMessage* into, bool deep) const
{
BArchiver archiver(into);
status_t err = BLayout::Archive(into, deep);
if (err == B_OK)
err = into->AddFloat(kLeftInsetField, fLeftInset);
if (err == B_OK)
err = into->AddFloat(kRightInsetField, fRightInset);
if (err == B_OK)
err = into->AddFloat(kTopInsetField, fTopInset);
if (err == B_OK)
err = into->AddFloat(kBottomInsetField, fBottomInset);
if (err == B_OK)
err = into->AddFloat(kHSpacingField, fHSpacing);
if (err == B_OK)
err = into->AddFloat(kVSpacingField, fVSpacing);
return archiver.Finish(err);
}
status_t
BTwoDimensionalLayout::AllArchived(BMessage* into) const
{
BArchiver archiver(into);
status_t err = BLayout::AllArchived(into);
if (err == B_OK)
err = fLocalLayouter->AddAlignedLayoutsToArchive(&archiver);
return err;
}
status_t
BTwoDimensionalLayout::AllUnarchived(const BMessage* from)
{
status_t err = BLayout::AllUnarchived(from);
if (err != B_OK)
return err;
BUnarchiver unarchiver(from);
err = fLocalLayouter->AlignLayoutsFromArchive(&unarchiver, B_HORIZONTAL);
if (err == B_OK)
err = fLocalLayouter->AlignLayoutsFromArchive(&unarchiver, B_VERTICAL);
return err;
}
BSize
BTwoDimensionalLayout::AddInsets(BSize size)
{
@ -531,6 +642,28 @@ BTwoDimensionalLayout::CompoundLayouter::RemoveLocalLayouter(
}
status_t
BTwoDimensionalLayout::CompoundLayouter::AddAlignedLayoutsToArchive(
BArchiver* archiver, LocalLayouter* requestedBy)
{
// The LocalLayouter* that really owns us is at index 0, layouts
// at other indices are aligned to this one.
if (requestedBy != fLocalLayouters.ItemAt(0))
return B_OK;
status_t err;
for (int32 i = fLocalLayouters.CountItems() - 1; i > 0; i--) {
LocalLayouter* layouter = (LocalLayouter*)fLocalLayouters.ItemAt(i);
bool wasAvailable;
err = layouter->AddOwnerToArchive(archiver, this, wasAvailable);
if (err != B_OK && wasAvailable)
return err;
}
return B_OK;
}
void
BTwoDimensionalLayout::CompoundLayouter::AbsorbCompoundLayouter(
CompoundLayouter* other)
@ -1013,6 +1146,60 @@ BTwoDimensionalLayout::LocalLayouter::AlignWith(LocalLayouter* other,
}
status_t
BTwoDimensionalLayout::LocalLayouter::AddAlignedLayoutsToArchive(
BArchiver* archiver)
{
status_t err = fHLayouter->AddAlignedLayoutsToArchive(archiver, this);
if (err == B_OK)
err = fVLayouter->AddAlignedLayoutsToArchive(archiver, this);
return err;
}
status_t
BTwoDimensionalLayout::LocalLayouter::AddOwnerToArchive(BArchiver* archiver,
CompoundLayouter* requestedBy, bool& _wasAvailable)
{
const char* field = kHAlignedLayoutField;
if (requestedBy == fVLayouter)
field = kVAlignedLayoutField;
if ((_wasAvailable = archiver->IsArchived(fLayout)))
return archiver->AddArchivable(field, fLayout);
return B_NAME_NOT_FOUND;
}
status_t
BTwoDimensionalLayout::LocalLayouter::AlignLayoutsFromArchive(
BUnarchiver* unarchiver, orientation posture)
{
const char* field = kHAlignedLayoutField;
if (posture == B_VERTICAL)
field = kVAlignedLayoutField;
int32 count;
status_t err = unarchiver->ArchiveMessage()->GetInfo(field, NULL, &count);
if (err == B_NAME_NOT_FOUND)
return B_OK;
BTwoDimensionalLayout* retriever;
for (int32 i = 0; i < count && err == B_OK; i++) {
err = unarchiver->FindObject(field, i,
BUnarchiver::B_DONT_ASSUME_OWNERSHIP, retriever);
if (err == B_OK)
retriever->AlignLayoutWith(fLayout, posture);
}
return err;
}
void
BTwoDimensionalLayout::LocalLayouter::PrepareItems(
CompoundLayouter* compoundLayouter)