diff --git a/src/kits/interface/SplitLayout.cpp b/src/kits/interface/SplitLayout.cpp index dca0a61068..8a9d7bcf31 100644 --- a/src/kits/interface/SplitLayout.cpp +++ b/src/kits/interface/SplitLayout.cpp @@ -3,18 +3,35 @@ * All rights reserved. Distributed under the terms of the MIT License. */ + #include "SplitLayout.h" +#include #include #include #include +#include #include #include "OneElementLayouter.h" #include "SimpleLayouter.h" -// ItemLayoutInfo + +// archivng constants +namespace { + const char* kInfoCollapsibleField = "BSplitLayout::info::collapsible"; + const char* kInfoWeightField = "BSplitLayout::info::weight"; + const char* kSpacingField = "BSplitLayout::spacing"; + const char* kSplitterSizeField = "BSplitLayout::splitterSize"; + const char* kIsVerticalField = "BSplitLayout::vertical"; + const char* kTopInsetField = "BSplitLayout::TopInset"; + const char* kBottomInsetField = "BSplitLayout::BottomInset"; + const char* kLeftInsetField = "BSplitLayout::LeftInset"; + const char* kRightInsetField = "BSplitLayout::RightInset"; +} + + class BSplitLayout::ItemLayoutInfo { public: float weight; @@ -25,17 +42,18 @@ public: bool isCollapsible; ItemLayoutInfo() - : weight(1.0f), - layoutFrame(0, 0, -1, -1), - min(), - max(), - isVisible(true), - isCollapsible(true) + : + weight(1.0f), + layoutFrame(0, 0, -1, -1), + min(), + max(), + isVisible(true), + isCollapsible(true) { } }; -// ValueRange + class BSplitLayout::ValueRange { public: int32 sumValue; // including spacing @@ -47,15 +65,17 @@ public: int32 nextSize; }; -// SplitterItem + class BSplitLayout::SplitterItem : public BLayoutItem { public: SplitterItem(BSplitLayout* layout) - : fLayout(layout), - fFrame() + : + fLayout(layout), + fFrame() { } + virtual BSize MinSize() { if (fLayout->Orientation() == B_HORIZONTAL) @@ -132,53 +152,97 @@ private: // #pragma mark - -// constructor BSplitLayout::BSplitLayout(enum orientation orientation, float spacing) - : fOrientation(orientation), - fLeftInset(0), - fRightInset(0), - fTopInset(0), - fBottomInset(0), - fSplitterSize(6), - fSpacing(spacing), + : + fOrientation(orientation), + fLeftInset(0), + fRightInset(0), + fTopInset(0), + fBottomInset(0), + fSplitterSize(6), + fSpacing(spacing), - fSplitterItems(), - fVisibleItems(), - fMin(), - fMax(), - fPreferred(), + fSplitterItems(), + fVisibleItems(), + fMin(), + fMax(), + fPreferred(), - fHorizontalLayouter(NULL), - fVerticalLayouter(NULL), - fHorizontalLayoutInfo(NULL), - fVerticalLayoutInfo(NULL), + fHorizontalLayouter(NULL), + fVerticalLayouter(NULL), + fHorizontalLayoutInfo(NULL), + fVerticalLayoutInfo(NULL), - fHeightForWidthItems(), - fHeightForWidthVerticalLayouter(NULL), - fHeightForWidthHorizontalLayoutInfo(NULL), + fHeightForWidthItems(), + fHeightForWidthVerticalLayouter(NULL), + fHeightForWidthHorizontalLayoutInfo(NULL), - fLayoutValid(false), + fLayoutValid(false), - fCachedHeightForWidthWidth(-2), - fHeightForWidthVerticalLayouterWidth(-2), - fCachedMinHeightForWidth(-1), - fCachedMaxHeightForWidth(-1), - fCachedPreferredHeightForWidth(-1), + fCachedHeightForWidthWidth(-2), + fHeightForWidthVerticalLayouterWidth(-2), + fCachedMinHeightForWidth(-1), + fCachedMaxHeightForWidth(-1), + fCachedPreferredHeightForWidth(-1), - fDraggingStartPoint(), - fDraggingStartValue(0), - fDraggingCurrentValue(0), - fDraggingSplitterIndex(-1) + fDraggingStartPoint(), + fDraggingStartValue(0), + fDraggingCurrentValue(0), + fDraggingSplitterIndex(-1) { } -// destructor + +BSplitLayout::BSplitLayout(BMessage* from) + : + BLayout(from), + fSplitterItems(), + fVisibleItems(), + fMin(), + fMax(), + fPreferred(), + + fHorizontalLayouter(NULL), + fVerticalLayouter(NULL), + fHorizontalLayoutInfo(NULL), + fVerticalLayoutInfo(NULL), + + fHeightForWidthItems(), + fHeightForWidthVerticalLayouter(NULL), + fHeightForWidthHorizontalLayoutInfo(NULL), + + fLayoutValid(false), + + fCachedHeightForWidthWidth(-2), + fHeightForWidthVerticalLayouterWidth(-2), + fCachedMinHeightForWidth(-1), + fCachedMaxHeightForWidth(-1), + fCachedPreferredHeightForWidth(-1), + + fDraggingStartPoint(), + fDraggingStartValue(0), + fDraggingCurrentValue(0), + fDraggingSplitterIndex(-1) +{ + bool isVertical; + from->FindBool(kIsVerticalField, &isVertical); + fOrientation = (isVertical) ? B_VERTICAL : B_HORIZONTAL ; + + from->FindFloat(kLeftInsetField, &fLeftInset); + from->FindFloat(kRightInsetField, &fRightInset); + from->FindFloat(kTopInsetField, &fTopInset); + from->FindFloat(kBottomInsetField, &fBottomInset); + from->FindFloat(kSplitterSizeField, &fSplitterSize); + from->FindFloat(kSpacingField, &fSpacing); +} + + BSplitLayout::~BSplitLayout() { } -// SetInsets + void BSplitLayout::SetInsets(float left, float top, float right, float bottom) { @@ -190,7 +254,7 @@ BSplitLayout::SetInsets(float left, float top, float right, float bottom) InvalidateLayout(); } -// GetInsets + void BSplitLayout::GetInsets(float* left, float* top, float* right, float* bottom) const @@ -205,14 +269,14 @@ BSplitLayout::GetInsets(float* left, float* top, float* right, *bottom = fBottomInset; } -// Spacing + float BSplitLayout::Spacing() const { return fSpacing; } -// SetSpacing + void BSplitLayout::SetSpacing(float spacing) { @@ -223,14 +287,14 @@ BSplitLayout::SetSpacing(float spacing) } } -// Orientation + orientation BSplitLayout::Orientation() const { return fOrientation; } -// SetOrientation + void BSplitLayout::SetOrientation(enum orientation orientation) { @@ -241,14 +305,14 @@ BSplitLayout::SetOrientation(enum orientation orientation) } } -// SplitterSize + float BSplitLayout::SplitterSize() const { return fSplitterSize; } -// SetSplitterSize + void BSplitLayout::SetSplitterSize(float size) { @@ -259,28 +323,28 @@ BSplitLayout::SetSplitterSize(float size) } } -// AddView + BLayoutItem* BSplitLayout::AddView(BView* child) { return BLayout::AddView(child); } -// AddView + BLayoutItem* BSplitLayout::AddView(int32 index, BView* child) { return BLayout::AddView(index, child); } -// AddView + BLayoutItem* BSplitLayout::AddView(BView* child, float weight) { return AddView(-1, child, weight); } -// AddView + BLayoutItem* BSplitLayout::AddView(int32 index, BView* child, float weight) { @@ -291,28 +355,28 @@ BSplitLayout::AddView(int32 index, BView* child, float weight) return item; } -// AddItem + bool BSplitLayout::AddItem(BLayoutItem* item) { return BLayout::AddItem(item); } -// AddItem + bool BSplitLayout::AddItem(int32 index, BLayoutItem* item) { return BLayout::AddItem(index, item); } -// AddItem + bool BSplitLayout::AddItem(BLayoutItem* item, float weight) { return AddItem(-1, item, weight); } -// AddItem + bool BSplitLayout::AddItem(int32 index, BLayoutItem* item, float weight) { @@ -323,7 +387,7 @@ BSplitLayout::AddItem(int32 index, BLayoutItem* item, float weight) return success; } -// ItemWeight + float BSplitLayout::ItemWeight(int32 index) const { @@ -333,7 +397,7 @@ BSplitLayout::ItemWeight(int32 index) const return ItemWeight(ItemAt(index)); } -// ItemWeight + float BSplitLayout::ItemWeight(BLayoutItem* item) const { @@ -342,7 +406,7 @@ BSplitLayout::ItemWeight(BLayoutItem* item) const return 0; } -// SetItemWeight + void BSplitLayout::SetItemWeight(int32 index, float weight, bool invalidateLayout) { @@ -366,7 +430,7 @@ BSplitLayout::SetItemWeight(int32 index, float weight, bool invalidateLayout) InvalidateLayout(); } -// SetItemWeight + void BSplitLayout::SetItemWeight(BLayoutItem* item, float weight) { @@ -374,21 +438,21 @@ BSplitLayout::SetItemWeight(BLayoutItem* item, float weight) info->weight = weight; } -// SetCollapsible + void BSplitLayout::SetCollapsible(bool collapsible) { SetCollapsible(0, CountItems() - 1, collapsible); } -// SetCollapsible + void BSplitLayout::SetCollapsible(int32 index, bool collapsible) { SetCollapsible(index, index, collapsible); } -// SetCollapsible + void BSplitLayout::SetCollapsible(int32 first, int32 last, bool collapsible) { @@ -401,7 +465,7 @@ BSplitLayout::SetCollapsible(int32 first, int32 last, bool collapsible) _ItemLayoutInfo(ItemAt(i))->isCollapsible = collapsible; } -// MinSize + BSize BSplitLayout::MinSize() { @@ -410,7 +474,7 @@ BSplitLayout::MinSize() return _AddInsets(fMin); } -// MaxSize + BSize BSplitLayout::MaxSize() { @@ -419,7 +483,7 @@ BSplitLayout::MaxSize() return _AddInsets(fMax); } -// PreferredSize + BSize BSplitLayout::PreferredSize() { @@ -428,14 +492,14 @@ BSplitLayout::PreferredSize() return _AddInsets(fPreferred); } -// Alignment + BAlignment BSplitLayout::Alignment() { return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); } -// HasHeightForWidth + bool BSplitLayout::HasHeightForWidth() { @@ -444,7 +508,7 @@ BSplitLayout::HasHeightForWidth() return !fHeightForWidthItems.IsEmpty(); } -// GetHeightForWidth + void BSplitLayout::GetHeightForWidth(float width, float* min, float* max, float* preferred) @@ -457,14 +521,14 @@ BSplitLayout::GetHeightForWidth(float width, float* min, float* max, _AddInsets(min, max, preferred); } -// InvalidateLayout + void BSplitLayout::InvalidateLayout() { _InvalidateLayout(true); } -// LayoutView + void BSplitLayout::LayoutView() { @@ -543,7 +607,7 @@ BSplitLayout::LayoutView() fLayoutValid = true; } -// SplitterItemFrame + BRect BSplitLayout::SplitterItemFrame(int32 index) const { @@ -552,14 +616,14 @@ BSplitLayout::SplitterItemFrame(int32 index) const return BRect(); } -// IsAboveSplitter + bool BSplitLayout::IsAboveSplitter(const BPoint& point) const { return _SplitterItemAt(point) != NULL; } -// StartDraggingSplitter + bool BSplitLayout::StartDraggingSplitter(BPoint point) { @@ -589,7 +653,7 @@ BSplitLayout::StartDraggingSplitter(BPoint point) return false; } -// DragSplitter + bool BSplitLayout::DragSplitter(BPoint point) { @@ -608,7 +672,7 @@ BSplitLayout::DragSplitter(BPoint point) fDraggingStartValue + valueDiff); } -// StopDraggingSplitter + bool BSplitLayout::StopDraggingSplitter() { @@ -623,14 +687,85 @@ BSplitLayout::StopDraggingSplitter() return true; } -// DraggedSplitter + int32 BSplitLayout::DraggedSplitter() const { return fDraggingSplitterIndex; } -// ItemAdded + +status_t +BSplitLayout::Archive(BMessage* into, bool deep) const +{ + BArchiver archiver(into); + status_t err = BLayout::Archive(into, deep); + + if (err == B_OK) + into->AddBool(kIsVerticalField, fOrientation == B_VERTICAL); + + 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(kSplitterSizeField, fSplitterSize); + + if (err == B_OK) + err = into->AddFloat(kSpacingField, fSpacing); + + return archiver.Finish(err); +} + + +BArchivable* +BSplitLayout::Instantiate(BMessage* from) +{ + if (validate_instantiation(from, "BSplitLayout")) + return new(std::nothrow) BSplitLayout(from); + return NULL; +} + + +status_t +BSplitLayout::ItemArchived(BMessage* into, BLayoutItem* item, int32 index) const +{ + ItemLayoutInfo* info = (ItemLayoutInfo*)item->LayoutData(); + + if (!info) // TODO: remove this check when AddItem() returns a bool + return B_ERROR; + + status_t err = into->AddFloat(kInfoWeightField, info->weight); + if (err == B_OK) + err = into->AddBool(kInfoCollapsibleField, info->isCollapsible); + + return err; +} + + +status_t +BSplitLayout::ItemUnarchived(const BMessage* from, + BLayoutItem* item, int32 index) +{ + ItemLayoutInfo* info = _ItemLayoutInfo(item); + status_t err = from->FindFloat(kInfoWeightField, index, &info->weight); + + if (err == B_OK) { + bool* collapsible = &info->isCollapsible; + err = from->FindBool(kInfoCollapsibleField, index, collapsible); + } + return err; +} + + void BSplitLayout::ItemAdded(BLayoutItem* item) { @@ -643,7 +778,7 @@ BSplitLayout::ItemAdded(BLayoutItem* item) SetItemWeight(item, 1); } -// ItemRemoved + void BSplitLayout::ItemRemoved(BLayoutItem* item) { @@ -658,7 +793,7 @@ BSplitLayout::ItemRemoved(BLayoutItem* item) item->SetLayoutData(NULL); } -// _InvalidateLayout + void BSplitLayout::_InvalidateLayout(bool invalidateView) { @@ -680,7 +815,7 @@ BSplitLayout::_InvalidateLayout(bool invalidateView) fLayoutValid = false; } -// _InvalidateCachedHeightForWidth + void BSplitLayout::_InvalidateCachedHeightForWidth() { @@ -694,7 +829,7 @@ BSplitLayout::_InvalidateCachedHeightForWidth() fHeightForWidthVerticalLayouterWidth = -2; } -// _SplitterItemAt + BSplitLayout::SplitterItem* BSplitLayout::_SplitterItemAt(const BPoint& point, int32* index) const { @@ -711,14 +846,14 @@ BSplitLayout::_SplitterItemAt(const BPoint& point, int32* index) const return NULL; } -// _SplitterItemAt + BSplitLayout::SplitterItem* BSplitLayout::_SplitterItemAt(int32 index) const { return (SplitterItem*)fSplitterItems.ItemAt(index); } -// _GetSplitterValueRange + void BSplitLayout::_GetSplitterValueRange(int32 index, ValueRange& range) { @@ -747,7 +882,7 @@ BSplitLayout::_GetSplitterValueRange(int32 index, ValueRange& range) range.sumValue += (int32)fSpacing; } -// _SplitterValue + int32 BSplitLayout::_SplitterValue(int32 index) const { @@ -761,7 +896,7 @@ BSplitLayout::_SplitterValue(int32 index) const return 0; } -// _LayoutItem + void BSplitLayout::_LayoutItem(BLayoutItem* item, BRect frame, bool visible) { @@ -790,7 +925,7 @@ BSplitLayout::_LayoutItem(BLayoutItem* item, BRect frame, bool visible) item->AlignInFrame(frame); } -// _LayoutItem + void BSplitLayout::_LayoutItem(BLayoutItem* item, ItemLayoutInfo* info) { @@ -813,7 +948,7 @@ BSplitLayout::_LayoutItem(BLayoutItem* item, ItemLayoutInfo* info) } } -// _SetSplitterValue + bool BSplitLayout::_SetSplitterValue(int32 index, int32 value) { @@ -1042,7 +1177,7 @@ BSplitLayout::_SetSplitterValue(int32 index, int32 value) return true; } -// _ItemLayoutInfo + BSplitLayout::ItemLayoutInfo* BSplitLayout::_ItemLayoutInfo(BLayoutItem* item) const { @@ -1055,7 +1190,7 @@ BSplitLayout::_ItemLayoutInfo(BLayoutItem* item) const return info; } -// _UpdateSplitterWeights + void BSplitLayout::_UpdateSplitterWeights() { @@ -1078,7 +1213,7 @@ BSplitLayout::_UpdateSplitterWeights() _InvalidateCachedHeightForWidth(); } -// _ValidateMinMax + void BSplitLayout::_ValidateMinMax() { @@ -1152,7 +1287,7 @@ BSplitLayout::_ValidateMinMax() view->ResetLayoutInvalidation(); } -// _InternalGetHeightForWidth + void BSplitLayout::_InternalGetHeightForWidth(float width, bool realLayout, float* minHeight, float* maxHeight, float* preferredHeight) @@ -1221,7 +1356,7 @@ BSplitLayout::_InternalGetHeightForWidth(float width, bool realLayout, *preferredHeight = fCachedPreferredHeightForWidth; } -// _SplitterSpace + float BSplitLayout::_SplitterSpace() const { @@ -1235,7 +1370,7 @@ BSplitLayout::_SplitterSpace() const return space; } -// _AddInsets + BSize BSplitLayout::_AddInsets(BSize size) { @@ -1253,7 +1388,7 @@ BSplitLayout::_AddInsets(BSize size) return size; } -// _AddInsets + void BSplitLayout::_AddInsets(float* minHeight, float* maxHeight, float* preferredHeight) @@ -1269,7 +1404,7 @@ BSplitLayout::_AddInsets(float* minHeight, float* maxHeight, *preferredHeight = BLayoutUtils::AddDistances(*preferredHeight, insets); } -// _SubtractInsets + BSize BSplitLayout::_SubtractInsets(BSize size) { diff --git a/src/kits/interface/SplitLayout.h b/src/kits/interface/SplitLayout.h index 353fb50178..84a6dc5c24 100644 --- a/src/kits/interface/SplitLayout.h +++ b/src/kits/interface/SplitLayout.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku Inc. + * Copyright 2006-2010, Haiku Inc. * Distributed under the terms of the MIT License. */ #ifndef _SPLIT_LAYOUT_H @@ -25,6 +25,7 @@ class BSplitLayout : public BLayout { public: BSplitLayout(enum orientation orientation, float spacing = 0.0f); + BSplitLayout(BMessage* from); virtual ~BSplitLayout(); void SetInsets(float left, float top, float right, @@ -87,6 +88,15 @@ public: bool StopDraggingSplitter(); int32 DraggedSplitter() const; + // archiving methods + virtual status_t Archive(BMessage* into, bool deep = true) const; + static BArchivable* Instantiate(BMessage* from); + + virtual status_t ItemArchived(BMessage* into, BLayoutItem* item, + int32 index) const; + virtual status_t ItemUnarchived(const BMessage* from, + BLayoutItem* item, int32 index); + protected: virtual void ItemAdded(BLayoutItem* item); virtual void ItemRemoved(BLayoutItem* item); @@ -121,7 +131,7 @@ private: void _ValidateMinMax(); - void _InternalGetHeightForWidth(float width, + void _InternalGetHeightForWidth(float width, bool realLayout, float* minHeight, float* maxHeight, float* preferredHeight);