Big change deriving BLayout from BLayoutItem, and allowing viewless BLayouts.

a few highlights:
* BLayout now derives publicly from BLayoutItem
* Added BAbstractLayout class, which our layouts now derive from
* updated layout builders to avoid creating views when they don't need to
* updated layout classes
* updated AboutSystem to fix a little regression
* more details on #6407
* please tell me about any regressions, I've tried to find them all, but some
  may have slipped by.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38207 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alex Wilson
2010-08-17 18:43:41 +00:00
parent 0f274fd5b2
commit 1d6c7b6cb6
28 changed files with 1546 additions and 312 deletions
+8 -8
View File
@@ -7,8 +7,8 @@
#ifndef BALM_LAYOUT_H #ifndef BALM_LAYOUT_H
#define BALM_LAYOUT_H #define BALM_LAYOUT_H
#include <AbstractLayout.h>
#include <File.h> #include <File.h>
#include <Layout.h>
#include <List.h> #include <List.h>
#include <Size.h> #include <Size.h>
#include <SupportDefs.h> #include <SupportDefs.h>
@@ -29,7 +29,7 @@ namespace BALM {
/** /**
* A GUI layout engine using the ALM. * A GUI layout engine using the ALM.
*/ */
class BALMLayout : public BLayout, public LinearSpec { class BALMLayout : public BAbstractLayout, public LinearSpec {
public: public:
BALMLayout(); BALMLayout();
@@ -70,15 +70,15 @@ public:
bool RemoveItem(BLayoutItem* item); bool RemoveItem(BLayoutItem* item);
BLayoutItem* RemoveItem(int32 index); BLayoutItem* RemoveItem(int32 index);
BSize MinSize(); BSize BaseMinSize();
BSize MaxSize(); BSize BaseMaxSize();
BSize PreferredSize(); BSize BasePreferredSize();
BAlignment Alignment(); BAlignment BaseAlignment();
bool HasHeightForWidth(); bool HasHeightForWidth();
void GetHeightForWidth(float width, float* min, void GetHeightForWidth(float width, float* min,
float* max, float* preferred); float* max, float* preferred);
void InvalidateLayout(); void InvalidateLayout(bool children = false);
void LayoutView(); virtual void DerivedLayoutItems();
char* PerformancePath() const; char* PerformancePath() const;
void SetPerformancePath(char* path); void SetPerformancePath(char* path);
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright 2010, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _ABSTRACT_LAYOUT_H
#define _ABSTRACT_LAYOUT_H
#include <Alignment.h>
#include <Layout.h>
#include <Size.h>
class BAbstractLayout : public BLayout {
public:
BAbstractLayout();
BAbstractLayout(BMessage* from);
virtual ~BAbstractLayout();
virtual BSize MinSize();
virtual BSize MaxSize();
virtual BSize PreferredSize();
virtual BAlignment Alignment();
virtual void SetExplicitMinSize(BSize size);
virtual void SetExplicitMaxSize(BSize size);
virtual void SetExplicitPreferredSize(BSize size);
virtual void SetExplicitAlignment(BAlignment alignment);
virtual BSize BaseMinSize();
virtual BSize BaseMaxSize();
virtual BSize BasePreferredSize();
virtual BAlignment BaseAlignment();
virtual BRect Frame();
virtual void SetFrame(BRect frame);
virtual bool IsVisible();
virtual void SetVisible(bool visible);
virtual status_t Archive(BMessage* into, bool deep = true) const;
virtual status_t AllUnarchived(const BMessage* from);
protected:
virtual void OwnerChanged(BView* was);
virtual void AncestorVisibilityChanged(bool shown);
private:
struct Proxy;
struct ViewProxy;
struct DataProxy;
Proxy* fExplicitData;
};
#endif // _ABSTRACT_LAYOUT_ITEM_H
+8 -8
View File
@@ -5,10 +5,10 @@
#ifndef _CARD_LAYOUT_H #ifndef _CARD_LAYOUT_H
#define _CARD_LAYOUT_H #define _CARD_LAYOUT_H
#include <Layout.h> #include <AbstractLayout.h>
class BCardLayout : public BLayout { class BCardLayout : public BAbstractLayout {
public: public:
BCardLayout(); BCardLayout();
BCardLayout(BMessage* from); BCardLayout(BMessage* from);
@@ -19,23 +19,23 @@ public:
void SetVisibleItem(int32 index); void SetVisibleItem(int32 index);
void SetVisibleItem(BLayoutItem* item); void SetVisibleItem(BLayoutItem* item);
virtual BSize MinSize(); virtual BSize BaseMinSize();
virtual BSize MaxSize(); virtual BSize BaseMaxSize();
virtual BSize PreferredSize(); virtual BSize BasePreferredSize();
virtual BAlignment Alignment(); virtual BAlignment BaseAlignment();
virtual bool HasHeightForWidth(); virtual bool HasHeightForWidth();
virtual void GetHeightForWidth(float width, float* min, virtual void GetHeightForWidth(float width, float* min,
float* max, float* preferred); float* max, float* preferred);
virtual void InvalidateLayout(); virtual void InvalidateLayout(bool children = false);
virtual void LayoutView();
virtual status_t Archive(BMessage* into, bool deep = true) const; virtual status_t Archive(BMessage* into, bool deep = true) const;
virtual status_t AllUnarchived(const BMessage* from); virtual status_t AllUnarchived(const BMessage* from);
static BArchivable* Instantiate(BMessage* from); static BArchivable* Instantiate(BMessage* from);
protected: protected:
virtual void DerivedLayoutItems();
virtual bool ItemAdded(BLayoutItem* item, int32 atIndex); virtual bool ItemAdded(BLayoutItem* item, int32 atIndex);
virtual void ItemRemoved(BLayoutItem* item, int32 fromIndex); virtual void ItemRemoved(BLayoutItem* item, int32 fromIndex);
+2 -3
View File
@@ -16,9 +16,9 @@ public:
BGridLayoutBuilder(BGridView* view); BGridLayoutBuilder(BGridView* view);
BGridLayout* GridLayout() const; BGridLayout* GridLayout() const;
BView* View() const;
BGridLayoutBuilder& GetGridLayout(BGridLayout** _layout); BGridLayoutBuilder& GetGridLayout(BGridLayout** _layout);
BGridLayoutBuilder& GetView(BView** _view); BView* View() const;
BGridLayoutBuilder& GetView(BView** _view);
BGridLayoutBuilder& Add(BView* view, int32 column, int32 row, BGridLayoutBuilder& Add(BView* view, int32 column, int32 row,
int32 columnCount = 1, int32 rowCount = 1); int32 columnCount = 1, int32 rowCount = 1);
@@ -32,7 +32,6 @@ public:
float bottom); float bottom);
operator BGridLayout*(); operator BGridLayout*();
operator BView*();
private: private:
BGridLayout* fLayout; BGridLayout* fLayout;
+1 -2
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. * Distributed under the terms of the MIT License.
*/ */
#ifndef _GROUP_LAYOUT_BUILDER_H #ifndef _GROUP_LAYOUT_BUILDER_H
@@ -39,7 +39,6 @@ public:
float bottom); float bottom);
operator BGroupLayout*(); operator BGroupLayout*();
operator BView*();
private: private:
bool _PushLayout(BGroupLayout* layout); bool _PushLayout(BGroupLayout* layout);
+49 -13
View File
@@ -8,22 +8,27 @@
#include <Alignment.h> #include <Alignment.h>
#include <Archivable.h> #include <Archivable.h>
#include <LayoutItem.h>
#include <List.h> #include <List.h>
#include <Size.h> #include <Size.h>
class BLayoutContext;
class BLayoutItem; class BLayoutItem;
class BView; class BView;
class BLayout : public BArchivable { class BLayout : public BLayoutItem {
public: public:
BLayout(); BLayout();
BLayout(BMessage* archive); BLayout(BMessage* archive);
virtual ~BLayout(); virtual ~BLayout();
BView* View() const; BView* Owner() const;
BView* TargetView() const;
virtual BView* View(); // from BLayoutItem
// methods dealing with items
virtual BLayoutItem* AddView(BView* child); virtual BLayoutItem* AddView(BView* child);
virtual BLayoutItem* AddView(int32 index, BView* child); virtual BLayoutItem* AddView(int32 index, BView* child);
@@ -39,18 +44,22 @@ public:
int32 IndexOfItem(const BLayoutItem* item) const; int32 IndexOfItem(const BLayoutItem* item) const;
int32 IndexOfView(BView* child) const; int32 IndexOfView(BView* child) const;
virtual BSize MinSize() = 0; bool AncestorsVisible();
virtual BSize MaxSize() = 0;
virtual BSize PreferredSize() = 0;
virtual BAlignment Alignment() = 0;
virtual bool HasHeightForWidth() = 0; // Layouting related methods
virtual void GetHeightForWidth(float width, float* min,
float* max, float* preferred) = 0;
virtual void InvalidateLayout(); virtual void InvalidateLayout(bool children = false);
virtual void Relayout(bool immediate = false);
void RequireLayout();
bool IsValid();
void EnableLayoutInvalidation();
void DisableLayoutInvalidation();
virtual void LayoutView() = 0; void LayoutItems(bool force = false);
BRect LayoutArea();
BLayoutContext* LayoutContext();
// Archiving methods
virtual status_t Archive(BMessage* into, bool deep = true) const; virtual status_t Archive(BMessage* into, bool deep = true) const;
virtual status_t AllUnarchived(const BMessage* from); virtual status_t AllUnarchived(const BMessage* from);
@@ -59,17 +68,44 @@ public:
int32 index) const; int32 index) const;
virtual status_t ItemUnarchived(const BMessage* from, virtual status_t ItemUnarchived(const BMessage* from,
BLayoutItem* item, int32 index); BLayoutItem* item, int32 index);
protected: protected:
// BLayout hook methods
virtual bool ItemAdded(BLayoutItem* item, int32 atIndex); virtual bool ItemAdded(BLayoutItem* item, int32 atIndex);
virtual void ItemRemoved(BLayoutItem* item, int32 fromIndex); virtual void ItemRemoved(BLayoutItem* item, int32 fromIndex);
virtual void DerivedLayoutItems() = 0;
virtual void OwnerChanged(BView* was);
// BLayoutItem hook methods
virtual void AttachedToLayout();
virtual void DetachedFromLayout(BLayout* layout);
virtual void AncestorVisibilityChanged(bool shown);
// To be called by sub-classes in SetVisible().
void VisibilityChanged(bool show);
// To be called when layout data is known to be good
void ResetLayoutInvalidation();
private: private:
friend class BView; friend class BView;
void SetView(BView* view); bool RemoveViewRecursive(BView* view);
bool InvalidateLayoutsForView(BView* view);
bool InvalidationLegal();
void SetOwner(BView* owner);
void SetTarget(BView* target);
BView* fView; void _LayoutWithinContext(bool force,
BLayoutContext* context);
uint32 fState;
bool fAncestorsVisible;
int32 fInvalidationDisabled;
BLayoutContext* fContext;
BView* fOwner;
BView* fTarget;
BList fItems; BList fItems;
BList fNestedLayouts;
}; };
+219 -38
View File
@@ -33,7 +33,6 @@ protected:
public: public:
inline void SetParent(ParentBuilder* parent); inline void SetParent(ParentBuilder* parent);
// conceptually private // conceptually private
inline ParentBuilder& End(); inline ParentBuilder& End();
protected: protected:
@@ -71,11 +70,23 @@ public:
inline GroupBuilder AddGroup(enum orientation orientation, inline GroupBuilder AddGroup(enum orientation orientation,
float spacing = 0.0f, float weight = 1.0f); float spacing = 0.0f, float weight = 1.0f);
inline GroupBuilder AddGroup(BGroupView* groupView,
float weight = 1.0f);
inline GroupBuilder AddGroup(BGroupLayout* groupLayout,
float weight = 1.0f);
inline GridBuilder AddGrid(float horizontalSpacing = 0.0f, inline GridBuilder AddGrid(float horizontalSpacing = 0.0f,
float verticalSpacing = 0.0f, float verticalSpacing = 0.0f,
float weight = 1.0f); float weight = 1.0f);
inline GridBuilder AddGrid(BGridLayout* gridLayout,
float weight = 1.0f);
inline GridBuilder AddGrid(BGridView* gridView,
float weight = 1.0f);
inline SplitBuilder AddSplit(enum orientation orientation, inline SplitBuilder AddSplit(enum orientation orientation,
float spacing = 0.0f, float weight = 1.0f); float spacing = 0.0f, float weight = 1.0f);
inline SplitBuilder AddSplit(BSplitView* splitView,
float weight = 1.0f);
inline ThisBuilder& AddGlue(float weight = 1.0f); inline ThisBuilder& AddGlue(float weight = 1.0f);
inline ThisBuilder& AddStrut(float size); inline ThisBuilder& AddStrut(float size);
@@ -84,7 +95,6 @@ public:
float bottom); float bottom);
inline operator BGroupLayout*(); inline operator BGroupLayout*();
inline operator BView*();
private: private:
BGroupLayout* fLayout; BGroupLayout* fLayout;
@@ -131,13 +141,30 @@ public:
inline GroupBuilder AddGroup(enum orientation orientation, inline GroupBuilder AddGroup(enum orientation orientation,
float spacing, int32 column, int32 row, float spacing, int32 column, int32 row,
int32 columnCount = 1, int32 rowCount = 1); int32 columnCount = 1, int32 rowCount = 1);
inline GroupBuilder AddGroup(BGroupView* groupView, int32 column,
int32 row, int32 columnCount = 1,
int32 rowCount = 1);
inline GroupBuilder AddGroup(BGroupLayout* groupLayout,
int32 column, int32 row,
int32 columnCount = 1, int32 rowCount = 1);
inline GridBuilder AddGrid(float horizontalSpacing, inline GridBuilder AddGrid(float horizontalSpacing,
float verticalSpacing, int32 column, float verticalSpacing, int32 column,
int32 row, int32 columnCount = 1, int32 row, int32 columnCount = 1,
int32 rowCount = 1); int32 rowCount = 1);
inline GridBuilder AddGrid(BGridLayout* gridLayout,
int32 column, int32 row,
int32 columnCount = 1, int32 rowCount = 1);
inline GridBuilder AddGrid(BGridView* gridView,
int32 column, int32 row,
int32 columnCount = 1, int32 rowCount = 1);
inline SplitBuilder AddSplit(enum orientation orientation, inline SplitBuilder AddSplit(enum orientation orientation,
float spacing, int32 column, int32 row, float spacing, int32 column, int32 row,
int32 columnCount = 1, int32 rowCount = 1); int32 columnCount = 1, int32 rowCount = 1);
inline SplitBuilder AddSplit(BSplitView* splitView, int32 column,
int32 row, int32 columnCount = 1,
int32 rowCount = 1);
inline ThisBuilder& SetColumnWeight(int32 column, float weight); inline ThisBuilder& SetColumnWeight(int32 column, float weight);
inline ThisBuilder& SetRowWeight(int32 row, float weight); inline ThisBuilder& SetRowWeight(int32 row, float weight);
@@ -146,7 +173,6 @@ public:
float bottom); float bottom);
inline operator BGridLayout*(); inline operator BGridLayout*();
inline operator BView*();
private: private:
BGridLayout* fLayout; BGridLayout* fLayout;
@@ -168,7 +194,8 @@ public:
inline Split(BSplitView* view); inline Split(BSplitView* view);
inline BSplitView* View() const; inline BSplitView* View() const;
inline ThisBuilder& GetView(BSplitView** _view); inline ThisBuilder& GetView(BView** _view);
inline ThisBuilder& GetSplitView(BSplitView** _view);
inline ThisBuilder& Add(BView* view); inline ThisBuilder& Add(BView* view);
inline ThisBuilder& Add(BView* view, float weight); inline ThisBuilder& Add(BView* view, float weight);
@@ -177,11 +204,23 @@ public:
inline GroupBuilder AddGroup(enum orientation orientation, inline GroupBuilder AddGroup(enum orientation orientation,
float spacing = 0.0f, float weight = 1.0f); float spacing = 0.0f, float weight = 1.0f);
inline GroupBuilder AddGroup(BGroupView* groupView,
float weight = 1.0f);
inline GroupBuilder AddGroup(BGroupLayout* groupLayout,
float weight = 1.0f);
inline GridBuilder AddGrid(float horizontalSpacing = 0.0f, inline GridBuilder AddGrid(float horizontalSpacing = 0.0f,
float verticalSpacing = 0.0f, float verticalSpacing = 0.0f,
float weight = 1.0f); float weight = 1.0f);
inline GridBuilder AddGrid(BGridView* gridView,
float weight = 1.0f);
inline GridBuilder AddGrid(BGridLayout* gridLayout,
float weight = 1.0f);
inline SplitBuilder AddSplit(enum orientation orientation, inline SplitBuilder AddSplit(enum orientation orientation,
float spacing = 0.0f, float weight = 1.0f); float spacing = 0.0f, float weight = 1.0f);
inline SplitBuilder AddSplit(BSplitView* splitView,
float weight = 1.0f);
inline ThisBuilder& SetCollapsible(bool collapsible); inline ThisBuilder& SetCollapsible(bool collapsible);
inline ThisBuilder& SetCollapsible(int32 index, bool collapsible); inline ThisBuilder& SetCollapsible(int32 index, bool collapsible);
@@ -244,7 +283,7 @@ Group<ParentBuilder>::Group(BWindow* window, enum orientation orientation,
{ {
window->SetLayout(fLayout); window->SetLayout(fLayout);
fLayout->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
// TODO: we get a white background if we don't do this // TODO: we get a white background if we don't do this
} }
@@ -277,7 +316,7 @@ template<typename ParentBuilder>
BView* BView*
Group<ParentBuilder>::View() const Group<ParentBuilder>::View() const
{ {
return fLayout->View(); return fLayout->Owner();
} }
@@ -294,7 +333,7 @@ template<typename ParentBuilder>
typename Group<ParentBuilder>::ThisBuilder& typename Group<ParentBuilder>::ThisBuilder&
Group<ParentBuilder>::GetView(BView** _view) Group<ParentBuilder>::GetView(BView** _view)
{ {
*_view = fLayout->View(); *_view = fLayout->Owner();
return *this; return *this;
} }
@@ -340,21 +379,65 @@ typename Group<ParentBuilder>::GroupBuilder
Group<ParentBuilder>::AddGroup(enum orientation orientation, float spacing, Group<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
float weight) float weight)
{ {
GroupBuilder builder(orientation, spacing); GroupBuilder builder(new BGroupLayout(orientation, spacing));
builder.SetParent(this); builder.SetParent(this);
fLayout->AddView(builder.View(), weight); fLayout->AddItem(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Group<ParentBuilder>::GroupBuilder
Group<ParentBuilder>::AddGroup(BGroupView* groupView, float weight)
{
GroupBuilder builder(groupView);
builder.SetParent(this);
fLayout->AddItem(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Group<ParentBuilder>::GroupBuilder
Group<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight)
{
GroupBuilder builder(groupLayout);
builder.SetParent(this);
fLayout->AddItem(builder.Layout(), weight);
return builder; return builder;
} }
template<typename ParentBuilder> template<typename ParentBuilder>
typename Group<ParentBuilder>::GridBuilder typename Group<ParentBuilder>::GridBuilder
Group<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, Group<ParentBuilder>::AddGrid(float horizontalSpacing,
float weight) float verticalSpacing, float weight)
{ {
GridBuilder builder(horizontalSpacing, verticalSpacing); GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
builder.SetParent(this); builder.SetParent(this);
fLayout->AddView(builder.View(), weight); fLayout->AddItem(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Group<ParentBuilder>::GridBuilder
Group<ParentBuilder>::AddGrid(BGridLayout* gridLayout, float weight)
{
GridBuilder builder(gridLayout);
builder.SetParent(this);
fLayout->AddItem(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Group<ParentBuilder>::GridBuilder
Group<ParentBuilder>::AddGrid(BGridView* gridView, float weight)
{
GridBuilder builder(gridView);
builder.SetParent(this);
fLayout->AddItem(builder.Layout(), weight);
return builder; return builder;
} }
@@ -371,6 +454,17 @@ Group<ParentBuilder>::AddSplit(enum orientation orientation, float spacing,
} }
template<typename ParentBuilder>
typename Group<ParentBuilder>::SplitBuilder
Group<ParentBuilder>::AddSplit(BSplitView* splitView, float weight)
{
SplitBuilder builder(splitView);
builder.SetParent(this);
fLayout->AddView(builder.View(), weight);
return builder;
}
template<typename ParentBuilder> template<typename ParentBuilder>
typename Group<ParentBuilder>::ThisBuilder& typename Group<ParentBuilder>::ThisBuilder&
Group<ParentBuilder>::AddGlue(float weight) Group<ParentBuilder>::AddGlue(float weight)
@@ -410,13 +504,6 @@ Group<ParentBuilder>::operator BGroupLayout*()
} }
template<typename ParentBuilder>
Group<ParentBuilder>::operator BView*()
{
return fLayout->View();
}
// #pragma mark - Grid // #pragma mark - Grid
@@ -436,7 +523,7 @@ Grid<ParentBuilder>::Grid(BWindow* window, float horizontalSpacing,
{ {
window->SetLayout(fLayout); window->SetLayout(fLayout);
fLayout->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
// TODO: we get a white background if we don't do this // TODO: we get a white background if we don't do this
} }
@@ -469,7 +556,7 @@ template<typename ParentBuilder>
BView* BView*
Grid<ParentBuilder>::View() const Grid<ParentBuilder>::View() const
{ {
return fLayout->View(); return fLayout->Owner();
} }
@@ -486,7 +573,7 @@ template<typename ParentBuilder>
typename Grid<ParentBuilder>::ThisBuilder& typename Grid<ParentBuilder>::ThisBuilder&
Grid<ParentBuilder>::GetView(BView** _view) Grid<ParentBuilder>::GetView(BView** _view)
{ {
*_view = fLayout->View(); *_view = fLayout->Owner();
return *this; return *this;
} }
@@ -546,9 +633,33 @@ typename Grid<ParentBuilder>::GroupBuilder
Grid<ParentBuilder>::AddGroup(enum orientation orientation, float spacing, Grid<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
int32 column, int32 row, int32 columnCount, int32 rowCount) int32 column, int32 row, int32 columnCount, int32 rowCount)
{ {
GroupBuilder builder(orientation, spacing); GroupBuilder builder(new BGroupLayout(orientation, spacing));
builder.SetParent(this); builder.SetParent(this);
fLayout->AddView(builder.View(), column, row, columnCount, rowCount); fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
return builder;
}
template<typename ParentBuilder>
typename Grid<ParentBuilder>::GroupBuilder
Grid<ParentBuilder>::AddGroup(BGroupView* groupView, int32 column, int32 row,
int32 columnCount, int32 rowCount)
{
GroupBuilder builder(groupView);
builder.SetParent(this);
fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
return builder;
}
template<typename ParentBuilder>
typename Grid<ParentBuilder>::GroupBuilder
Grid<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, int32 column,
int32 row, int32 columnCount, int32 rowCount)
{
GroupBuilder builder(groupLayout);
builder.SetParent(this);
fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
return builder; return builder;
} }
@@ -558,7 +669,19 @@ typename Grid<ParentBuilder>::GridBuilder
Grid<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, Grid<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing,
int32 column, int32 row, int32 columnCount, int32 rowCount) int32 column, int32 row, int32 columnCount, int32 rowCount)
{ {
GridBuilder builder(horizontalSpacing, verticalSpacing); GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
builder.SetParent(this);
fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
return builder;
}
template<typename ParentBuilder>
typename Grid<ParentBuilder>::GridBuilder
Grid<ParentBuilder>::AddGrid(BGridView* gridView, int32 column, int32 row,
int32 columnCount, int32 rowCount)
{
GridBuilder builder(gridView);
builder.SetParent(this); builder.SetParent(this);
fLayout->AddView(builder.View(), column, row, columnCount, rowCount); fLayout->AddView(builder.View(), column, row, columnCount, rowCount);
return builder; return builder;
@@ -577,6 +700,18 @@ Grid<ParentBuilder>::AddSplit(enum orientation orientation, float spacing,
} }
template<typename ParentBuilder>
typename Grid<ParentBuilder>::SplitBuilder
Grid<ParentBuilder>::AddSplit(BSplitView* splitView, int32 column, int32 row,
int32 columnCount, int32 rowCount)
{
SplitBuilder builder(splitView);
builder.SetParent(this);
fLayout->AddView(builder.View(), column, row, columnCount, rowCount);
return builder;
}
template<typename ParentBuilder> template<typename ParentBuilder>
typename Grid<ParentBuilder>::ThisBuilder& typename Grid<ParentBuilder>::ThisBuilder&
Grid<ParentBuilder>::SetColumnWeight(int32 column, float weight) Grid<ParentBuilder>::SetColumnWeight(int32 column, float weight)
@@ -612,13 +747,6 @@ Grid<ParentBuilder>::operator BGridLayout*()
} }
template<typename ParentBuilder>
Grid<ParentBuilder>::operator BView*()
{
return fLayout->View();
}
// #pragma mark - Split // #pragma mark - Split
@@ -648,7 +776,16 @@ Split<ParentBuilder>::View() const
template<typename ParentBuilder> template<typename ParentBuilder>
typename Split<ParentBuilder>::ThisBuilder& typename Split<ParentBuilder>::ThisBuilder&
Split<ParentBuilder>::GetView(BSplitView** _view) Split<ParentBuilder>::GetView(BView** _view)
{
*_view = fView;
return *this;
}
template<typename ParentBuilder>
typename Split<ParentBuilder>::ThisBuilder&
Split<ParentBuilder>::GetSplitView(BSplitView** _view)
{ {
*_view = fView; *_view = fView;
return *this; return *this;
@@ -696,9 +833,31 @@ typename Split<ParentBuilder>::GroupBuilder
Split<ParentBuilder>::AddGroup(enum orientation orientation, float spacing, Split<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
float weight) float weight)
{ {
GroupBuilder builder(orientation, spacing); GroupBuilder builder(new BGroupLayout(orientation, spacing));
builder.SetParent(this); builder.SetParent(this);
fView->AddChild(builder.View(), weight); fView->AddChild(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Split<ParentBuilder>::GroupBuilder
Split<ParentBuilder>::AddGroup(BGroupView* groupView, float weight)
{
GroupBuilder builder(groupView);
builder.SetParent(this);
fView->AddChild(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Split<ParentBuilder>::GroupBuilder
Split<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight)
{
GroupBuilder builder(groupLayout);
builder.SetParent(this);
fView->AddChild(builder.Layout(), weight);
return builder; return builder;
} }
@@ -708,9 +867,31 @@ typename Split<ParentBuilder>::GridBuilder
Split<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, Split<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing,
float weight) float weight)
{ {
GridBuilder builder(horizontalSpacing, verticalSpacing); GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
builder.SetParent(this); builder.SetParent(this);
fView->AddChild(builder.View(), weight); fView->AddChild(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Split<ParentBuilder>::GridBuilder
Split<ParentBuilder>::AddGrid(BGridView* gridView, float weight)
{
GridBuilder builder(gridView);
builder.SetParent(this);
fView->AddChild(builder.Layout(), weight);
return builder;
}
template<typename ParentBuilder>
typename Split<ParentBuilder>::GridBuilder
Split<ParentBuilder>::AddGrid(BGridLayout* layout, float weight)
{
GridBuilder builder(layout);
builder.SetParent(this);
fView->AddChild(builder.Layout(), weight);
return builder; return builder;
} }
+13 -4
View File
@@ -16,7 +16,7 @@ class BLayout;
class BView; class BView;
class BLayoutItem: public BArchivable { class BLayoutItem : public BArchivable {
public: public:
BLayoutItem(); BLayoutItem();
BLayoutItem(BMessage* from); BLayoutItem(BMessage* from);
@@ -46,7 +46,8 @@ public:
virtual BView* View(); virtual BView* View();
virtual void InvalidateLayout(); virtual void InvalidateLayout(bool children = false);
virtual void Relayout(bool immediate = false);
void* LayoutData() const; void* LayoutData() const;
void SetLayoutData(void* data); void SetLayoutData(void* data);
@@ -57,11 +58,19 @@ public:
virtual status_t AllArchived(BMessage* into) const; virtual status_t AllArchived(BMessage* into) const;
virtual status_t AllUnarchived(const BMessage* from); virtual status_t AllUnarchived(const BMessage* from);
private: protected:
friend class BLayout;
void SetLayout(BLayout* layout); void SetLayout(BLayout* layout);
// hook methods
virtual void AttachedToLayout();
virtual void DetachedFromLayout(BLayout* layout);
virtual void AncestorVisibilityChanged(bool shown);
private:
friend class BLayout;
BLayout* fLayout; BLayout* fLayout;
void* fLayoutData; void* fLayoutData;
}; };
+10 -9
View File
@@ -6,12 +6,12 @@
#define _TWO_DIMENSIONAL_LAYOUT_H #define _TWO_DIMENSIONAL_LAYOUT_H
#include <Layout.h> #include <AbstractLayout.h>
class BLayoutContext; class BLayoutContext;
class BTwoDimensionalLayout : public BLayout { class BTwoDimensionalLayout : public BAbstractLayout {
public: public:
BTwoDimensionalLayout(); BTwoDimensionalLayout();
BTwoDimensionalLayout(BMessage* from); BTwoDimensionalLayout(BMessage* from);
@@ -25,18 +25,18 @@ public:
void AlignLayoutWith(BTwoDimensionalLayout* other, void AlignLayoutWith(BTwoDimensionalLayout* other,
enum orientation orientation); enum orientation orientation);
virtual BSize MinSize(); virtual BSize BaseMinSize();
virtual BSize MaxSize(); virtual BSize BaseMaxSize();
virtual BSize PreferredSize(); virtual BSize BasePreferredSize();
virtual BAlignment Alignment(); virtual BAlignment BaseAlignment();
virtual bool HasHeightForWidth(); virtual bool HasHeightForWidth();
virtual void GetHeightForWidth(float width, float* min, virtual void GetHeightForWidth(float width, float* min,
float* max, float* preferred); float* max, float* preferred);
virtual void InvalidateLayout(); virtual void SetFrame(BRect frame);
virtual void LayoutView(); virtual void InvalidateLayout(bool children = false);
virtual status_t Archive(BMessage* into, bool deep = true) const; virtual status_t Archive(BMessage* into, bool deep = true) const;
virtual status_t AllArchived(BMessage* into) const; virtual status_t AllArchived(BMessage* into) const;
@@ -56,6 +56,8 @@ protected:
int32 height; int32 height;
}; };
virtual void DerivedLayoutItems();
BSize AddInsets(BSize size); BSize AddInsets(BSize size);
void AddInsets(float* minHeight, float* maxHeight, void AddInsets(float* minHeight, float* maxHeight,
float* preferredHeight); float* preferredHeight);
@@ -82,7 +84,6 @@ private:
friend class LocalLayouter; friend class LocalLayouter;
void _ValidateMinMax(); void _ValidateMinMax();
BLayoutContext* _CurrentLayoutContext();
protected: protected:
float fLeftInset; float fLeftInset;
+5
View File
@@ -562,6 +562,8 @@ public:
void Layout(bool force); void Layout(bool force);
void Relayout(); void Relayout();
class Private;
protected: protected:
virtual void DoLayout(); virtual void DoLayout();
@@ -580,6 +582,8 @@ protected:
private: private:
void _Layout(bool force, BLayoutContext* context); void _Layout(bool force, BLayoutContext* context);
void _LayoutLeft(BLayout* deleted);
void _InvalidateParentLayout();
private: private:
// FBC padding and forbidden methods // FBC padding and forbidden methods
@@ -595,6 +599,7 @@ private:
private: private:
struct LayoutData; struct LayoutData;
friend class Private;
friend class BBitmap; friend class BBitmap;
friend class BLayout; friend class BLayout;
friend class BPrintJob; friend class BPrintJob;
+1
View File
@@ -103,6 +103,7 @@ public:
void Close() { Quit(); } void Close() { Quit(); }
void AddChild(BView* child, BView* before = NULL); void AddChild(BView* child, BView* before = NULL);
void AddChild(BLayoutItem* child);
bool RemoveChild(BView* child); bool RemoveChild(BView* child);
int32 CountChildren() const; int32 CountChildren() const;
BView* ChildAt(int32 index) const; BView* ChildAt(int32 index) const;
+22
View File
@@ -16,6 +16,7 @@
#include <Rect.h> #include <Rect.h>
#include <Region.h> #include <Region.h>
#include <ServerProtocolStructs.h> #include <ServerProtocolStructs.h>
#include <View.h>
const static uint32 kDeleteReplicant = 'JAHA'; const static uint32 kDeleteReplicant = 'JAHA';
@@ -48,6 +49,27 @@ enum {
}; };
class BView::Private {
public:
Private(BView* view)
:
fView(view)
{
}
int16 ShowLevel()
{
return fView->fShowLevel;
}
// defined in View.cpp
bool WillLayout();
bool MinMaxValid();
BView* fView;
};
namespace BPrivate { namespace BPrivate {
class PortLink; class PortLink;
+1
View File
@@ -579,6 +579,7 @@ AboutView::AboutView()
const float offset = 5; const float offset = 5;
SetLayout(new BGroupLayout(B_HORIZONTAL)); SetLayout(new BGroupLayout(B_HORIZONTAL));
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) BLayoutBuilder::Group<>((BGroupLayout*)GetLayout())
.AddGroup(B_VERTICAL) .AddGroup(B_VERTICAL)
+468
View File
@@ -0,0 +1,468 @@
/*
* Copyright 2010, Haiku, Inc.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <AbstractLayout.h>
#include <LayoutUtils.h>
#include <Message.h>
#include <View.h>
#include <ViewPrivate.h>
namespace {
const char* const kSizesField = "BAbstractLayout:sizes";
// kSizesField == {min, max, preferred}
const char* const kAlignmentField = "BAbstractLayout:alignment";
const char* const kFrameField = "BAbstractLayout:frame";
const char* const kVisibleField = "BAbstractLayout:visible";
enum proxy_type { VIEW_PROXY_TYPE, DATA_PROXY_TYPE };
}
struct BAbstractLayout::Proxy {
Proxy(proxy_type type)
:
type(type)
{
}
virtual BSize MinSize() const = 0;
virtual void SetMinSize(const BSize&) = 0;
virtual BSize MaxSize() const = 0;
virtual void SetMaxSize(const BSize&) = 0;
virtual BSize PreferredSize() const = 0;
virtual void SetPreferredSize(const BSize&) = 0;
virtual BAlignment Alignment() const = 0;
virtual void SetAlignment(const BAlignment&) = 0;
virtual BRect Frame() const = 0;
virtual void SetFrame(const BRect& frame) = 0;
virtual bool IsVisible(bool ancestorHidden) const = 0;
virtual void SetVisible(bool visible) = 0;
virtual status_t AddDataToArchive(BMessage* archive,
bool ancestorHidden) = 0;
virtual status_t RestoreDataFromArchive(const BMessage* archive) = 0;
proxy_type type;
};
struct BAbstractLayout::DataProxy : Proxy {
DataProxy()
:
Proxy(DATA_PROXY_TYPE),
minSize(),
maxSize(),
preferredSize(),
alignment(),
frame(-1, -1, 0, 0),
visible(true)
{
}
BSize MinSize() const
{
return minSize;
}
void SetMinSize(const BSize& min)
{
minSize = min;
}
BSize MaxSize() const
{
return maxSize;
}
void SetMaxSize(const BSize& max)
{
maxSize = max;
}
BSize PreferredSize() const
{
return preferredSize;
}
void SetPreferredSize(const BSize& preferred)
{
preferredSize = preferred;
}
BAlignment Alignment() const
{
return this->alignment;
}
void SetAlignment(const BAlignment& align)
{
this->alignment = align;
}
BRect Frame() const
{
return frame;
}
void SetFrame(const BRect& frame)
{
if (frame == this->frame)
return;
this->frame = frame;
}
bool IsVisible(bool) const
{
return visible;
}
void SetVisible(bool visible)
{
this->visible = visible;
}
status_t AddDataToArchive(BMessage* archive, bool ancestorHidden)
{
status_t err = archive->AddSize(kSizesField, minSize);
if (err == B_OK)
err = archive->AddSize(kSizesField, maxSize);
if (err == B_OK)
err = archive->AddSize(kSizesField, preferredSize);
if (err == B_OK)
err = archive->AddAlignment(kAlignmentField, alignment);
if (err == B_OK)
err = archive->AddRect(kFrameField, frame);
if (err == B_OK)
err = archive->AddBool(kVisibleField, visible);
return err;
}
status_t RestoreDataFromArchive(const BMessage* archive)
{
status_t err = archive->FindSize(kSizesField, 0, &minSize);
if (err == B_OK)
err = archive->FindSize(kSizesField, 1, &maxSize);
if (err == B_OK)
err = archive->FindSize(kSizesField, 2, &preferredSize);
if (err == B_OK)
err = archive->FindAlignment(kAlignmentField, &alignment);
if (err == B_OK)
err = archive->FindRect(kFrameField, &frame);
if (err == B_OK)
err = archive->FindBool(kVisibleField, &visible);
return err;
}
BSize minSize;
BSize maxSize;
BSize preferredSize;
BAlignment alignment;
BRect frame;
bool visible;
};
struct BAbstractLayout::ViewProxy : Proxy {
ViewProxy(BView* target)
:
Proxy(VIEW_PROXY_TYPE),
view(target)
{
}
BSize MinSize() const
{
return view->ExplicitMinSize();
}
void SetMinSize(const BSize& min)
{
view->SetExplicitMinSize(min);
}
BSize MaxSize() const
{
return view->ExplicitMaxSize();
}
void SetMaxSize(const BSize& min)
{
view->SetExplicitMaxSize(min);
}
BSize PreferredSize() const
{
return view->ExplicitPreferredSize();
}
void SetPreferredSize(const BSize& preferred)
{
view->SetExplicitPreferredSize(preferred);
}
BAlignment Alignment() const
{
return view->ExplicitAlignment();
}
void SetAlignment(const BAlignment& alignment)
{
view->SetExplicitAlignment(alignment);
}
BRect Frame() const
{
return view->Frame();
}
void SetFrame(const BRect& frame)
{
view->MoveTo(frame.LeftTop());
view->ResizeTo(frame.Width(), frame.Height());
}
bool IsVisible(bool ancestorsVisible) const
{
int16 showLevel = BView::Private(view).ShowLevel();
return (showLevel - (ancestorsVisible) ? 0 : 1) <= 0;
}
void SetVisible(bool visible)
{
// No need to check that we are not re-hiding, that is done
// for us.
if (visible)
view->Show();
else
view->Hide();
}
status_t AddDataToArchive(BMessage* archive, bool ancestorHidden)
{
return B_OK;
}
status_t RestoreDataFromArchive(const BMessage* archive)
{
return B_OK;
}
BView* view;
};
BAbstractLayout::BAbstractLayout()
:
fExplicitData(new BAbstractLayout::DataProxy())
{
}
BAbstractLayout::BAbstractLayout(BMessage* from)
:
BLayout(BUnarchiver::PrepareArchive(from)),
fExplicitData(new DataProxy())
{
BUnarchiver(from).Finish();
}
BAbstractLayout::~BAbstractLayout()
{
delete fExplicitData;
}
BSize
BAbstractLayout::MinSize()
{
return BLayoutUtils::ComposeSize(fExplicitData->MinSize(), BaseMinSize());
}
BSize
BAbstractLayout::MaxSize()
{
return BLayoutUtils::ComposeSize(fExplicitData->MaxSize(), BaseMaxSize());
}
BSize
BAbstractLayout::PreferredSize()
{
return BLayoutUtils::ComposeSize(fExplicitData->PreferredSize(),
BasePreferredSize());
}
BAlignment
BAbstractLayout::Alignment()
{
return BLayoutUtils::ComposeAlignment(fExplicitData->Alignment(),
BaseAlignment());
}
void
BAbstractLayout::SetExplicitMinSize(BSize size)
{
fExplicitData->SetMinSize(size);
}
void
BAbstractLayout::SetExplicitMaxSize(BSize size)
{
fExplicitData->SetMaxSize(size);
}
void
BAbstractLayout::SetExplicitPreferredSize(BSize size)
{
fExplicitData->SetPreferredSize(size);
}
void
BAbstractLayout::SetExplicitAlignment(BAlignment alignment)
{
fExplicitData->SetAlignment(alignment);
}
BSize
BAbstractLayout::BaseMinSize()
{
return BSize(0, 0);
}
BSize
BAbstractLayout::BaseMaxSize()
{
return BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
}
BSize
BAbstractLayout::BasePreferredSize()
{
return BSize(0, 0);
}
BAlignment
BAbstractLayout::BaseAlignment()
{
return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
}
BRect
BAbstractLayout::Frame()
{
return fExplicitData->Frame();
}
void
BAbstractLayout::SetFrame(BRect frame)
{
if (frame != fExplicitData->Frame()) {
fExplicitData->SetFrame(frame);
if (!Owner())
Relayout();
}
}
bool
BAbstractLayout::IsVisible()
{
return fExplicitData->IsVisible(AncestorsVisible());
}
void
BAbstractLayout::SetVisible(bool visible)
{
if (visible != fExplicitData->IsVisible(AncestorsVisible())) {
fExplicitData->SetVisible(visible);
if (Layout())
Layout()->InvalidateLayout(false);
VisibilityChanged(visible);
}
}
status_t
BAbstractLayout::Archive(BMessage* into, bool deep) const
{
BArchiver archiver(into);
status_t err = BLayout::Archive(into, deep);
return archiver.Finish(err);
}
status_t
BAbstractLayout::AllUnarchived(const BMessage* from)
{
if (Owner()) {
ViewProxy* proxy = dynamic_cast<ViewProxy*>(fExplicitData);
if (!proxy) {
delete fExplicitData;
proxy = new ViewProxy(Owner());
}
proxy->view = Owner();
} else {
fExplicitData = new DataProxy();
return fExplicitData->RestoreDataFromArchive(from);
}
return BLayout::AllUnarchived(from);
}
void
BAbstractLayout::OwnerChanged(BView* was)
{
if (was) {
static_cast<ViewProxy*>(fExplicitData)->view = Owner();
return;
}
delete fExplicitData;
fExplicitData = new ViewProxy(Owner());
}
void
BAbstractLayout::AncestorVisibilityChanged(bool shown)
{
if (AncestorsVisible() == shown)
return;
if (BView* owner = Owner()) {
if (shown)
owner->Show();
else
owner->Hide();
}
BLayout::AncestorVisibilityChanged(shown);
}
+22 -19
View File
@@ -17,7 +17,7 @@ namespace {
BCardLayout::BCardLayout() BCardLayout::BCardLayout()
: :
BLayout(), BAbstractLayout(),
fMin(0, 0), fMin(0, 0),
fMax(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED), fMax(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED),
fPreferred(0, 0), fPreferred(0, 0),
@@ -29,7 +29,7 @@ BCardLayout::BCardLayout()
BCardLayout::BCardLayout(BMessage* from) BCardLayout::BCardLayout(BMessage* from)
: :
BLayout(BUnarchiver::PrepareArchive(from)), BAbstractLayout(BUnarchiver::PrepareArchive(from)),
fMin(0, 0), fMin(0, 0),
fMax(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED), fMax(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED),
fPreferred(0, 0), fPreferred(0, 0),
@@ -83,13 +83,13 @@ BCardLayout::SetVisibleItem(BLayoutItem* item)
if (fVisibleItem != NULL) { if (fVisibleItem != NULL) {
fVisibleItem->SetVisible(true); fVisibleItem->SetVisible(true);
LayoutView(); Relayout();
} }
} }
BSize BSize
BCardLayout::MinSize() BCardLayout::BaseMinSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
return fMin; return fMin;
@@ -97,7 +97,7 @@ BCardLayout::MinSize()
BSize BSize
BCardLayout::MaxSize() BCardLayout::BaseMaxSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
return fMax; return fMax;
@@ -105,7 +105,7 @@ BCardLayout::MaxSize()
BSize BSize
BCardLayout::PreferredSize() BCardLayout::BasePreferredSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
return fPreferred; return fPreferred;
@@ -113,7 +113,7 @@ BCardLayout::PreferredSize()
BAlignment BAlignment
BCardLayout::Alignment() BCardLayout::BaseAlignment()
{ {
return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
} }
@@ -174,25 +174,30 @@ BCardLayout::GetHeightForWidth(float width, float* min, float* max,
void void
BCardLayout::InvalidateLayout() BCardLayout::InvalidateLayout(bool children)
{ {
BLayout::InvalidateLayout(); BLayout::InvalidateLayout(children);
fMinMaxValid = false; fMinMaxValid = false;
} }
void void
BCardLayout::LayoutView() BCardLayout::DerivedLayoutItems()
{ {
_ValidateMinMax(); _ValidateMinMax();
BSize size = View()->Bounds().Size(); BSize size(LayoutArea().Size());
size.width = max_c(size.width, fMin.width);
size.height = max_c(size.height, fMin.height);
if (fVisibleItem != NULL) // this cannot be done when we are viewless, as our children
fVisibleItem->AlignInFrame(BRect(0, 0, size.width, size.height)); // would not get cut off in the right place.
if (Owner()) {
size.width = max_c(size.width, fMin.width);
size.height = max_c(size.height, fMin.height);
}
if (fVisibleItem != NULL)
fVisibleItem->AlignInFrame(BRect(LayoutArea().LeftTop(), size));
} }
@@ -200,7 +205,7 @@ status_t
BCardLayout::Archive(BMessage* into, bool deep) const BCardLayout::Archive(BMessage* into, bool deep) const
{ {
BArchiver archiver(into); BArchiver archiver(into);
status_t err = BLayout::Archive(into, deep); status_t err = BAbstractLayout::Archive(into, deep);
if (err == B_OK && deep) if (err == B_OK && deep)
err = into->AddInt32(kVisibleItemField, IndexOfItem(fVisibleItem)); err = into->AddInt32(kVisibleItemField, IndexOfItem(fVisibleItem));
@@ -292,7 +297,5 @@ BCardLayout::_ValidateMinMax()
fPreferred.height = min_c(fPreferred.height, fMax.height); fPreferred.height = min_c(fPreferred.height, fMax.height);
fMinMaxValid = true; fMinMaxValid = true;
ResetLayoutInvalidation();
if (BView* view = View())
view->ResetLayoutInvalidation();
} }
+2 -7
View File
@@ -45,7 +45,7 @@ BGridLayoutBuilder::GridLayout() const
BView* BView*
BGridLayoutBuilder::View() const BGridLayoutBuilder::View() const
{ {
return fLayout->View(); return fLayout->Owner();
} }
// GetGridLayout // GetGridLayout
@@ -60,7 +60,7 @@ BGridLayoutBuilder::GetGridLayout(BGridLayout** _layout)
BGridLayoutBuilder& BGridLayoutBuilder&
BGridLayoutBuilder::GetView(BView** _view) BGridLayoutBuilder::GetView(BView** _view)
{ {
*_view = fLayout->View(); *_view = fLayout->Owner();
return *this; return *this;
} }
@@ -112,8 +112,3 @@ BGridLayoutBuilder::operator BGridLayout*()
return fLayout; return fLayout;
} }
// cast operator BView*
BGridLayoutBuilder::operator BView*()
{
return fLayout->View();
}
+2 -9
View File
@@ -28,7 +28,6 @@ BGroupLayoutBuilder::BGroupLayoutBuilder(BGroupLayout* layout)
_PushLayout(fRootLayout); _PushLayout(fRootLayout);
} }
// constructor // constructor
BGroupLayoutBuilder::BGroupLayoutBuilder(BGroupView* view) BGroupLayoutBuilder::BGroupLayoutBuilder(BGroupView* view)
: fRootLayout(view->GroupLayout()) : fRootLayout(view->GroupLayout())
@@ -64,7 +63,7 @@ BGroupLayoutBuilder::GetTopLayout(BGroupLayout** _layout)
BView* BView*
BGroupLayoutBuilder::TopView() const BGroupLayoutBuilder::TopView() const
{ {
return TopLayout()->View(); return TopLayout()->Owner();
} }
// GetTopView // GetTopView
@@ -72,7 +71,7 @@ BGroupLayoutBuilder&
BGroupLayoutBuilder::GetTopView(BView** _view) BGroupLayoutBuilder::GetTopView(BView** _view)
{ {
if (BGroupLayout* layout = TopLayout()) if (BGroupLayout* layout = TopLayout())
*_view = layout->View(); *_view = layout->Owner();
else else
*_view = NULL; *_view = NULL;
@@ -181,12 +180,6 @@ BGroupLayoutBuilder::operator BGroupLayout*()
return fRootLayout; return fRootLayout;
} }
// cast operator BView*
BGroupLayoutBuilder::operator BView*()
{
return fRootLayout->View();
}
// _PushLayout // _PushLayout
bool bool
BGroupLayoutBuilder::_PushLayout(BGroupLayout* layout) BGroupLayoutBuilder::_PushLayout(BGroupLayout* layout)
+1
View File
@@ -31,6 +31,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) textview_support ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) layouter ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) layouter ] ;
MergeObject <libbe>interface_kit.o : MergeObject <libbe>interface_kit.o :
AbstractLayout.cpp
AbstractLayoutItem.cpp AbstractLayoutItem.cpp
AffineTransform.cpp AffineTransform.cpp
Alert.cpp Alert.cpp
+344 -27
View File
@@ -7,26 +7,50 @@
#include <Layout.h> #include <Layout.h>
#include <syslog.h> #include <algorithm>
#include <new> #include <new>
#include <syslog.h>
#include <LayoutContext.h>
#include <Message.h> #include <Message.h>
#include <View.h> #include <View.h>
#include <ViewPrivate.h>
#include "ViewLayoutItem.h" #include "ViewLayoutItem.h"
using std::nothrow; using std::nothrow;
using std::swap;
namespace { namespace {
// flags for our state
const uint32 B_LAYOUT_INVALID = 0x80000000UL; // needs layout
const uint32 B_LAYOUT_CACHE_INVALID = 0x40000000UL; // needs recalculation
const uint32 B_LAYOUT_REQUIRED = 0x20000000UL; // needs layout
const uint32 B_LAYOUT_IN_PROGRESS = 0x10000000UL;
const uint32 B_LAYOUT_ALL_CLEAR = 0UL;
// handy masks to check various states
const uint32 B_LAYOUT_INVALIDATION_ILLEGAL
= B_LAYOUT_CACHE_INVALID | B_LAYOUT_IN_PROGRESS;
const uint32 B_LAYOUT_NECESSARY
= B_LAYOUT_INVALID | B_LAYOUT_REQUIRED | B_LAYOUT_CACHE_INVALID;
const uint32 B_RELAYOUT_NOT_OK
= B_LAYOUT_INVALID | B_LAYOUT_IN_PROGRESS;
const char* const kLayoutItemField = "BLayout:items"; const char* const kLayoutItemField = "BLayout:items";
} }
BLayout::BLayout() BLayout::BLayout()
: :
fView(NULL), fState(B_LAYOUT_ALL_CLEAR),
fAncestorsVisible(true),
fInvalidationDisabled(0),
fContext(NULL),
fOwner(NULL),
fTarget(NULL),
fItems(20) fItems(20)
{ {
} }
@@ -34,8 +58,13 @@ BLayout::BLayout()
BLayout::BLayout(BMessage* from) BLayout::BLayout(BMessage* from)
: :
BArchivable(BUnarchiver::PrepareArchive(from)), BLayoutItem(BUnarchiver::PrepareArchive(from)),
fView(NULL), fState(B_LAYOUT_ALL_CLEAR),
fAncestorsVisible(true),
fInvalidationDisabled(0),
fContext(NULL),
fOwner(NULL),
fTarget(NULL),
fItems(20) fItems(20)
{ {
BUnarchiver unarchiver(from); BUnarchiver unarchiver(from);
@@ -48,15 +77,36 @@ BLayout::BLayout(BMessage* from)
BLayout::~BLayout() BLayout::~BLayout()
{ {
// this deletes all items // in case we have a view, but have been added to a layout as a BLayoutItem
SetView(NULL); // we will get deleted before our view, so we should tell it that we're
// going, so that we aren't double-freed.
if (fOwner && this == fOwner->GetLayout())
fOwner->_LayoutLeft(this);
// removes and deletes all items
if (fTarget)
SetTarget(NULL);
} }
BView* BView*
BLayout::View() const BLayout::Owner() const
{ {
return fView; return fOwner;
}
BView*
BLayout::TargetView() const
{
return fTarget;
}
BView*
BLayout::View()
{
return fOwner;
} }
@@ -70,11 +120,15 @@ BLayout::AddView(BView* child)
BLayoutItem* BLayoutItem*
BLayout::AddView(int32 index, BView* child) BLayout::AddView(int32 index, BView* child)
{ {
if (BViewLayoutItem* item = new(nothrow) BViewLayoutItem(child)) { BLayoutItem* item = child->GetLayout();
if (AddItem(index, item)) if (!item)
return item; item = new(nothrow) BViewLayoutItem(child);
if (item && AddItem(index, item))
return item;
if (!child->GetLayout())
delete item; delete item;
}
return NULL; return NULL;
} }
@@ -89,15 +143,15 @@ BLayout::AddItem(BLayoutItem* item)
bool bool
BLayout::AddItem(int32 index, BLayoutItem* item) BLayout::AddItem(int32 index, BLayoutItem* item)
{ {
if (!fView || !item || fItems.HasItem(item)) if (!fTarget || !item || fItems.HasItem(item))
return false; 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 // view
bool addedView = false; bool addedView = false;
BView* view = item->View(); BView* view = item->View();
if (view && view->fParent != fView if (view && view->fParent != fTarget
&& !(addedView = fView->_AddChild(view, NULL))) && !(addedView = fTarget->_AddChild(view, NULL)))
return false; return false;
// validate the index // validate the index
@@ -106,6 +160,8 @@ BLayout::AddItem(int32 index, BLayoutItem* item)
if (fItems.AddItem(item, index) && ItemAdded(item, index)) { if (fItems.AddItem(item, index) && ItemAdded(item, index)) {
item->SetLayout(this); item->SetLayout(this);
if (!fAncestorsVisible)
item->AncestorVisibilityChanged(fAncestorsVisible);
InvalidateLayout(); InvalidateLayout();
return true; return true;
} else { } else {
@@ -160,11 +216,11 @@ BLayout::RemoveItem(int32 index)
// if the item refers to a BView, we make sure, it is removed from the // if the item refers to a BView, we make sure, it is removed from the
// parent view // parent view
BView* view = item->View(); BView* view = item->View();
if (view && view->fParent == fView) if (view && view->fParent == fTarget)
view->_RemoveSelf(); view->_RemoveSelf();
item->SetLayout(NULL);
ItemRemoved(item, index); ItemRemoved(item, index);
item->SetLayout(NULL);
InvalidateLayout(); InvalidateLayout();
return item; return item;
@@ -206,11 +262,150 @@ BLayout::IndexOfView(BView* child) const
} }
void bool
BLayout::InvalidateLayout() BLayout::AncestorsVisible()
{ {
if (fView) return fAncestorsVisible;
fView->InvalidateLayout(); }
void
BLayout::InvalidateLayout(bool children)
{
// printf("BLayout(%p)::InvalidateLayout(%i) : state %x, disabled %li\n",
// this, children, (unsigned int)fState, fInvalidationDisabled);
if (!InvalidationLegal())
return;
fState |= B_LAYOUT_NECESSARY;
if (children) {
for (int32 i = CountItems() - 1; i >= 0; i--)
ItemAt(i)->InvalidateLayout(children);
}
if (fOwner && BView::Private(fOwner).MinMaxValid())
fOwner->InvalidateLayout(children);
if (BLayout* nestedIn = Layout()) {
if (nestedIn->InvalidationLegal())
nestedIn->InvalidateLayout();
} else if (fOwner) {
// If we weren't added as a BLayoutItem, we still have to invalidate
// whatever layout our owner is in.
BView* ownerParent = fOwner->fParent;
if (ownerParent) {
BLayout* layout = ownerParent->GetLayout();
if (layout && layout->fNestedLayouts.CountItems() > 0)
layout->InvalidateLayoutsForView(fOwner);
else if (BView::Private(ownerParent).MinMaxValid())
ownerParent->InvalidateLayout(false);
}
}
}
void
BLayout::RequireLayout()
{
fState |= B_LAYOUT_REQUIRED;
}
bool
BLayout::IsValid()
{
return (fState & B_LAYOUT_INVALID) == 0;
}
void
BLayout::DisableLayoutInvalidation()
{
fInvalidationDisabled++;
}
void
BLayout::EnableLayoutInvalidation()
{
if (fInvalidationDisabled > 0)
fInvalidationDisabled--;
}
void
BLayout::LayoutItems(bool force)
{
if ((fState & B_LAYOUT_NECESSARY) == 0 && !force)
return;
if (Layout() && (Layout()->fState & B_LAYOUT_IN_PROGRESS) != 0)
return; // wait for parent layout to lay us out.
if (fTarget && fTarget->LayoutContext())
return;
BLayoutContext context;
_LayoutWithinContext(force, &context);
}
void
BLayout::Relayout(bool immediate)
{
if ((fState & B_RELAYOUT_NOT_OK) == 0 || immediate) {
fState |= B_LAYOUT_REQUIRED;
LayoutItems(false);
}
}
void
BLayout::_LayoutWithinContext(bool force, BLayoutContext* context)
{
// printf("BLayout(%p)::_LayoutWithinContext(%i, %p), state %x, fContext %p\n",
// this, force, context, (unsigned int)fState, fContext);
if ((fState & B_LAYOUT_NECESSARY) == 0 && !force)
return;
BLayoutContext* oldContext = fContext;
fContext = context;
if (fOwner && BView::Private(fOwner).WillLayout()) {
// in this case, let our owner decide whether or not to have us
// do our layout, if they do, we won't end up here again.
fOwner->_Layout(force, context);
} else {
fState |= B_LAYOUT_IN_PROGRESS;
DerivedLayoutItems();
// we must ensure that all items are laid out, layouts with a view will
// have their layout process triggered by their view, but nested
// view-less layouts must have their layout triggered here (if it hasn't
// already been triggered).
int32 nestedLayoutCount = fNestedLayouts.CountItems();
for (int32 i = 0; i < nestedLayoutCount; i++) {
BLayout* layout = (BLayout*)fNestedLayouts.ItemAt(i);
if ((layout->fState & B_LAYOUT_NECESSARY) != 0)
layout->_LayoutWithinContext(force, context);
}
fState = B_LAYOUT_ALL_CLEAR;
}
fContext = oldContext;
}
BRect
BLayout::LayoutArea()
{
BRect area(Frame());
if (fOwner)
area.OffsetTo(B_ORIGIN);
return area;
} }
@@ -218,7 +413,7 @@ status_t
BLayout::Archive(BMessage* into, bool deep) const BLayout::Archive(BMessage* into, bool deep) const
{ {
BArchiver archiver(into); BArchiver archiver(into);
status_t err = BArchivable::Archive(into, deep); status_t err = BLayoutItem::Archive(into, deep);
if (deep) { if (deep) {
int32 count = CountItems(); int32 count = CountItems();
@@ -242,7 +437,7 @@ status_t
BLayout::AllUnarchived(const BMessage* from) BLayout::AllUnarchived(const BMessage* from)
{ {
BUnarchiver unarchiver(from); BUnarchiver unarchiver(from);
status_t err = BArchivable::AllUnarchived(from); status_t err = BLayoutItem::AllUnarchived(from);
if (err != B_OK) if (err != B_OK)
return err; return err;
@@ -304,16 +499,138 @@ BLayout::ItemRemoved(BLayoutItem* item, int32 fromIndex)
void void
BLayout::SetView(BView* view) BLayout::OwnerChanged(BView* was)
{ {
if (view != fView) { }
fView = NULL;
void
BLayout::AttachedToLayout()
{
if (!fOwner) {
Layout()->fNestedLayouts.AddItem(this);
SetTarget(Layout()->TargetView());
}
}
void
BLayout::DetachedFromLayout(BLayout* from)
{
if (!fOwner) {
from->fNestedLayouts.RemoveItem(this);
SetTarget(NULL);
}
}
void
BLayout::AncestorVisibilityChanged(bool shown)
{
if (fAncestorsVisible == shown)
return;
fAncestorsVisible = shown;
VisibilityChanged(shown);
}
void
BLayout::VisibilityChanged(bool show)
{
if (fOwner)
return;
for (int32 i = CountItems() - 1; i >= 0; i--)
ItemAt(i)->AncestorVisibilityChanged(show);
}
void
BLayout::ResetLayoutInvalidation()
{
fState &= ~B_LAYOUT_CACHE_INVALID;
}
BLayoutContext*
BLayout::LayoutContext()
{
return fContext;
}
bool
BLayout::RemoveViewRecursive(BView* view)
{
bool removed = RemoveView(view);
for (int32 i = fNestedLayouts.CountItems() - 1; i >= 0; i--) {
BLayout* nested = (BLayout*)fNestedLayouts.ItemAt(i);
removed |= nested->RemoveViewRecursive(view);
}
return removed;
}
bool
BLayout::InvalidateLayoutsForView(BView* view)
{
bool found = false;
for (int32 i = fNestedLayouts.CountItems() - 1; i >= 0; i--) {
BLayout* layout = (BLayout*)fNestedLayouts.ItemAt(i);
found |= layout->InvalidateLayoutsForView(view);
}
if (found)
return found;
if (!InvalidationLegal())
return false;
for (int32 i = CountItems() - 1; i >= 0; i--) {
if (ItemAt(i)->View() == view) {
InvalidateLayout();
return true;
}
}
return found;
}
bool
BLayout::InvalidationLegal()
{
return fInvalidationDisabled <= 0
&& (fState & B_LAYOUT_INVALIDATION_ILLEGAL) == 0;
}
void
BLayout::SetOwner(BView* owner)
{
if (fOwner == owner)
return;
SetTarget(owner);
swap(fOwner, owner);
OwnerChanged(owner);
// call hook
}
void
BLayout::SetTarget(BView* target)
{
if (fTarget != target) {
fTarget = NULL;
// only remove items, not views
// remove and delete all items // remove and delete all items
for (int32 i = CountItems() - 1; i >= 0; i--) for (int32 i = CountItems() - 1; i >= 0; i--)
delete RemoveItem(i); delete RemoveItem(i);
fView = view; fTarget = target;
InvalidateLayout(); InvalidateLayout();
} }
+49 -3
View File
@@ -8,6 +8,9 @@
#include <Layout.h> #include <Layout.h>
#include <LayoutUtils.h> #include <LayoutUtils.h>
#include <View.h>
#include <algorithm>
BLayoutItem::BLayoutItem() BLayoutItem::BLayoutItem()
@@ -30,6 +33,8 @@ BLayoutItem::BLayoutItem(BMessage* from)
BLayoutItem::~BLayoutItem() BLayoutItem::~BLayoutItem()
{ {
if (fLayout)
fLayout->RemoveItem(this);
} }
@@ -64,10 +69,21 @@ BLayoutItem::View()
void void
BLayoutItem::InvalidateLayout() BLayoutItem::InvalidateLayout(bool children)
{ {
if (fLayout) if (fLayout)
fLayout->InvalidateLayout(); fLayout->InvalidateLayout(children);
}
void
BLayoutItem::Relayout(bool immediate)
{
BView* view = View();
if (view && !immediate)
view->Relayout();
else if (view && immediate)
view->Layout(false);
} }
@@ -144,5 +160,35 @@ BLayoutItem::AllUnarchived(const BMessage* from)
void void
BLayoutItem::SetLayout(BLayout* layout) BLayoutItem::SetLayout(BLayout* layout)
{ {
fLayout = layout; if (layout == fLayout)
return;
std::swap(fLayout, layout);
if (layout)
DetachedFromLayout(layout);
if (fLayout)
AttachedToLayout();
} }
void
BLayoutItem::AttachedToLayout()
{
// hook method
}
void
BLayoutItem::DetachedFromLayout(BLayout* oldLayout)
{
// hook method
}
void
BLayoutItem::AncestorVisibilityChanged(bool shown)
{
// hook method
}
+26 -27
View File
@@ -196,7 +196,7 @@ BSplitLayout::BSplitLayout(enum orientation orientation,
BSplitLayout::BSplitLayout(BMessage* from) BSplitLayout::BSplitLayout(BMessage* from)
: :
BLayout(BUnarchiver::PrepareArchive(from)), BAbstractLayout(BUnarchiver::PrepareArchive(from)),
fSplitterItems(), fSplitterItems(),
fVisibleItems(), fVisibleItems(),
fMin(), fMin(),
@@ -340,14 +340,14 @@ BSplitLayout::SetSplitterSize(float size)
BLayoutItem* BLayoutItem*
BSplitLayout::AddView(BView* child) BSplitLayout::AddView(BView* child)
{ {
return BLayout::AddView(child); return BAbstractLayout::AddView(child);
} }
BLayoutItem* BLayoutItem*
BSplitLayout::AddView(int32 index, BView* child) BSplitLayout::AddView(int32 index, BView* child)
{ {
return BLayout::AddView(index, child); return BAbstractLayout::AddView(index, child);
} }
@@ -372,14 +372,14 @@ BSplitLayout::AddView(int32 index, BView* child, float weight)
bool bool
BSplitLayout::AddItem(BLayoutItem* item) BSplitLayout::AddItem(BLayoutItem* item)
{ {
return BLayout::AddItem(item); return BAbstractLayout::AddItem(item);
} }
bool bool
BSplitLayout::AddItem(int32 index, BLayoutItem* item) BSplitLayout::AddItem(int32 index, BLayoutItem* item)
{ {
return BLayout::AddItem(index, item); return BAbstractLayout::AddItem(index, item);
} }
@@ -480,7 +480,7 @@ BSplitLayout::SetCollapsible(int32 first, int32 last, bool collapsible)
BSize BSize
BSplitLayout::MinSize() BSplitLayout::BaseMinSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
@@ -489,7 +489,7 @@ BSplitLayout::MinSize()
BSize BSize
BSplitLayout::MaxSize() BSplitLayout::BaseMaxSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
@@ -498,7 +498,7 @@ BSplitLayout::MaxSize()
BSize BSize
BSplitLayout::PreferredSize() BSplitLayout::BasePreferredSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
@@ -507,9 +507,9 @@ BSplitLayout::PreferredSize()
BAlignment BAlignment
BSplitLayout::Alignment() BSplitLayout::BaseAlignment()
{ {
return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); return BAbstractLayout::BaseAlignment();
} }
@@ -536,19 +536,19 @@ BSplitLayout::GetHeightForWidth(float width, float* min, float* max,
void void
BSplitLayout::InvalidateLayout() BSplitLayout::InvalidateLayout(bool children)
{ {
_InvalidateLayout(true); _InvalidateLayout(true, children);
} }
void void
BSplitLayout::LayoutView() BSplitLayout::DerivedLayoutItems()
{ {
_ValidateMinMax(); _ValidateMinMax();
// layout the elements // layout the elements
BSize size = _SubtractInsets(View()->Bounds().Size()); BSize size = _SubtractInsets(LayoutArea().Size());
fHorizontalLayouter->Layout(fHorizontalLayoutInfo, size.width); fHorizontalLayouter->Layout(fHorizontalLayoutInfo, size.width);
Layouter* verticalLayouter; Layouter* verticalLayouter;
@@ -647,7 +647,7 @@ BSplitLayout::StartDraggingSplitter(BPoint point)
return false; return false;
// Things shouldn't be draggable, if we have a >= max layout. // Things shouldn't be draggable, if we have a >= max layout.
BSize size = _SubtractInsets(View()->Frame().Size()); BSize size = _SubtractInsets(LayoutArea().Size());
if ((fOrientation == B_HORIZONTAL && size.width >= fMax.width) if ((fOrientation == B_HORIZONTAL && size.width >= fMax.width)
|| (fOrientation == B_VERTICAL && size.height >= fMax.height)) { || (fOrientation == B_VERTICAL && size.height >= fMax.height)) {
return false; return false;
@@ -655,7 +655,7 @@ BSplitLayout::StartDraggingSplitter(BPoint point)
int32 index = -1; int32 index = -1;
if (_SplitterItemAt(point, &index) != NULL) { if (_SplitterItemAt(point, &index) != NULL) {
fDraggingStartPoint = View()->ConvertToScreen(point); fDraggingStartPoint = Owner()->ConvertToScreen(point);
fDraggingStartValue = _SplitterValue(index); fDraggingStartValue = _SplitterValue(index);
fDraggingCurrentValue = fDraggingStartValue; fDraggingCurrentValue = fDraggingStartValue;
fDraggingSplitterIndex = index; fDraggingSplitterIndex = index;
@@ -673,7 +673,7 @@ BSplitLayout::DragSplitter(BPoint point)
if (fDraggingSplitterIndex < 0) if (fDraggingSplitterIndex < 0)
return false; return false;
point = View()->ConvertToScreen(point); point = Owner()->ConvertToScreen(point);
int32 valueDiff; int32 valueDiff;
if (fOrientation == B_HORIZONTAL) if (fOrientation == B_HORIZONTAL)
@@ -712,7 +712,7 @@ status_t
BSplitLayout::Archive(BMessage* into, bool deep) const BSplitLayout::Archive(BMessage* into, bool deep) const
{ {
BArchiver archiver(into); BArchiver archiver(into);
status_t err = BLayout::Archive(into, deep); status_t err = BAbstractLayout::Archive(into, deep);
if (err == B_OK) if (err == B_OK)
err = into->AddBool(kIsVerticalField, fOrientation == B_VERTICAL); err = into->AddBool(kIsVerticalField, fOrientation == B_VERTICAL);
@@ -811,10 +811,10 @@ BSplitLayout::ItemRemoved(BLayoutItem* item, int32 atIndex)
void void
BSplitLayout::_InvalidateLayout(bool invalidateView) BSplitLayout::_InvalidateLayout(bool invalidateView, bool children)
{ {
if (invalidateView) if (invalidateView)
BLayout::InvalidateLayout(); BAbstractLayout::InvalidateLayout(children);
delete fHorizontalLayouter; delete fHorizontalLayouter;
delete fVerticalLayouter; delete fVerticalLayouter;
@@ -929,7 +929,7 @@ BSplitLayout::_LayoutItem(BLayoutItem* item, BRect frame, bool visible)
info->max = item->MaxSize(); info->max = item->MaxSize();
if (item->HasHeightForWidth()) { if (item->HasHeightForWidth()) {
BSize size = _SubtractInsets(View()->Frame().Size()); BSize size = _SubtractInsets(LayoutArea().Size());
float minHeight, maxHeight; float minHeight, maxHeight;
item->GetHeightForWidth(size.width, &minHeight, &maxHeight, NULL); item->GetHeightForWidth(size.width, &minHeight, &maxHeight, NULL);
info->min.height = max_c(info->min.height, minHeight); info->min.height = max_c(info->min.height, minHeight);
@@ -958,9 +958,9 @@ BSplitLayout::_LayoutItem(BLayoutItem* item, ItemLayoutInfo* info)
item->AlignInFrame(info->layoutFrame); item->AlignInFrame(info->layoutFrame);
// if the item became visible, we need to update its internal layout // if the item became visible, we need to update its internal layout
if (visibilityChanged) { if (visibilityChanged && fOrientation != B_HORIZONTAL
if (BView* itemView = item->View()) || !HasHeightForWidth()) {
itemView->Layout(false); item->Relayout(true);
} }
} }
@@ -1216,7 +1216,7 @@ BSplitLayout::_UpdateSplitterWeights()
} }
// Just updating the splitter weights is fine in principle. The next // Just updating the splitter weights is fine in principle. The next
// LayoutView() will use the correct values. But, if our orientation is // LayoutItems() will use the correct values. But, if our orientation is
// vertical, the cached height for width info needs to be flushed, or the // vertical, the cached height for width info needs to be flushed, or the
// obsolete cached values will be used. // obsolete cached values will be used.
if (fOrientation == B_VERTICAL) if (fOrientation == B_VERTICAL)
@@ -1293,8 +1293,7 @@ BSplitLayout::_ValidateMinMax()
if (fHeightForWidthItems.IsEmpty()) if (fHeightForWidthItems.IsEmpty())
fVerticalLayoutInfo = fVerticalLayouter->CreateLayoutInfo(); fVerticalLayoutInfo = fVerticalLayouter->CreateLayoutInfo();
if (BView* view = View()) ResetLayoutInvalidation();
view->ResetLayoutInvalidation();
} }
+10 -9
View File
@@ -6,7 +6,7 @@
#define _SPLIT_LAYOUT_H #define _SPLIT_LAYOUT_H
#include <Layout.h> #include <AbstractLayout.h>
#include <Point.h> #include <Point.h>
@@ -21,7 +21,7 @@ using BPrivate::Layout::Layouter;
using BPrivate::Layout::LayoutInfo; using BPrivate::Layout::LayoutInfo;
class BSplitLayout : public BLayout { class BSplitLayout : public BAbstractLayout {
public: public:
BSplitLayout(enum orientation orientation, BSplitLayout(enum orientation orientation,
float spacing = 0.0f); float spacing = 0.0f);
@@ -66,18 +66,18 @@ public:
void SetCollapsible(int32 first, int32 last, void SetCollapsible(int32 first, int32 last,
bool collapsible); bool collapsible);
virtual BSize MinSize(); virtual BSize BaseMinSize();
virtual BSize MaxSize(); virtual BSize BaseMaxSize();
virtual BSize PreferredSize(); virtual BSize BasePreferredSize();
virtual BAlignment Alignment(); virtual BAlignment BaseAlignment();
virtual bool HasHeightForWidth(); virtual bool HasHeightForWidth();
virtual void GetHeightForWidth(float width, float* min, virtual void GetHeightForWidth(float width, float* min,
float* max, float* preferred); float* max, float* preferred);
virtual void InvalidateLayout(); virtual void InvalidateLayout(bool children = false);
virtual void LayoutView(); virtual void DerivedLayoutItems();
// interface for BSplitView // interface for BSplitView
BRect SplitterItemFrame(int32 index) const; BRect SplitterItemFrame(int32 index) const;
@@ -106,7 +106,8 @@ private:
class ValueRange; class ValueRange;
class SplitterItem; class SplitterItem;
void _InvalidateLayout(bool invalidateView); void _InvalidateLayout(bool invalidateView,
bool children = false);
void _InvalidateCachedHeightForWidth(); void _InvalidateCachedHeightForWidth();
SplitterItem* _SplitterItemAt(const BPoint& point, SplitterItem* _SplitterItemAt(const BPoint& point,
+70 -72
View File
@@ -258,7 +258,7 @@ BTwoDimensionalLayout::BTwoDimensionalLayout()
BTwoDimensionalLayout::BTwoDimensionalLayout(BMessage* from) BTwoDimensionalLayout::BTwoDimensionalLayout(BMessage* from)
: :
BLayout(from), BAbstractLayout(from),
fLeftInset(0), fLeftInset(0),
fRightInset(0), fRightInset(0),
fTopInset(0), fTopInset(0),
@@ -324,7 +324,7 @@ BTwoDimensionalLayout::AlignLayoutWith(BTwoDimensionalLayout* other,
BSize BSize
BTwoDimensionalLayout::MinSize() BTwoDimensionalLayout::BaseMinSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
return AddInsets(fLocalLayouter->MinSize()); return AddInsets(fLocalLayouter->MinSize());
@@ -332,7 +332,7 @@ BTwoDimensionalLayout::MinSize()
BSize BSize
BTwoDimensionalLayout::MaxSize() BTwoDimensionalLayout::BaseMaxSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
return AddInsets(fLocalLayouter->MaxSize()); return AddInsets(fLocalLayouter->MaxSize());
@@ -340,7 +340,7 @@ BTwoDimensionalLayout::MaxSize()
BSize BSize
BTwoDimensionalLayout::PreferredSize() BTwoDimensionalLayout::BasePreferredSize()
{ {
_ValidateMinMax(); _ValidateMinMax();
return AddInsets(fLocalLayouter->PreferredSize()); return AddInsets(fLocalLayouter->PreferredSize());
@@ -348,9 +348,9 @@ BTwoDimensionalLayout::PreferredSize()
BAlignment BAlignment
BTwoDimensionalLayout::Alignment() BTwoDimensionalLayout::BaseAlignment()
{ {
return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); return BAbstractLayout::BaseAlignment();
} }
@@ -377,64 +377,17 @@ BTwoDimensionalLayout::GetHeightForWidth(float width, float* min, float* max,
void void
BTwoDimensionalLayout::InvalidateLayout() BTwoDimensionalLayout::SetFrame(BRect frame)
{ {
BLayout::InvalidateLayout(); BAbstractLayout::SetFrame(frame);
fLocalLayouter->InvalidateLayout();
} }
void void
BTwoDimensionalLayout::LayoutView() BTwoDimensionalLayout::InvalidateLayout(bool children)
{ {
_ValidateMinMax(); BLayout::InvalidateLayout(children);
fLocalLayouter->InvalidateLayout();
// layout the horizontal/vertical elements
BSize size = SubtractInsets(View()->Frame().Size());
#ifdef DEBUG_LAYOUT
printf("BTwoDimensionalLayout::LayoutView(%p): size: (%.1f, %.1f)\n",
View(), size.width, size.height);
#endif
fLocalLayouter->Layout(size);
// layout the items
int itemCount = CountItems();
for (int i = 0; i < itemCount; i++) {
BLayoutItem* item = ItemAt(i);
if (item->IsVisible()) {
Dimensions itemDimensions;
GetItemDimensions(item, &itemDimensions);
BRect frame = fLocalLayouter->ItemFrame(itemDimensions);
frame.left += fLeftInset;
frame.top += fTopInset;
frame.right += fLeftInset;
frame.bottom += fTopInset;
{
#ifdef DEBUG_LAYOUT
printf(" frame for item %2d (view: %p): ", i, item->View());
frame.PrintToStream();
#endif
//BSize min(item->MinSize());
//BSize max(item->MaxSize());
//printf(" min: (%.1f, %.1f), max: (%.1f, %.1f)\n", min.width, min.height,
// max.width, max.height);
//if (item->HasHeightForWidth()) {
//float minHeight, maxHeight, preferredHeight;
//item->GetHeightForWidth(frame.Width(), &minHeight, &maxHeight,
// &preferredHeight);
//printf(" hfw: min: %.1f, max: %.1f, pref: %.1f\n", minHeight, maxHeight,
// preferredHeight);
//}
}
item->AlignInFrame(frame);
}
//else
//printf(" item %2d not visible", i);
}
} }
@@ -442,7 +395,7 @@ status_t
BTwoDimensionalLayout::Archive(BMessage* into, bool deep) const BTwoDimensionalLayout::Archive(BMessage* into, bool deep) const
{ {
BArchiver archiver(into); BArchiver archiver(into);
status_t err = BLayout::Archive(into, deep); status_t err = BAbstractLayout::Archive(into, deep);
if (err == B_OK) { if (err == B_OK) {
BRect insets(fLeftInset, fTopInset, fRightInset, fBottomInset); BRect insets(fLeftInset, fTopInset, fRightInset, fBottomInset);
@@ -487,6 +440,61 @@ BTwoDimensionalLayout::AllUnarchived(const BMessage* from)
} }
void
BTwoDimensionalLayout::DerivedLayoutItems()
{
_ValidateMinMax();
// layout the horizontal/vertical elements
BSize size(SubtractInsets(LayoutArea().Size()));
#ifdef DEBUG_LAYOUT
printf("BTwoDimensionalLayout::DerivedLayoutItems(): view: %p"
" size: (%.1f, %.1f)\n", View(), size.Width(), size.Height());
#endif
fLocalLayouter->Layout(size);
// layout the items
BPoint itemOffset(LayoutArea().LeftTop());
int itemCount = CountItems();
for (int i = 0; i < itemCount; i++) {
BLayoutItem* item = ItemAt(i);
if (item->IsVisible()) {
Dimensions itemDimensions;
GetItemDimensions(item, &itemDimensions);
BRect frame = fLocalLayouter->ItemFrame(itemDimensions);
frame.left += fLeftInset;
frame.top += fTopInset;
frame.right += fLeftInset;
frame.bottom += fTopInset;
frame.OffsetBy(itemOffset);
{
#ifdef DEBUG_LAYOUT
printf(" frame for item %2d (view: %p): ", i, item->View());
frame.PrintToStream();
#endif
//BSize min(item->MinSize());
//BSize max(item->MaxSize());
//printf(" min: (%.1f, %.1f), max: (%.1f, %.1f)\n", min.width, min.height,
// max.width, max.height);
//if (item->HasHeightForWidth()) {
//float minHeight, maxHeight, preferredHeight;
//item->GetHeightForWidth(frame.Width(), &minHeight, &maxHeight,
// &preferredHeight);
//printf(" hfw: min: %.1f, max: %.1f, pref: %.1f\n", minHeight, maxHeight,
// preferredHeight);
//}
}
item->AlignInFrame(frame);
}
//else
//printf(" item %2d not visible", i);
}
}
BSize BSize
BTwoDimensionalLayout::AddInsets(BSize size) BTwoDimensionalLayout::AddInsets(BSize size)
{ {
@@ -547,17 +555,6 @@ void
BTwoDimensionalLayout::_ValidateMinMax() BTwoDimensionalLayout::_ValidateMinMax()
{ {
fLocalLayouter->ValidateMinMax(); fLocalLayouter->ValidateMinMax();
if (BView* view = View())
view->ResetLayoutInvalidation();
}
BLayoutContext*
BTwoDimensionalLayout::_CurrentLayoutContext()
{
BView* view = View();
return (view ? view->LayoutContext() : NULL);
} }
@@ -1060,7 +1057,7 @@ void
BTwoDimensionalLayout::LocalLayouter::Layout(BSize size) BTwoDimensionalLayout::LocalLayouter::Layout(BSize size)
{ {
DoHorizontalLayout(size.width); DoHorizontalLayout(size.width);
fVLayouter->Layout(size.height, this, fLayout->_CurrentLayoutContext()); fVLayouter->Layout(size.height, this, fLayout->LayoutContext());
} }
@@ -1092,13 +1089,14 @@ BTwoDimensionalLayout::LocalLayouter::ValidateMinMax()
fHLayouter->ValidateMinMax(); fHLayouter->ValidateMinMax();
fVLayouter->ValidateMinMax(); fVLayouter->ValidateMinMax();
fLayout->ResetLayoutInvalidation();
} }
void void
BTwoDimensionalLayout::LocalLayouter::DoHorizontalLayout(float width) BTwoDimensionalLayout::LocalLayouter::DoHorizontalLayout(float width)
{ {
BLayoutContext* context = fLayout->_CurrentLayoutContext(); BLayoutContext* context = fLayout->LayoutContext();
if (fHorizontalLayoutContext != context if (fHorizontalLayoutContext != context
|| width != fHorizontalLayoutWidth) { || width != fHorizontalLayoutWidth) {
_SetHorizontalLayoutContext(context, width); _SetHorizontalLayoutContext(context, width);
+82 -26
View File
@@ -648,7 +648,7 @@ BView::AllUnarchived(const BMessage* from)
err = unarchiver.FindObject(kLayoutField, layout); err = unarchiver.FindObject(kLayoutField, layout);
if (err == B_OK && layout) { if (err == B_OK && layout) {
fFlags |= B_SUPPORTS_LAYOUT; fFlags |= B_SUPPORTS_LAYOUT;
fLayoutData->fLayout->BLayout::SetView(this); fLayoutData->fLayout->SetOwner(this);
} }
} }
@@ -997,7 +997,7 @@ BView::Hide()
fShowLevel++; fShowLevel++;
if (fShowLevel == 1 && fParent) if (fShowLevel == 1 && fParent)
fParent->InvalidateLayout(); _InvalidateParentLayout();
} }
@@ -1012,7 +1012,7 @@ BView::Show()
} }
if (fShowLevel == 0 && fParent) if (fShowLevel == 0 && fParent)
fParent->InvalidateLayout(); _InvalidateParentLayout();
} }
@@ -4020,7 +4020,7 @@ bool
BView::RemoveSelf() BView::RemoveSelf()
{ {
if (fParent && fParent->fLayoutData->fLayout) if (fParent && fParent->fLayoutData->fLayout)
return fParent->fLayoutData->fLayout->RemoveView(this); return fParent->fLayoutData->fLayout->RemoveViewRecursive(this);
return _RemoveSelf(); return _RemoveSelf();
} }
@@ -4643,18 +4643,21 @@ BView::SetLayout(BLayout* layout)
if (layout == fLayoutData->fLayout) if (layout == fLayoutData->fLayout)
return; return;
if (layout && layout->Layout())
debugger("BView::SetLayout() failed, layout is already in use.");
fFlags |= B_SUPPORTS_LAYOUT; fFlags |= B_SUPPORTS_LAYOUT;
// unset and delete the old layout // unset and delete the old layout
if (fLayoutData->fLayout) { if (fLayoutData->fLayout) {
fLayoutData->fLayout->SetView(NULL); fLayoutData->fLayout->SetOwner(NULL);
delete fLayoutData->fLayout; delete fLayoutData->fLayout;
} }
fLayoutData->fLayout = layout; fLayoutData->fLayout = layout;
if (fLayoutData->fLayout) { if (fLayoutData->fLayout) {
fLayoutData->fLayout->SetView(this); fLayoutData->fLayout->SetOwner(this);
// add all children // add all children
int count = CountChildren(); int count = CountChildren();
@@ -4676,21 +4679,27 @@ BView::GetLayout() const
void void
BView::InvalidateLayout(bool descendants) BView::InvalidateLayout(bool descendants)
{ {
// printf("BView(%p)::InvalidateLayout(%i), valid: %i, inProgress: %i\n",
// this, descendants, fLayoutData->fLayoutValid,
// fLayoutData->fLayoutInProgress);
if (fLayoutData->fMinMaxValid && !fLayoutData->fLayoutInProgress if (fLayoutData->fMinMaxValid && !fLayoutData->fLayoutInProgress
&& fLayoutData->fLayoutInvalidationDisabled == 0) { && fLayoutData->fLayoutInvalidationDisabled == 0) {
if (fParent && fParent->fLayoutData->fMinMaxValid)
fParent->InvalidateLayout(false);
fLayoutData->fLayoutValid = false; fLayoutData->fLayoutValid = false;
fLayoutData->fMinMaxValid = false; fLayoutData->fMinMaxValid = false;
if (fLayoutData->fLayout)
fLayoutData->fLayout->InvalidateLayout();
if (descendants) { if (descendants) {
int count = CountChildren(); for (BView* child = fFirstChild;
for (int i = 0; i < count; i++) child; child = child->fNextSibling) {
ChildAt(i)->InvalidateLayout(descendants); child->InvalidateLayout(descendants);
}
}
if (fLayoutData->fLayout && fLayoutData->fLayout->InvalidationLegal())
fLayoutData->fLayout->InvalidateLayout(descendants);
else if (!fLayoutData->fLayout && fParent) {
_InvalidateParentLayout();
} }
if (fTopLevelView) { if (fTopLevelView) {
@@ -4724,15 +4733,12 @@ BView::IsLayoutValid() const
} }
/*! \brief Service call for BLayout derived classes reenabling /*! \brief Service call for BView derived classes reenabling
InvalidateLayout() notifications. InvalidateLayout() notifications.
BView::InvalidateLayout() invokes InvalidateLayout() on its layout the first
time, but suppresses further calls until Layout()/Relayout() has been
invoked. This method will reenable the notification for the next call of
BView::InvalidateLayout().
If the layout caches internal layout information and updates those BLayout & BView will avoid calling InvalidateLayout on views that have
information also in methods other than LayoutView(), it has to invoke this already been invalidated, but if the view caches internal layout information
which it updates in methds other than DoLayout(), it has to invoke this
method, when it has done so, since otherwise the information might become method, when it has done so, since otherwise the information might become
obsolete without the layout noticing. obsolete without the layout noticing.
*/ */
@@ -4763,6 +4769,8 @@ BView::Relayout()
{ {
if (fLayoutData->fLayoutValid && !fLayoutData->fLayoutInProgress) { if (fLayoutData->fLayoutValid && !fLayoutData->fLayoutInProgress) {
fLayoutData->fNeedsRelayout = true; fLayoutData->fNeedsRelayout = true;
if (fLayoutData->fLayout)
fLayoutData->fLayout->RequireLayout();
// Layout() is recursive, that is if the parent view is currently laid // Layout() is recursive, that is if the parent view is currently laid
// out, we don't call layout() on this view, but wait for the parent's // out, we don't call layout() on this view, but wait for the parent's
@@ -4777,7 +4785,7 @@ void
BView::DoLayout() BView::DoLayout()
{ {
if (fLayoutData->fLayout) if (fLayoutData->fLayout)
fLayoutData->fLayout->LayoutView(); fLayoutData->fLayout->_LayoutWithinContext(false, LayoutContext());
} }
@@ -4881,9 +4889,7 @@ BView::_Layout(bool force, BLayoutContext* context)
fLayoutData->fNeedsRelayout = false; fLayoutData->fNeedsRelayout = false;
// layout children // layout children
int32 childCount = CountChildren(); for(BView* child = fFirstChild; child; child = child->fNextSibling) {
for (int32 i = 0; i < childCount; i++) {
BView* child = ChildAt(i);
if (!child->IsHidden(child)) if (!child->IsHidden(child))
child->_Layout(force, context); child->_Layout(force, context);
} }
@@ -4897,6 +4903,34 @@ BView::_Layout(bool force, BLayoutContext* context)
} }
void
BView::_LayoutLeft(BLayout* deleted)
{
// If our layout is added to another layout (via BLayout::AddItem())
// then we share ownership of our layout. In the event that our layout gets
// deleted by the layout it has been added to, this method is called so
// that we don't double-delete our layout.
if (fLayoutData->fLayout == deleted)
fLayoutData->fLayout = NULL;
InvalidateLayout();
}
void
BView::_InvalidateParentLayout()
{
BLayout* layout = fLayoutData->fLayout;
BLayout* layoutParent = layout ? layout->Layout() : NULL;
if (layoutParent && layoutParent->InvalidationLegal()) {
layout->Layout()->InvalidateLayout();
} else if (fParent && fParent->fLayoutData->fLayout) {
fParent->fLayoutData->fLayout->InvalidateLayoutsForView(this);
} else if (fParent) {
fParent->InvalidateLayout();
}
}
// #pragma mark - Private Functions // #pragma mark - Private Functions
@@ -5920,3 +5954,25 @@ BView::_PrintTree()
} }
} }
} }
// #pragma mark -
bool
BView::Private::MinMaxValid()
{
return fView->fLayoutData->fMinMaxValid;
}
bool
BView::Private::WillLayout()
{
BView::LayoutData* data = fView->fLayoutData;
if (data->fLayoutInProgress)
return false;
if (data->fNeedsRelayout || !data->fLayoutValid || !data->fMinMaxValid)
return true;
return false;
}
+34 -5
View File
@@ -11,6 +11,7 @@
#include <Layout.h> #include <Layout.h>
#include <View.h> #include <View.h>
#include <ViewPrivate.h>
namespace { namespace {
@@ -20,7 +21,8 @@ namespace {
BViewLayoutItem::BViewLayoutItem(BView* view) BViewLayoutItem::BViewLayoutItem(BView* view)
: :
fView(view) fView(view),
fAncestorsVisible(true)
{ {
} }
@@ -28,7 +30,8 @@ BViewLayoutItem::BViewLayoutItem(BView* view)
BViewLayoutItem::BViewLayoutItem(BMessage* from) BViewLayoutItem::BViewLayoutItem(BMessage* from)
: :
BLayoutItem(BUnarchiver::PrepareArchive(from)), BLayoutItem(BUnarchiver::PrepareArchive(from)),
fView(NULL) fView(NULL),
fAncestorsVisible(true)
{ {
BUnarchiver unarchiver(from); BUnarchiver unarchiver(from);
unarchiver.Finish(unarchiver.FindObject<BView>(kViewField, 0, unarchiver.Finish(unarchiver.FindObject<BView>(kViewField, 0,
@@ -100,7 +103,8 @@ BViewLayoutItem::SetExplicitAlignment(BAlignment alignment)
bool bool
BViewLayoutItem::IsVisible() BViewLayoutItem::IsVisible()
{ {
return !fView->IsHidden(fView); int16 showLevel = BView::Private(fView).ShowLevel();
return showLevel - (fAncestorsVisible ? 0 : 1) <= 0;
} }
@@ -154,9 +158,19 @@ BViewLayoutItem::View()
void void
BViewLayoutItem::InvalidateLayout() BViewLayoutItem::InvalidateLayout(bool children)
{ {
fView->InvalidateLayout(); fView->InvalidateLayout(children);
}
void
BViewLayoutItem::Relayout(bool immediate)
{
if (immediate)
fView->Layout(false);
else
fView->Relayout();
} }
@@ -204,3 +218,18 @@ BViewLayoutItem::Instantiate(BMessage* from)
return new(std::nothrow) BViewLayoutItem(from); return new(std::nothrow) BViewLayoutItem(from);
return NULL; return NULL;
} }
void
BViewLayoutItem::AncestorVisibilityChanged(bool shown)
{
if (fAncestorsVisible == shown)
return;
fAncestorsVisible = shown;
if (shown)
fView->Show();
if (!shown)
fView->Hide();
}
+6 -1
View File
@@ -36,15 +36,20 @@ public:
virtual BView* View(); virtual BView* View();
virtual void InvalidateLayout(); virtual void InvalidateLayout(bool children = false);
virtual void Relayout(bool immediate = false);
virtual status_t Archive(BMessage* into, bool deep = true) const; virtual status_t Archive(BMessage* into, bool deep = true) const;
virtual status_t AllArchived(BMessage* into) const; virtual status_t AllArchived(BMessage* into) const;
virtual status_t AllUnarchived(const BMessage* from); virtual status_t AllUnarchived(const BMessage* from);
static BArchivable* Instantiate(BMessage* from); static BArchivable* Instantiate(BMessage* from);
protected:
virtual void AncestorVisibilityChanged(bool shown);
private: private:
BView* fView; BView* fView;
int32 fAncestorsVisible;
}; };
#endif // _VIEW_LAYOUT_ITEM_H #endif // _VIEW_LAYOUT_ITEM_H
+9
View File
@@ -543,6 +543,15 @@ BWindow::AddChild(BView* child, BView* before)
} }
void
BWindow::AddChild(BLayoutItem* child)
{
BAutolock locker(this);
if (locker.IsLocked())
fTopView->AddChild(child);
}
bool bool
BWindow::RemoveChild(BView* child) BWindow::RemoveChild(BView* child)
{ {
+27 -21
View File
@@ -20,7 +20,8 @@
* Creates new layout engine. * Creates new layout engine.
*/ */
BALMLayout::BALMLayout() BALMLayout::BALMLayout()
: BLayout(), :
BAbstractLayout(),
LinearSpec() LinearSpec()
{ {
fLayoutStyle = FIT_TO_SIZE; fLayoutStyle = FIT_TO_SIZE;
@@ -189,7 +190,7 @@ BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
{ {
InvalidateLayout(); InvalidateLayout();
if (content != NULL) if (content != NULL)
View()->AddChild(content); TargetView()->AddChild(content);
Area* area = new Area(this, left, top, right, bottom, content, minContentSize); Area* area = new Area(this, left, top, right, bottom, content, minContentSize);
fAreas->AddItem(area); fAreas->AddItem(area);
return area; return area;
@@ -211,7 +212,7 @@ BALMLayout::AddArea(Row* row, Column* column, BView* content,
{ {
InvalidateLayout(); InvalidateLayout();
if (content != NULL) if (content != NULL)
View()->AddChild(content); TargetView()->AddChild(content);
Area* area = new Area(this, row, column, content, minContentSize); Area* area = new Area(this, row, column, content, minContentSize);
fAreas->AddItem(area); fAreas->AddItem(area);
return area; return area;
@@ -234,7 +235,7 @@ BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
{ {
InvalidateLayout(); InvalidateLayout();
if (content != NULL) if (content != NULL)
View()->AddChild(content); TargetView()->AddChild(content);
Area* area = new Area(this, left, top, right, bottom, content, BSize(0, 0)); Area* area = new Area(this, left, top, right, bottom, content, BSize(0, 0));
area->SetDefaultBehavior(); area->SetDefaultBehavior();
area->SetAutoPreferredContentSize(false); area->SetAutoPreferredContentSize(false);
@@ -256,7 +257,7 @@ BALMLayout::AddArea(Row* row, Column* column, BView* content)
{ {
InvalidateLayout(); InvalidateLayout();
if (content != NULL) if (content != NULL)
View()->AddChild(content); TargetView()->AddChild(content);
Area* area = new Area(this, row, column, content, BSize(0, 0)); Area* area = new Area(this, row, column, content, BSize(0, 0));
area->SetDefaultBehavior(); area->SetDefaultBehavior();
area->SetAutoPreferredContentSize(false); area->SetAutoPreferredContentSize(false);
@@ -435,9 +436,10 @@ BALMLayout::RemoveItem(int32 index)
/** /**
* Sets and gets minimum size. * Gets minimum size.
*/ */
BSize BALMLayout::MinSize() { BSize
BALMLayout::BaseMinSize() {
if (fMinSize == Area::kUndefinedSize) if (fMinSize == Area::kUndefinedSize)
fMinSize = CalculateMinSize(); fMinSize = CalculateMinSize();
return fMinSize; return fMinSize;
@@ -445,10 +447,10 @@ BSize BALMLayout::MinSize() {
/** /**
* Sets and gets maximum size. * Gets maximum size.
*/ */
BSize BSize
BALMLayout::MaxSize() BALMLayout::BaseMaxSize()
{ {
if (fMaxSize == Area::kUndefinedSize) if (fMaxSize == Area::kUndefinedSize)
fMaxSize = CalculateMaxSize(); fMaxSize = CalculateMaxSize();
@@ -457,10 +459,10 @@ BALMLayout::MaxSize()
/** /**
* Sets and gets preferred size. * Gets preferred size.
*/ */
BSize BSize
BALMLayout::PreferredSize() BALMLayout::BasePreferredSize()
{ {
if (fPreferredSize == Area::kUndefinedSize) if (fPreferredSize == Area::kUndefinedSize)
fPreferredSize = CalculatePreferredSize(); fPreferredSize = CalculatePreferredSize();
@@ -472,7 +474,7 @@ BALMLayout::PreferredSize()
* Gets the alignment. * Gets the alignment.
*/ */
BAlignment BAlignment
BALMLayout::Alignment() BALMLayout::BaseAlignment()
{ {
BAlignment alignment; BAlignment alignment;
alignment.SetHorizontal(B_ALIGN_HORIZONTAL_CENTER); alignment.SetHorizontal(B_ALIGN_HORIZONTAL_CENTER);
@@ -492,7 +494,7 @@ BALMLayout::HasHeightForWidth()
/** /**
* Sets whether the height of the layout depends on its width. * Gets height constraints for a given width.
*/ */
void void
BALMLayout::GetHeightForWidth(float width, float* min, float* max, float* preferred) {} BALMLayout::GetHeightForWidth(float width, float* min, float* max, float* preferred) {}
@@ -503,8 +505,9 @@ BALMLayout::GetHeightForWidth(float width, float* min, float* max, float* prefer
* Resets minimum/maximum/preferred size. * Resets minimum/maximum/preferred size.
*/ */
void void
BALMLayout::InvalidateLayout() BALMLayout::InvalidateLayout(bool children)
{ {
BLayout::InvalidateLayout(children);
fMinSize = Area::kUndefinedSize; fMinSize = Area::kUndefinedSize;
fMaxSize = Area::kUndefinedSize; fMaxSize = Area::kUndefinedSize;
fPreferredSize = Area::kUndefinedSize; fPreferredSize = Area::kUndefinedSize;
@@ -516,25 +519,28 @@ BALMLayout::InvalidateLayout()
* If no layout specification is given, a specification is reverse engineered automatically. * If no layout specification is given, a specification is reverse engineered automatically.
*/ */
void void
BALMLayout::LayoutView() BALMLayout::DerivedLayoutItems()
{ {
// TODO: modify to allow for viewlessness
// make sure that layout events occuring during layout are ignored // make sure that layout events occuring during layout are ignored
// i.e. activated is set to false during layout caluclation // i.e. activated is set to false during layout calculation
if (!fActivated) if (!fActivated)
return; return;
fActivated = false; fActivated = false;
if (View() == NULL) if (Owner() == NULL)
return; return;
// reverse engineer a layout specification if none was given // reverse engineer a layout specification if none was given
//~ if (this == NULL) RecoverLayout(View()); //~ if (this == NULL) RecoverLayout(View());
// if the layout engine is set to fit the GUI to the given size, // if the layout engine is set to fit the GUI to the given size,
// then the given size is enforced by setting absolute positions for Right and Bottom // then the given size is enforced by setting absolute positions
// for Right and Bottom
if (fLayoutStyle == FIT_TO_SIZE) { if (fLayoutStyle == FIT_TO_SIZE) {
Right()->SetRange(View()->Bounds().Width(), View()->Bounds().Width()); BRect area(LayoutArea());
Bottom()->SetRange(View()->Bounds().Height(), View()->Bounds().Height()); Right()->SetRange(area.right, area.right);
Bottom()->SetRange(area.bottom, area.bottom);
} }
SolveLayout(); SolveLayout();
@@ -554,7 +560,7 @@ BALMLayout::LayoutView()
// change the size of the GUI according to the calculated size // change the size of the GUI according to the calculated size
// if the layout engine was configured to do so // if the layout engine was configured to do so
if (fLayoutStyle == ADJUST_SIZE) { if (fLayoutStyle == ADJUST_SIZE) {
View()->ResizeTo(floor(Right()->Value() - Left()->Value() + 0.5), Owner()->ResizeTo(floor(Right()->Value() - Left()->Value() + 0.5),
floor(Bottom()->Value() - Top()->Value() + 0.5)); floor(Bottom()->Value() - Top()->Value() + 0.5));
} }