Patch by Alex Wilson:

* Added archiving/unarchiving support.
* Coding style cleanup (some more by myself).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37548 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-07-17 01:46:40 +00:00
parent 39c72631a3
commit 4b20c303bd
2 changed files with 245 additions and 100 deletions
+233 -98
View File
@@ -3,18 +3,35 @@
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "SplitLayout.h"
#include <new>
#include <stdio.h>
#include <LayoutItem.h>
#include <LayoutUtils.h>
#include <Message.h>
#include <View.h>
#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)
{
+12 -2
View File
@@ -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);