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:
@@ -7,8 +7,8 @@
|
||||
#ifndef BALM_LAYOUT_H
|
||||
#define BALM_LAYOUT_H
|
||||
|
||||
#include <AbstractLayout.h>
|
||||
#include <File.h>
|
||||
#include <Layout.h>
|
||||
#include <List.h>
|
||||
#include <Size.h>
|
||||
#include <SupportDefs.h>
|
||||
@@ -29,7 +29,7 @@ namespace BALM {
|
||||
/**
|
||||
* A GUI layout engine using the ALM.
|
||||
*/
|
||||
class BALMLayout : public BLayout, public LinearSpec {
|
||||
class BALMLayout : public BAbstractLayout, public LinearSpec {
|
||||
|
||||
public:
|
||||
BALMLayout();
|
||||
@@ -70,15 +70,15 @@ public:
|
||||
bool RemoveItem(BLayoutItem* item);
|
||||
BLayoutItem* RemoveItem(int32 index);
|
||||
|
||||
BSize MinSize();
|
||||
BSize MaxSize();
|
||||
BSize PreferredSize();
|
||||
BAlignment Alignment();
|
||||
BSize BaseMinSize();
|
||||
BSize BaseMaxSize();
|
||||
BSize BasePreferredSize();
|
||||
BAlignment BaseAlignment();
|
||||
bool HasHeightForWidth();
|
||||
void GetHeightForWidth(float width, float* min,
|
||||
float* max, float* preferred);
|
||||
void InvalidateLayout();
|
||||
void LayoutView();
|
||||
void InvalidateLayout(bool children = false);
|
||||
virtual void DerivedLayoutItems();
|
||||
|
||||
char* PerformancePath() const;
|
||||
void SetPerformancePath(char* path);
|
||||
|
||||
@@ -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
|
||||
@@ -5,10 +5,10 @@
|
||||
#ifndef _CARD_LAYOUT_H
|
||||
#define _CARD_LAYOUT_H
|
||||
|
||||
#include <Layout.h>
|
||||
#include <AbstractLayout.h>
|
||||
|
||||
|
||||
class BCardLayout : public BLayout {
|
||||
class BCardLayout : public BAbstractLayout {
|
||||
public:
|
||||
BCardLayout();
|
||||
BCardLayout(BMessage* from);
|
||||
@@ -19,23 +19,23 @@ public:
|
||||
void SetVisibleItem(int32 index);
|
||||
void SetVisibleItem(BLayoutItem* item);
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
virtual BAlignment Alignment();
|
||||
virtual BSize BaseMinSize();
|
||||
virtual BSize BaseMaxSize();
|
||||
virtual BSize BasePreferredSize();
|
||||
virtual BAlignment BaseAlignment();
|
||||
|
||||
virtual bool HasHeightForWidth();
|
||||
virtual void GetHeightForWidth(float width, float* min,
|
||||
float* max, float* preferred);
|
||||
|
||||
virtual void InvalidateLayout();
|
||||
virtual void LayoutView();
|
||||
virtual void InvalidateLayout(bool children = false);
|
||||
|
||||
virtual status_t Archive(BMessage* into, bool deep = true) const;
|
||||
virtual status_t AllUnarchived(const BMessage* from);
|
||||
static BArchivable* Instantiate(BMessage* from);
|
||||
|
||||
protected:
|
||||
virtual void DerivedLayoutItems();
|
||||
virtual bool ItemAdded(BLayoutItem* item, int32 atIndex);
|
||||
virtual void ItemRemoved(BLayoutItem* item, int32 fromIndex);
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ public:
|
||||
BGridLayoutBuilder(BGridView* view);
|
||||
|
||||
BGridLayout* GridLayout() const;
|
||||
BView* View() const;
|
||||
BGridLayoutBuilder& GetGridLayout(BGridLayout** _layout);
|
||||
BGridLayoutBuilder& GetView(BView** _view);
|
||||
BView* View() const;
|
||||
BGridLayoutBuilder& GetView(BView** _view);
|
||||
|
||||
BGridLayoutBuilder& Add(BView* view, int32 column, int32 row,
|
||||
int32 columnCount = 1, int32 rowCount = 1);
|
||||
@@ -32,7 +32,6 @@ public:
|
||||
float bottom);
|
||||
|
||||
operator BGridLayout*();
|
||||
operator BView*();
|
||||
|
||||
private:
|
||||
BGridLayout* fLayout;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All rights reserved.
|
||||
* Copyright 2006-2010, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _GROUP_LAYOUT_BUILDER_H
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
float bottom);
|
||||
|
||||
operator BGroupLayout*();
|
||||
operator BView*();
|
||||
|
||||
private:
|
||||
bool _PushLayout(BGroupLayout* layout);
|
||||
|
||||
@@ -8,22 +8,27 @@
|
||||
|
||||
#include <Alignment.h>
|
||||
#include <Archivable.h>
|
||||
#include <LayoutItem.h>
|
||||
#include <List.h>
|
||||
#include <Size.h>
|
||||
|
||||
|
||||
class BLayoutContext;
|
||||
class BLayoutItem;
|
||||
class BView;
|
||||
|
||||
|
||||
class BLayout : public BArchivable {
|
||||
class BLayout : public BLayoutItem {
|
||||
public:
|
||||
BLayout();
|
||||
BLayout(BMessage* archive);
|
||||
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(int32 index, BView* child);
|
||||
|
||||
@@ -39,18 +44,22 @@ public:
|
||||
int32 IndexOfItem(const BLayoutItem* item) const;
|
||||
int32 IndexOfView(BView* child) const;
|
||||
|
||||
virtual BSize MinSize() = 0;
|
||||
virtual BSize MaxSize() = 0;
|
||||
virtual BSize PreferredSize() = 0;
|
||||
virtual BAlignment Alignment() = 0;
|
||||
bool AncestorsVisible();
|
||||
|
||||
virtual bool HasHeightForWidth() = 0;
|
||||
virtual void GetHeightForWidth(float width, float* min,
|
||||
float* max, float* preferred) = 0;
|
||||
// Layouting related methods
|
||||
|
||||
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 AllUnarchived(const BMessage* from);
|
||||
@@ -59,17 +68,44 @@ public:
|
||||
int32 index) const;
|
||||
virtual status_t ItemUnarchived(const BMessage* from,
|
||||
BLayoutItem* item, int32 index);
|
||||
|
||||
protected:
|
||||
// BLayout hook methods
|
||||
virtual bool ItemAdded(BLayoutItem* item, int32 atIndex);
|
||||
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:
|
||||
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 fNestedLayouts;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ protected:
|
||||
public:
|
||||
inline void SetParent(ParentBuilder* parent);
|
||||
// conceptually private
|
||||
|
||||
inline ParentBuilder& End();
|
||||
|
||||
protected:
|
||||
@@ -71,11 +70,23 @@ public:
|
||||
|
||||
inline GroupBuilder AddGroup(enum orientation orientation,
|
||||
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,
|
||||
float verticalSpacing = 0.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,
|
||||
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& AddStrut(float size);
|
||||
@@ -84,7 +95,6 @@ public:
|
||||
float bottom);
|
||||
|
||||
inline operator BGroupLayout*();
|
||||
inline operator BView*();
|
||||
|
||||
private:
|
||||
BGroupLayout* fLayout;
|
||||
@@ -131,13 +141,30 @@ public:
|
||||
inline GroupBuilder AddGroup(enum orientation orientation,
|
||||
float spacing, int32 column, int32 row,
|
||||
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,
|
||||
float verticalSpacing, int32 column,
|
||||
int32 row, int32 columnCount = 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,
|
||||
float spacing, int32 column, int32 row,
|
||||
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& SetRowWeight(int32 row, float weight);
|
||||
@@ -146,7 +173,6 @@ public:
|
||||
float bottom);
|
||||
|
||||
inline operator BGridLayout*();
|
||||
inline operator BView*();
|
||||
|
||||
private:
|
||||
BGridLayout* fLayout;
|
||||
@@ -168,7 +194,8 @@ public:
|
||||
inline Split(BSplitView* view);
|
||||
|
||||
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, float weight);
|
||||
@@ -177,11 +204,23 @@ public:
|
||||
|
||||
inline GroupBuilder AddGroup(enum orientation orientation,
|
||||
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,
|
||||
float verticalSpacing = 0.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,
|
||||
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(int32 index, bool collapsible);
|
||||
@@ -244,7 +283,7 @@ Group<ParentBuilder>::Group(BWindow* window, enum orientation orientation,
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
@@ -277,7 +316,7 @@ template<typename ParentBuilder>
|
||||
BView*
|
||||
Group<ParentBuilder>::View() const
|
||||
{
|
||||
return fLayout->View();
|
||||
return fLayout->Owner();
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +333,7 @@ template<typename ParentBuilder>
|
||||
typename Group<ParentBuilder>::ThisBuilder&
|
||||
Group<ParentBuilder>::GetView(BView** _view)
|
||||
{
|
||||
*_view = fLayout->View();
|
||||
*_view = fLayout->Owner();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -340,21 +379,65 @@ typename Group<ParentBuilder>::GroupBuilder
|
||||
Group<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
|
||||
float weight)
|
||||
{
|
||||
GroupBuilder builder(orientation, spacing);
|
||||
GroupBuilder builder(new BGroupLayout(orientation, spacing));
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
template<typename ParentBuilder>
|
||||
typename Group<ParentBuilder>::GridBuilder
|
||||
Group<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing,
|
||||
float weight)
|
||||
Group<ParentBuilder>::AddGrid(float horizontalSpacing,
|
||||
float verticalSpacing, float weight)
|
||||
{
|
||||
GridBuilder builder(horizontalSpacing, verticalSpacing);
|
||||
GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
typename Group<ParentBuilder>::ThisBuilder&
|
||||
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
|
||||
|
||||
|
||||
@@ -436,7 +523,7 @@ Grid<ParentBuilder>::Grid(BWindow* window, float horizontalSpacing,
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
@@ -469,7 +556,7 @@ template<typename ParentBuilder>
|
||||
BView*
|
||||
Grid<ParentBuilder>::View() const
|
||||
{
|
||||
return fLayout->View();
|
||||
return fLayout->Owner();
|
||||
}
|
||||
|
||||
|
||||
@@ -486,7 +573,7 @@ template<typename ParentBuilder>
|
||||
typename Grid<ParentBuilder>::ThisBuilder&
|
||||
Grid<ParentBuilder>::GetView(BView** _view)
|
||||
{
|
||||
*_view = fLayout->View();
|
||||
*_view = fLayout->Owner();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -546,9 +633,33 @@ typename Grid<ParentBuilder>::GroupBuilder
|
||||
Grid<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
|
||||
int32 column, int32 row, int32 columnCount, int32 rowCount)
|
||||
{
|
||||
GroupBuilder builder(orientation, spacing);
|
||||
GroupBuilder builder(new BGroupLayout(orientation, spacing));
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -558,7 +669,19 @@ typename Grid<ParentBuilder>::GridBuilder
|
||||
Grid<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing,
|
||||
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);
|
||||
fLayout->AddView(builder.View(), column, row, columnCount, rowCount);
|
||||
return builder;
|
||||
@@ -574,7 +697,19 @@ Grid<ParentBuilder>::AddSplit(enum orientation orientation, float spacing,
|
||||
builder.SetParent(this);
|
||||
fLayout->AddView(builder.View(), column, row, columnCount, rowCount);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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>
|
||||
@@ -612,13 +747,6 @@ Grid<ParentBuilder>::operator BGridLayout*()
|
||||
}
|
||||
|
||||
|
||||
template<typename ParentBuilder>
|
||||
Grid<ParentBuilder>::operator BView*()
|
||||
{
|
||||
return fLayout->View();
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Split
|
||||
|
||||
|
||||
@@ -648,7 +776,16 @@ Split<ParentBuilder>::View() const
|
||||
|
||||
template<typename ParentBuilder>
|
||||
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;
|
||||
return *this;
|
||||
@@ -696,9 +833,31 @@ typename Split<ParentBuilder>::GroupBuilder
|
||||
Split<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
|
||||
float weight)
|
||||
{
|
||||
GroupBuilder builder(orientation, spacing);
|
||||
GroupBuilder builder(new BGroupLayout(orientation, spacing));
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -708,9 +867,31 @@ typename Split<ParentBuilder>::GridBuilder
|
||||
Split<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing,
|
||||
float weight)
|
||||
{
|
||||
GridBuilder builder(horizontalSpacing, verticalSpacing);
|
||||
GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class BLayout;
|
||||
class BView;
|
||||
|
||||
|
||||
class BLayoutItem: public BArchivable {
|
||||
class BLayoutItem : public BArchivable {
|
||||
public:
|
||||
BLayoutItem();
|
||||
BLayoutItem(BMessage* from);
|
||||
@@ -46,7 +46,8 @@ public:
|
||||
|
||||
virtual BView* View();
|
||||
|
||||
virtual void InvalidateLayout();
|
||||
virtual void InvalidateLayout(bool children = false);
|
||||
virtual void Relayout(bool immediate = false);
|
||||
|
||||
void* LayoutData() const;
|
||||
void SetLayoutData(void* data);
|
||||
@@ -57,11 +58,19 @@ public:
|
||||
virtual status_t AllArchived(BMessage* into) const;
|
||||
virtual status_t AllUnarchived(const BMessage* from);
|
||||
|
||||
private:
|
||||
friend class BLayout;
|
||||
protected:
|
||||
|
||||
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;
|
||||
void* fLayoutData;
|
||||
};
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#define _TWO_DIMENSIONAL_LAYOUT_H
|
||||
|
||||
|
||||
#include <Layout.h>
|
||||
#include <AbstractLayout.h>
|
||||
|
||||
class BLayoutContext;
|
||||
|
||||
|
||||
class BTwoDimensionalLayout : public BLayout {
|
||||
class BTwoDimensionalLayout : public BAbstractLayout {
|
||||
public:
|
||||
BTwoDimensionalLayout();
|
||||
BTwoDimensionalLayout(BMessage* from);
|
||||
@@ -25,18 +25,18 @@ public:
|
||||
void AlignLayoutWith(BTwoDimensionalLayout* other,
|
||||
enum orientation orientation);
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
virtual BAlignment Alignment();
|
||||
virtual BSize BaseMinSize();
|
||||
virtual BSize BaseMaxSize();
|
||||
virtual BSize BasePreferredSize();
|
||||
virtual BAlignment BaseAlignment();
|
||||
|
||||
virtual bool HasHeightForWidth();
|
||||
virtual void GetHeightForWidth(float width, float* min,
|
||||
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 AllArchived(BMessage* into) const;
|
||||
@@ -56,6 +56,8 @@ protected:
|
||||
int32 height;
|
||||
};
|
||||
|
||||
virtual void DerivedLayoutItems();
|
||||
|
||||
BSize AddInsets(BSize size);
|
||||
void AddInsets(float* minHeight, float* maxHeight,
|
||||
float* preferredHeight);
|
||||
@@ -82,7 +84,6 @@ private:
|
||||
friend class LocalLayouter;
|
||||
|
||||
void _ValidateMinMax();
|
||||
BLayoutContext* _CurrentLayoutContext();
|
||||
|
||||
protected:
|
||||
float fLeftInset;
|
||||
|
||||
@@ -562,6 +562,8 @@ public:
|
||||
void Layout(bool force);
|
||||
void Relayout();
|
||||
|
||||
class Private;
|
||||
|
||||
protected:
|
||||
virtual void DoLayout();
|
||||
|
||||
@@ -580,6 +582,8 @@ protected:
|
||||
|
||||
private:
|
||||
void _Layout(bool force, BLayoutContext* context);
|
||||
void _LayoutLeft(BLayout* deleted);
|
||||
void _InvalidateParentLayout();
|
||||
|
||||
private:
|
||||
// FBC padding and forbidden methods
|
||||
@@ -595,6 +599,7 @@ private:
|
||||
private:
|
||||
struct LayoutData;
|
||||
|
||||
friend class Private;
|
||||
friend class BBitmap;
|
||||
friend class BLayout;
|
||||
friend class BPrintJob;
|
||||
|
||||
@@ -103,6 +103,7 @@ public:
|
||||
void Close() { Quit(); }
|
||||
|
||||
void AddChild(BView* child, BView* before = NULL);
|
||||
void AddChild(BLayoutItem* child);
|
||||
bool RemoveChild(BView* child);
|
||||
int32 CountChildren() const;
|
||||
BView* ChildAt(int32 index) const;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <Rect.h>
|
||||
#include <Region.h>
|
||||
#include <ServerProtocolStructs.h>
|
||||
#include <View.h>
|
||||
|
||||
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 {
|
||||
|
||||
class PortLink;
|
||||
|
||||
@@ -579,6 +579,7 @@ AboutView::AboutView()
|
||||
const float offset = 5;
|
||||
|
||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
BLayoutBuilder::Group<>((BGroupLayout*)GetLayout())
|
||||
.AddGroup(B_VERTICAL)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace {
|
||||
|
||||
BCardLayout::BCardLayout()
|
||||
:
|
||||
BLayout(),
|
||||
BAbstractLayout(),
|
||||
fMin(0, 0),
|
||||
fMax(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED),
|
||||
fPreferred(0, 0),
|
||||
@@ -29,7 +29,7 @@ BCardLayout::BCardLayout()
|
||||
|
||||
BCardLayout::BCardLayout(BMessage* from)
|
||||
:
|
||||
BLayout(BUnarchiver::PrepareArchive(from)),
|
||||
BAbstractLayout(BUnarchiver::PrepareArchive(from)),
|
||||
fMin(0, 0),
|
||||
fMax(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED),
|
||||
fPreferred(0, 0),
|
||||
@@ -83,13 +83,13 @@ BCardLayout::SetVisibleItem(BLayoutItem* item)
|
||||
if (fVisibleItem != NULL) {
|
||||
fVisibleItem->SetVisible(true);
|
||||
|
||||
LayoutView();
|
||||
Relayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
BCardLayout::MinSize()
|
||||
BCardLayout::BaseMinSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return fMin;
|
||||
@@ -97,7 +97,7 @@ BCardLayout::MinSize()
|
||||
|
||||
|
||||
BSize
|
||||
BCardLayout::MaxSize()
|
||||
BCardLayout::BaseMaxSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return fMax;
|
||||
@@ -105,7 +105,7 @@ BCardLayout::MaxSize()
|
||||
|
||||
|
||||
BSize
|
||||
BCardLayout::PreferredSize()
|
||||
BCardLayout::BasePreferredSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return fPreferred;
|
||||
@@ -113,7 +113,7 @@ BCardLayout::PreferredSize()
|
||||
|
||||
|
||||
BAlignment
|
||||
BCardLayout::Alignment()
|
||||
BCardLayout::BaseAlignment()
|
||||
{
|
||||
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
|
||||
BCardLayout::InvalidateLayout()
|
||||
BCardLayout::InvalidateLayout(bool children)
|
||||
{
|
||||
BLayout::InvalidateLayout();
|
||||
BLayout::InvalidateLayout(children);
|
||||
|
||||
fMinMaxValid = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BCardLayout::LayoutView()
|
||||
BCardLayout::DerivedLayoutItems()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
|
||||
BSize size = View()->Bounds().Size();
|
||||
size.width = max_c(size.width, fMin.width);
|
||||
size.height = max_c(size.height, fMin.height);
|
||||
BSize size(LayoutArea().Size());
|
||||
|
||||
if (fVisibleItem != NULL)
|
||||
fVisibleItem->AlignInFrame(BRect(0, 0, size.width, size.height));
|
||||
// this cannot be done when we are viewless, as our children
|
||||
// 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
|
||||
{
|
||||
BArchiver archiver(into);
|
||||
status_t err = BLayout::Archive(into, deep);
|
||||
status_t err = BAbstractLayout::Archive(into, deep);
|
||||
|
||||
if (err == B_OK && deep)
|
||||
err = into->AddInt32(kVisibleItemField, IndexOfItem(fVisibleItem));
|
||||
@@ -292,7 +297,5 @@ BCardLayout::_ValidateMinMax()
|
||||
fPreferred.height = min_c(fPreferred.height, fMax.height);
|
||||
|
||||
fMinMaxValid = true;
|
||||
|
||||
if (BView* view = View())
|
||||
view->ResetLayoutInvalidation();
|
||||
ResetLayoutInvalidation();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ BGridLayoutBuilder::GridLayout() const
|
||||
BView*
|
||||
BGridLayoutBuilder::View() const
|
||||
{
|
||||
return fLayout->View();
|
||||
return fLayout->Owner();
|
||||
}
|
||||
|
||||
// GetGridLayout
|
||||
@@ -60,7 +60,7 @@ BGridLayoutBuilder::GetGridLayout(BGridLayout** _layout)
|
||||
BGridLayoutBuilder&
|
||||
BGridLayoutBuilder::GetView(BView** _view)
|
||||
{
|
||||
*_view = fLayout->View();
|
||||
*_view = fLayout->Owner();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -112,8 +112,3 @@ BGridLayoutBuilder::operator BGridLayout*()
|
||||
return fLayout;
|
||||
}
|
||||
|
||||
// cast operator BView*
|
||||
BGridLayoutBuilder::operator BView*()
|
||||
{
|
||||
return fLayout->View();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ BGroupLayoutBuilder::BGroupLayoutBuilder(BGroupLayout* layout)
|
||||
_PushLayout(fRootLayout);
|
||||
}
|
||||
|
||||
|
||||
// constructor
|
||||
BGroupLayoutBuilder::BGroupLayoutBuilder(BGroupView* view)
|
||||
: fRootLayout(view->GroupLayout())
|
||||
@@ -64,7 +63,7 @@ BGroupLayoutBuilder::GetTopLayout(BGroupLayout** _layout)
|
||||
BView*
|
||||
BGroupLayoutBuilder::TopView() const
|
||||
{
|
||||
return TopLayout()->View();
|
||||
return TopLayout()->Owner();
|
||||
}
|
||||
|
||||
// GetTopView
|
||||
@@ -72,7 +71,7 @@ BGroupLayoutBuilder&
|
||||
BGroupLayoutBuilder::GetTopView(BView** _view)
|
||||
{
|
||||
if (BGroupLayout* layout = TopLayout())
|
||||
*_view = layout->View();
|
||||
*_view = layout->Owner();
|
||||
else
|
||||
*_view = NULL;
|
||||
|
||||
@@ -181,12 +180,6 @@ BGroupLayoutBuilder::operator BGroupLayout*()
|
||||
return fRootLayout;
|
||||
}
|
||||
|
||||
// cast operator BView*
|
||||
BGroupLayoutBuilder::operator BView*()
|
||||
{
|
||||
return fRootLayout->View();
|
||||
}
|
||||
|
||||
// _PushLayout
|
||||
bool
|
||||
BGroupLayoutBuilder::_PushLayout(BGroupLayout* layout)
|
||||
|
||||
@@ -31,6 +31,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) textview_support ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) layouter ] ;
|
||||
|
||||
MergeObject <libbe>interface_kit.o :
|
||||
AbstractLayout.cpp
|
||||
AbstractLayoutItem.cpp
|
||||
AffineTransform.cpp
|
||||
Alert.cpp
|
||||
|
||||
+344
-27
@@ -7,26 +7,50 @@
|
||||
|
||||
#include <Layout.h>
|
||||
|
||||
#include <syslog.h>
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <LayoutContext.h>
|
||||
#include <Message.h>
|
||||
#include <View.h>
|
||||
#include <ViewPrivate.h>
|
||||
|
||||
#include "ViewLayoutItem.h"
|
||||
|
||||
|
||||
using std::nothrow;
|
||||
using std::swap;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
|
||||
BLayout::BLayout()
|
||||
:
|
||||
fView(NULL),
|
||||
fState(B_LAYOUT_ALL_CLEAR),
|
||||
fAncestorsVisible(true),
|
||||
fInvalidationDisabled(0),
|
||||
fContext(NULL),
|
||||
fOwner(NULL),
|
||||
fTarget(NULL),
|
||||
fItems(20)
|
||||
{
|
||||
}
|
||||
@@ -34,8 +58,13 @@ BLayout::BLayout()
|
||||
|
||||
BLayout::BLayout(BMessage* from)
|
||||
:
|
||||
BArchivable(BUnarchiver::PrepareArchive(from)),
|
||||
fView(NULL),
|
||||
BLayoutItem(BUnarchiver::PrepareArchive(from)),
|
||||
fState(B_LAYOUT_ALL_CLEAR),
|
||||
fAncestorsVisible(true),
|
||||
fInvalidationDisabled(0),
|
||||
fContext(NULL),
|
||||
fOwner(NULL),
|
||||
fTarget(NULL),
|
||||
fItems(20)
|
||||
{
|
||||
BUnarchiver unarchiver(from);
|
||||
@@ -48,15 +77,36 @@ BLayout::BLayout(BMessage* from)
|
||||
|
||||
BLayout::~BLayout()
|
||||
{
|
||||
// this deletes all items
|
||||
SetView(NULL);
|
||||
// in case we have a view, but have been added to a layout as a BLayoutItem
|
||||
// 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*
|
||||
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*
|
||||
BLayout::AddView(int32 index, BView* child)
|
||||
{
|
||||
if (BViewLayoutItem* item = new(nothrow) BViewLayoutItem(child)) {
|
||||
if (AddItem(index, item))
|
||||
return item;
|
||||
BLayoutItem* item = child->GetLayout();
|
||||
if (!item)
|
||||
item = new(nothrow) BViewLayoutItem(child);
|
||||
|
||||
if (item && AddItem(index, item))
|
||||
return item;
|
||||
|
||||
if (!child->GetLayout())
|
||||
delete item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -89,15 +143,15 @@ BLayout::AddItem(BLayoutItem* item)
|
||||
bool
|
||||
BLayout::AddItem(int32 index, BLayoutItem* item)
|
||||
{
|
||||
if (!fView || !item || fItems.HasItem(item))
|
||||
if (!fTarget || !item || fItems.HasItem(item))
|
||||
return false;
|
||||
|
||||
// if the item refers to a BView, we make sure it is added to the parent
|
||||
// view
|
||||
bool addedView = false;
|
||||
BView* view = item->View();
|
||||
if (view && view->fParent != fView
|
||||
&& !(addedView = fView->_AddChild(view, NULL)))
|
||||
if (view && view->fParent != fTarget
|
||||
&& !(addedView = fTarget->_AddChild(view, NULL)))
|
||||
return false;
|
||||
|
||||
// validate the index
|
||||
@@ -106,6 +160,8 @@ BLayout::AddItem(int32 index, BLayoutItem* item)
|
||||
|
||||
if (fItems.AddItem(item, index) && ItemAdded(item, index)) {
|
||||
item->SetLayout(this);
|
||||
if (!fAncestorsVisible)
|
||||
item->AncestorVisibilityChanged(fAncestorsVisible);
|
||||
InvalidateLayout();
|
||||
return true;
|
||||
} else {
|
||||
@@ -160,11 +216,11 @@ BLayout::RemoveItem(int32 index)
|
||||
// if the item refers to a BView, we make sure, it is removed from the
|
||||
// parent view
|
||||
BView* view = item->View();
|
||||
if (view && view->fParent == fView)
|
||||
if (view && view->fParent == fTarget)
|
||||
view->_RemoveSelf();
|
||||
|
||||
item->SetLayout(NULL);
|
||||
ItemRemoved(item, index);
|
||||
item->SetLayout(NULL);
|
||||
InvalidateLayout();
|
||||
|
||||
return item;
|
||||
@@ -206,11 +262,150 @@ BLayout::IndexOfView(BView* child) const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BLayout::InvalidateLayout()
|
||||
bool
|
||||
BLayout::AncestorsVisible()
|
||||
{
|
||||
if (fView)
|
||||
fView->InvalidateLayout();
|
||||
return fAncestorsVisible;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
BArchiver archiver(into);
|
||||
status_t err = BArchivable::Archive(into, deep);
|
||||
status_t err = BLayoutItem::Archive(into, deep);
|
||||
|
||||
if (deep) {
|
||||
int32 count = CountItems();
|
||||
@@ -242,7 +437,7 @@ status_t
|
||||
BLayout::AllUnarchived(const BMessage* from)
|
||||
{
|
||||
BUnarchiver unarchiver(from);
|
||||
status_t err = BArchivable::AllUnarchived(from);
|
||||
status_t err = BLayoutItem::AllUnarchived(from);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
|
||||
@@ -304,16 +499,138 @@ BLayout::ItemRemoved(BLayoutItem* item, int32 fromIndex)
|
||||
|
||||
|
||||
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
|
||||
for (int32 i = CountItems() - 1; i >= 0; i--)
|
||||
delete RemoveItem(i);
|
||||
|
||||
fView = view;
|
||||
fTarget = target;
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
#include <Layout.h>
|
||||
#include <LayoutUtils.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
BLayoutItem::BLayoutItem()
|
||||
@@ -30,6 +33,8 @@ BLayoutItem::BLayoutItem(BMessage* from)
|
||||
|
||||
BLayoutItem::~BLayoutItem()
|
||||
{
|
||||
if (fLayout)
|
||||
fLayout->RemoveItem(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,10 +69,21 @@ BLayoutItem::View()
|
||||
|
||||
|
||||
void
|
||||
BLayoutItem::InvalidateLayout()
|
||||
BLayoutItem::InvalidateLayout(bool children)
|
||||
{
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ BSplitLayout::BSplitLayout(enum orientation orientation,
|
||||
|
||||
BSplitLayout::BSplitLayout(BMessage* from)
|
||||
:
|
||||
BLayout(BUnarchiver::PrepareArchive(from)),
|
||||
BAbstractLayout(BUnarchiver::PrepareArchive(from)),
|
||||
fSplitterItems(),
|
||||
fVisibleItems(),
|
||||
fMin(),
|
||||
@@ -340,14 +340,14 @@ BSplitLayout::SetSplitterSize(float size)
|
||||
BLayoutItem*
|
||||
BSplitLayout::AddView(BView* child)
|
||||
{
|
||||
return BLayout::AddView(child);
|
||||
return BAbstractLayout::AddView(child);
|
||||
}
|
||||
|
||||
|
||||
BLayoutItem*
|
||||
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
|
||||
BSplitLayout::AddItem(BLayoutItem* item)
|
||||
{
|
||||
return BLayout::AddItem(item);
|
||||
return BAbstractLayout::AddItem(item);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
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
|
||||
BSplitLayout::MinSize()
|
||||
BSplitLayout::BaseMinSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
|
||||
@@ -489,7 +489,7 @@ BSplitLayout::MinSize()
|
||||
|
||||
|
||||
BSize
|
||||
BSplitLayout::MaxSize()
|
||||
BSplitLayout::BaseMaxSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
|
||||
@@ -498,7 +498,7 @@ BSplitLayout::MaxSize()
|
||||
|
||||
|
||||
BSize
|
||||
BSplitLayout::PreferredSize()
|
||||
BSplitLayout::BasePreferredSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
|
||||
@@ -507,9 +507,9 @@ BSplitLayout::PreferredSize()
|
||||
|
||||
|
||||
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
|
||||
BSplitLayout::InvalidateLayout()
|
||||
BSplitLayout::InvalidateLayout(bool children)
|
||||
{
|
||||
_InvalidateLayout(true);
|
||||
_InvalidateLayout(true, children);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSplitLayout::LayoutView()
|
||||
BSplitLayout::DerivedLayoutItems()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
|
||||
// layout the elements
|
||||
BSize size = _SubtractInsets(View()->Bounds().Size());
|
||||
BSize size = _SubtractInsets(LayoutArea().Size());
|
||||
fHorizontalLayouter->Layout(fHorizontalLayoutInfo, size.width);
|
||||
|
||||
Layouter* verticalLayouter;
|
||||
@@ -647,7 +647,7 @@ BSplitLayout::StartDraggingSplitter(BPoint point)
|
||||
return false;
|
||||
|
||||
// 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)
|
||||
|| (fOrientation == B_VERTICAL && size.height >= fMax.height)) {
|
||||
return false;
|
||||
@@ -655,7 +655,7 @@ BSplitLayout::StartDraggingSplitter(BPoint point)
|
||||
|
||||
int32 index = -1;
|
||||
if (_SplitterItemAt(point, &index) != NULL) {
|
||||
fDraggingStartPoint = View()->ConvertToScreen(point);
|
||||
fDraggingStartPoint = Owner()->ConvertToScreen(point);
|
||||
fDraggingStartValue = _SplitterValue(index);
|
||||
fDraggingCurrentValue = fDraggingStartValue;
|
||||
fDraggingSplitterIndex = index;
|
||||
@@ -673,7 +673,7 @@ BSplitLayout::DragSplitter(BPoint point)
|
||||
if (fDraggingSplitterIndex < 0)
|
||||
return false;
|
||||
|
||||
point = View()->ConvertToScreen(point);
|
||||
point = Owner()->ConvertToScreen(point);
|
||||
|
||||
int32 valueDiff;
|
||||
if (fOrientation == B_HORIZONTAL)
|
||||
@@ -712,7 +712,7 @@ status_t
|
||||
BSplitLayout::Archive(BMessage* into, bool deep) const
|
||||
{
|
||||
BArchiver archiver(into);
|
||||
status_t err = BLayout::Archive(into, deep);
|
||||
status_t err = BAbstractLayout::Archive(into, deep);
|
||||
|
||||
if (err == B_OK)
|
||||
err = into->AddBool(kIsVerticalField, fOrientation == B_VERTICAL);
|
||||
@@ -811,10 +811,10 @@ BSplitLayout::ItemRemoved(BLayoutItem* item, int32 atIndex)
|
||||
|
||||
|
||||
void
|
||||
BSplitLayout::_InvalidateLayout(bool invalidateView)
|
||||
BSplitLayout::_InvalidateLayout(bool invalidateView, bool children)
|
||||
{
|
||||
if (invalidateView)
|
||||
BLayout::InvalidateLayout();
|
||||
BAbstractLayout::InvalidateLayout(children);
|
||||
|
||||
delete fHorizontalLayouter;
|
||||
delete fVerticalLayouter;
|
||||
@@ -929,7 +929,7 @@ BSplitLayout::_LayoutItem(BLayoutItem* item, BRect frame, bool visible)
|
||||
info->max = item->MaxSize();
|
||||
|
||||
if (item->HasHeightForWidth()) {
|
||||
BSize size = _SubtractInsets(View()->Frame().Size());
|
||||
BSize size = _SubtractInsets(LayoutArea().Size());
|
||||
float minHeight, maxHeight;
|
||||
item->GetHeightForWidth(size.width, &minHeight, &maxHeight, NULL);
|
||||
info->min.height = max_c(info->min.height, minHeight);
|
||||
@@ -958,9 +958,9 @@ BSplitLayout::_LayoutItem(BLayoutItem* item, ItemLayoutInfo* info)
|
||||
item->AlignInFrame(info->layoutFrame);
|
||||
|
||||
// if the item became visible, we need to update its internal layout
|
||||
if (visibilityChanged) {
|
||||
if (BView* itemView = item->View())
|
||||
itemView->Layout(false);
|
||||
if (visibilityChanged && fOrientation != B_HORIZONTAL
|
||||
|| !HasHeightForWidth()) {
|
||||
item->Relayout(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1216,7 +1216,7 @@ BSplitLayout::_UpdateSplitterWeights()
|
||||
}
|
||||
|
||||
// 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
|
||||
// obsolete cached values will be used.
|
||||
if (fOrientation == B_VERTICAL)
|
||||
@@ -1293,8 +1293,7 @@ BSplitLayout::_ValidateMinMax()
|
||||
if (fHeightForWidthItems.IsEmpty())
|
||||
fVerticalLayoutInfo = fVerticalLayouter->CreateLayoutInfo();
|
||||
|
||||
if (BView* view = View())
|
||||
view->ResetLayoutInvalidation();
|
||||
ResetLayoutInvalidation();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define _SPLIT_LAYOUT_H
|
||||
|
||||
|
||||
#include <Layout.h>
|
||||
#include <AbstractLayout.h>
|
||||
#include <Point.h>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ using BPrivate::Layout::Layouter;
|
||||
using BPrivate::Layout::LayoutInfo;
|
||||
|
||||
|
||||
class BSplitLayout : public BLayout {
|
||||
class BSplitLayout : public BAbstractLayout {
|
||||
public:
|
||||
BSplitLayout(enum orientation orientation,
|
||||
float spacing = 0.0f);
|
||||
@@ -66,18 +66,18 @@ public:
|
||||
void SetCollapsible(int32 first, int32 last,
|
||||
bool collapsible);
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
virtual BAlignment Alignment();
|
||||
virtual BSize BaseMinSize();
|
||||
virtual BSize BaseMaxSize();
|
||||
virtual BSize BasePreferredSize();
|
||||
virtual BAlignment BaseAlignment();
|
||||
|
||||
virtual bool HasHeightForWidth();
|
||||
virtual void GetHeightForWidth(float width, float* min,
|
||||
float* max, float* preferred);
|
||||
|
||||
virtual void InvalidateLayout();
|
||||
virtual void InvalidateLayout(bool children = false);
|
||||
|
||||
virtual void LayoutView();
|
||||
virtual void DerivedLayoutItems();
|
||||
|
||||
// interface for BSplitView
|
||||
BRect SplitterItemFrame(int32 index) const;
|
||||
@@ -106,7 +106,8 @@ private:
|
||||
class ValueRange;
|
||||
class SplitterItem;
|
||||
|
||||
void _InvalidateLayout(bool invalidateView);
|
||||
void _InvalidateLayout(bool invalidateView,
|
||||
bool children = false);
|
||||
void _InvalidateCachedHeightForWidth();
|
||||
|
||||
SplitterItem* _SplitterItemAt(const BPoint& point,
|
||||
|
||||
@@ -258,7 +258,7 @@ BTwoDimensionalLayout::BTwoDimensionalLayout()
|
||||
|
||||
BTwoDimensionalLayout::BTwoDimensionalLayout(BMessage* from)
|
||||
:
|
||||
BLayout(from),
|
||||
BAbstractLayout(from),
|
||||
fLeftInset(0),
|
||||
fRightInset(0),
|
||||
fTopInset(0),
|
||||
@@ -324,7 +324,7 @@ BTwoDimensionalLayout::AlignLayoutWith(BTwoDimensionalLayout* other,
|
||||
|
||||
|
||||
BSize
|
||||
BTwoDimensionalLayout::MinSize()
|
||||
BTwoDimensionalLayout::BaseMinSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return AddInsets(fLocalLayouter->MinSize());
|
||||
@@ -332,7 +332,7 @@ BTwoDimensionalLayout::MinSize()
|
||||
|
||||
|
||||
BSize
|
||||
BTwoDimensionalLayout::MaxSize()
|
||||
BTwoDimensionalLayout::BaseMaxSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return AddInsets(fLocalLayouter->MaxSize());
|
||||
@@ -340,7 +340,7 @@ BTwoDimensionalLayout::MaxSize()
|
||||
|
||||
|
||||
BSize
|
||||
BTwoDimensionalLayout::PreferredSize()
|
||||
BTwoDimensionalLayout::BasePreferredSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return AddInsets(fLocalLayouter->PreferredSize());
|
||||
@@ -348,9 +348,9 @@ BTwoDimensionalLayout::PreferredSize()
|
||||
|
||||
|
||||
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
|
||||
BTwoDimensionalLayout::InvalidateLayout()
|
||||
BTwoDimensionalLayout::SetFrame(BRect frame)
|
||||
{
|
||||
BLayout::InvalidateLayout();
|
||||
|
||||
fLocalLayouter->InvalidateLayout();
|
||||
BAbstractLayout::SetFrame(frame);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BTwoDimensionalLayout::LayoutView()
|
||||
BTwoDimensionalLayout::InvalidateLayout(bool children)
|
||||
{
|
||||
_ValidateMinMax();
|
||||
|
||||
// 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);
|
||||
}
|
||||
BLayout::InvalidateLayout(children);
|
||||
fLocalLayouter->InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
@@ -442,7 +395,7 @@ status_t
|
||||
BTwoDimensionalLayout::Archive(BMessage* into, bool deep) const
|
||||
{
|
||||
BArchiver archiver(into);
|
||||
status_t err = BLayout::Archive(into, deep);
|
||||
status_t err = BAbstractLayout::Archive(into, deep);
|
||||
|
||||
if (err == B_OK) {
|
||||
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
|
||||
BTwoDimensionalLayout::AddInsets(BSize size)
|
||||
{
|
||||
@@ -547,17 +555,6 @@ void
|
||||
BTwoDimensionalLayout::_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)
|
||||
{
|
||||
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();
|
||||
fVLayouter->ValidateMinMax();
|
||||
fLayout->ResetLayoutInvalidation();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BTwoDimensionalLayout::LocalLayouter::DoHorizontalLayout(float width)
|
||||
{
|
||||
BLayoutContext* context = fLayout->_CurrentLayoutContext();
|
||||
BLayoutContext* context = fLayout->LayoutContext();
|
||||
if (fHorizontalLayoutContext != context
|
||||
|| width != fHorizontalLayoutWidth) {
|
||||
_SetHorizontalLayoutContext(context, width);
|
||||
|
||||
+82
-26
@@ -648,7 +648,7 @@ BView::AllUnarchived(const BMessage* from)
|
||||
err = unarchiver.FindObject(kLayoutField, layout);
|
||||
if (err == B_OK && layout) {
|
||||
fFlags |= B_SUPPORTS_LAYOUT;
|
||||
fLayoutData->fLayout->BLayout::SetView(this);
|
||||
fLayoutData->fLayout->SetOwner(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -997,7 +997,7 @@ BView::Hide()
|
||||
fShowLevel++;
|
||||
|
||||
if (fShowLevel == 1 && fParent)
|
||||
fParent->InvalidateLayout();
|
||||
_InvalidateParentLayout();
|
||||
}
|
||||
|
||||
|
||||
@@ -1012,7 +1012,7 @@ BView::Show()
|
||||
}
|
||||
|
||||
if (fShowLevel == 0 && fParent)
|
||||
fParent->InvalidateLayout();
|
||||
_InvalidateParentLayout();
|
||||
}
|
||||
|
||||
|
||||
@@ -4020,7 +4020,7 @@ bool
|
||||
BView::RemoveSelf()
|
||||
{
|
||||
if (fParent && fParent->fLayoutData->fLayout)
|
||||
return fParent->fLayoutData->fLayout->RemoveView(this);
|
||||
return fParent->fLayoutData->fLayout->RemoveViewRecursive(this);
|
||||
|
||||
return _RemoveSelf();
|
||||
}
|
||||
@@ -4643,18 +4643,21 @@ BView::SetLayout(BLayout* layout)
|
||||
if (layout == fLayoutData->fLayout)
|
||||
return;
|
||||
|
||||
if (layout && layout->Layout())
|
||||
debugger("BView::SetLayout() failed, layout is already in use.");
|
||||
|
||||
fFlags |= B_SUPPORTS_LAYOUT;
|
||||
|
||||
// unset and delete the old layout
|
||||
if (fLayoutData->fLayout) {
|
||||
fLayoutData->fLayout->SetView(NULL);
|
||||
fLayoutData->fLayout->SetOwner(NULL);
|
||||
delete fLayoutData->fLayout;
|
||||
}
|
||||
|
||||
fLayoutData->fLayout = layout;
|
||||
|
||||
if (fLayoutData->fLayout) {
|
||||
fLayoutData->fLayout->SetView(this);
|
||||
fLayoutData->fLayout->SetOwner(this);
|
||||
|
||||
// add all children
|
||||
int count = CountChildren();
|
||||
@@ -4676,21 +4679,27 @@ BView::GetLayout() const
|
||||
void
|
||||
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
|
||||
&& fLayoutData->fLayoutInvalidationDisabled == 0) {
|
||||
if (fParent && fParent->fLayoutData->fMinMaxValid)
|
||||
fParent->InvalidateLayout(false);
|
||||
&& fLayoutData->fLayoutInvalidationDisabled == 0) {
|
||||
|
||||
fLayoutData->fLayoutValid = false;
|
||||
fLayoutData->fMinMaxValid = false;
|
||||
|
||||
if (fLayoutData->fLayout)
|
||||
fLayoutData->fLayout->InvalidateLayout();
|
||||
|
||||
if (descendants) {
|
||||
int count = CountChildren();
|
||||
for (int i = 0; i < count; i++)
|
||||
ChildAt(i)->InvalidateLayout(descendants);
|
||||
for (BView* child = fFirstChild;
|
||||
child; child = child->fNextSibling) {
|
||||
child->InvalidateLayout(descendants);
|
||||
}
|
||||
}
|
||||
|
||||
if (fLayoutData->fLayout && fLayoutData->fLayout->InvalidationLegal())
|
||||
fLayoutData->fLayout->InvalidateLayout(descendants);
|
||||
else if (!fLayoutData->fLayout && fParent) {
|
||||
_InvalidateParentLayout();
|
||||
}
|
||||
|
||||
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.
|
||||
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
|
||||
information also in methods other than LayoutView(), it has to invoke this
|
||||
BLayout & BView will avoid calling InvalidateLayout on views that have
|
||||
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
|
||||
obsolete without the layout noticing.
|
||||
*/
|
||||
@@ -4763,6 +4769,8 @@ BView::Relayout()
|
||||
{
|
||||
if (fLayoutData->fLayoutValid && !fLayoutData->fLayoutInProgress) {
|
||||
fLayoutData->fNeedsRelayout = true;
|
||||
if (fLayoutData->fLayout)
|
||||
fLayoutData->fLayout->RequireLayout();
|
||||
|
||||
// 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
|
||||
@@ -4777,7 +4785,7 @@ void
|
||||
BView::DoLayout()
|
||||
{
|
||||
if (fLayoutData->fLayout)
|
||||
fLayoutData->fLayout->LayoutView();
|
||||
fLayoutData->fLayout->_LayoutWithinContext(false, LayoutContext());
|
||||
}
|
||||
|
||||
|
||||
@@ -4881,9 +4889,7 @@ BView::_Layout(bool force, BLayoutContext* context)
|
||||
fLayoutData->fNeedsRelayout = false;
|
||||
|
||||
// layout children
|
||||
int32 childCount = CountChildren();
|
||||
for (int32 i = 0; i < childCount; i++) {
|
||||
BView* child = ChildAt(i);
|
||||
for(BView* child = fFirstChild; child; child = child->fNextSibling) {
|
||||
if (!child->IsHidden(child))
|
||||
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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <Layout.h>
|
||||
#include <View.h>
|
||||
#include <ViewPrivate.h>
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -20,7 +21,8 @@ namespace {
|
||||
|
||||
BViewLayoutItem::BViewLayoutItem(BView* view)
|
||||
:
|
||||
fView(view)
|
||||
fView(view),
|
||||
fAncestorsVisible(true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -28,7 +30,8 @@ BViewLayoutItem::BViewLayoutItem(BView* view)
|
||||
BViewLayoutItem::BViewLayoutItem(BMessage* from)
|
||||
:
|
||||
BLayoutItem(BUnarchiver::PrepareArchive(from)),
|
||||
fView(NULL)
|
||||
fView(NULL),
|
||||
fAncestorsVisible(true)
|
||||
{
|
||||
BUnarchiver unarchiver(from);
|
||||
unarchiver.Finish(unarchiver.FindObject<BView>(kViewField, 0,
|
||||
@@ -100,7 +103,8 @@ BViewLayoutItem::SetExplicitAlignment(BAlignment alignment)
|
||||
bool
|
||||
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
|
||||
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 NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BViewLayoutItem::AncestorVisibilityChanged(bool shown)
|
||||
{
|
||||
if (fAncestorsVisible == shown)
|
||||
return;
|
||||
|
||||
fAncestorsVisible = shown;
|
||||
if (shown)
|
||||
fView->Show();
|
||||
if (!shown)
|
||||
fView->Hide();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,15 +36,20 @@ public:
|
||||
|
||||
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 AllArchived(BMessage* into) const;
|
||||
virtual status_t AllUnarchived(const BMessage* from);
|
||||
static BArchivable* Instantiate(BMessage* from);
|
||||
|
||||
protected:
|
||||
virtual void AncestorVisibilityChanged(bool shown);
|
||||
|
||||
private:
|
||||
BView* fView;
|
||||
int32 fAncestorsVisible;
|
||||
};
|
||||
|
||||
#endif // _VIEW_LAYOUT_ITEM_H
|
||||
|
||||
@@ -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
|
||||
BWindow::RemoveChild(BView* child)
|
||||
{
|
||||
|
||||
+27
-21
@@ -20,7 +20,8 @@
|
||||
* Creates new layout engine.
|
||||
*/
|
||||
BALMLayout::BALMLayout()
|
||||
: BLayout(),
|
||||
:
|
||||
BAbstractLayout(),
|
||||
LinearSpec()
|
||||
{
|
||||
fLayoutStyle = FIT_TO_SIZE;
|
||||
@@ -189,7 +190,7 @@ BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
|
||||
{
|
||||
InvalidateLayout();
|
||||
if (content != NULL)
|
||||
View()->AddChild(content);
|
||||
TargetView()->AddChild(content);
|
||||
Area* area = new Area(this, left, top, right, bottom, content, minContentSize);
|
||||
fAreas->AddItem(area);
|
||||
return area;
|
||||
@@ -211,7 +212,7 @@ BALMLayout::AddArea(Row* row, Column* column, BView* content,
|
||||
{
|
||||
InvalidateLayout();
|
||||
if (content != NULL)
|
||||
View()->AddChild(content);
|
||||
TargetView()->AddChild(content);
|
||||
Area* area = new Area(this, row, column, content, minContentSize);
|
||||
fAreas->AddItem(area);
|
||||
return area;
|
||||
@@ -234,7 +235,7 @@ BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
|
||||
{
|
||||
InvalidateLayout();
|
||||
if (content != NULL)
|
||||
View()->AddChild(content);
|
||||
TargetView()->AddChild(content);
|
||||
Area* area = new Area(this, left, top, right, bottom, content, BSize(0, 0));
|
||||
area->SetDefaultBehavior();
|
||||
area->SetAutoPreferredContentSize(false);
|
||||
@@ -256,7 +257,7 @@ BALMLayout::AddArea(Row* row, Column* column, BView* content)
|
||||
{
|
||||
InvalidateLayout();
|
||||
if (content != NULL)
|
||||
View()->AddChild(content);
|
||||
TargetView()->AddChild(content);
|
||||
Area* area = new Area(this, row, column, content, BSize(0, 0));
|
||||
area->SetDefaultBehavior();
|
||||
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)
|
||||
fMinSize = CalculateMinSize();
|
||||
return fMinSize;
|
||||
@@ -445,10 +447,10 @@ BSize BALMLayout::MinSize() {
|
||||
|
||||
|
||||
/**
|
||||
* Sets and gets maximum size.
|
||||
* Gets maximum size.
|
||||
*/
|
||||
BSize
|
||||
BALMLayout::MaxSize()
|
||||
BALMLayout::BaseMaxSize()
|
||||
{
|
||||
if (fMaxSize == Area::kUndefinedSize)
|
||||
fMaxSize = CalculateMaxSize();
|
||||
@@ -457,10 +459,10 @@ BALMLayout::MaxSize()
|
||||
|
||||
|
||||
/**
|
||||
* Sets and gets preferred size.
|
||||
* Gets preferred size.
|
||||
*/
|
||||
BSize
|
||||
BALMLayout::PreferredSize()
|
||||
BALMLayout::BasePreferredSize()
|
||||
{
|
||||
if (fPreferredSize == Area::kUndefinedSize)
|
||||
fPreferredSize = CalculatePreferredSize();
|
||||
@@ -472,7 +474,7 @@ BALMLayout::PreferredSize()
|
||||
* Gets the alignment.
|
||||
*/
|
||||
BAlignment
|
||||
BALMLayout::Alignment()
|
||||
BALMLayout::BaseAlignment()
|
||||
{
|
||||
BAlignment alignment;
|
||||
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
|
||||
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.
|
||||
*/
|
||||
void
|
||||
BALMLayout::InvalidateLayout()
|
||||
BALMLayout::InvalidateLayout(bool children)
|
||||
{
|
||||
BLayout::InvalidateLayout(children);
|
||||
fMinSize = Area::kUndefinedSize;
|
||||
fMaxSize = Area::kUndefinedSize;
|
||||
fPreferredSize = Area::kUndefinedSize;
|
||||
@@ -516,25 +519,28 @@ BALMLayout::InvalidateLayout()
|
||||
* If no layout specification is given, a specification is reverse engineered automatically.
|
||||
*/
|
||||
void
|
||||
BALMLayout::LayoutView()
|
||||
BALMLayout::DerivedLayoutItems()
|
||||
{
|
||||
// TODO: modify to allow for viewlessness
|
||||
// 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)
|
||||
return;
|
||||
fActivated = false;
|
||||
|
||||
if (View() == NULL)
|
||||
if (Owner() == NULL)
|
||||
return;
|
||||
|
||||
// reverse engineer a layout specification if none was given
|
||||
//~ if (this == NULL) RecoverLayout(View());
|
||||
|
||||
// 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) {
|
||||
Right()->SetRange(View()->Bounds().Width(), View()->Bounds().Width());
|
||||
Bottom()->SetRange(View()->Bounds().Height(), View()->Bounds().Height());
|
||||
BRect area(LayoutArea());
|
||||
Right()->SetRange(area.right, area.right);
|
||||
Bottom()->SetRange(area.bottom, area.bottom);
|
||||
}
|
||||
|
||||
SolveLayout();
|
||||
@@ -554,7 +560,7 @@ BALMLayout::LayoutView()
|
||||
// change the size of the GUI according to the calculated size
|
||||
// if the layout engine was configured to do so
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user