From 80c2bbd8ae62af882a3327024f8ab306a2923239 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 16 Jul 2010 18:11:24 +0000 Subject: [PATCH] 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 --- headers/os/interface/TwoDimensionalLayout.h | 9 +- src/kits/interface/TwoDimensionalLayout.cpp | 189 +++++++++++++++++++- 2 files changed, 195 insertions(+), 3 deletions(-) diff --git a/headers/os/interface/TwoDimensionalLayout.h b/headers/os/interface/TwoDimensionalLayout.h index d756c08e57..7517e180eb 100644 --- a/headers/os/interface/TwoDimensionalLayout.h +++ b/headers/os/interface/TwoDimensionalLayout.h @@ -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: diff --git a/src/kits/interface/TwoDimensionalLayout.cpp b/src/kits/interface/TwoDimensionalLayout.cpp index 5a6387c547..0176042b6e 100644 --- a/src/kits/interface/TwoDimensionalLayout.cpp +++ b/src/kits/interface/TwoDimensionalLayout.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -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)