canvas::Layout: support for contents margins.

This commit is contained in:
Thomas Geymayer
2014-07-22 12:00:24 +02:00
parent f25abad9d7
commit 76fc47b24b
11 changed files with 456 additions and 147 deletions
+1 -12
View File
@@ -196,7 +196,6 @@ namespace canvas
{ {
_layout = layout; _layout = layout;
_layout->setCanvas(this); _layout->setCanvas(this);
_status |= LAYOUT_DIRTY;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -256,15 +255,7 @@ namespace canvas
} }
if( _layout ) if( _layout )
{ _layout->setGeometry(SGRecti(0, 0, _view_width, _view_height));
if( (_status & LAYOUT_DIRTY) )
{
_layout->setGeometry(SGRecti(0, 0, _view_width, _view_height));
_status &= ~LAYOUT_DIRTY;
}
else
_layout->update();
}
if( _visible || _render_always ) if( _visible || _render_always )
{ {
@@ -410,7 +401,6 @@ namespace canvas
if( _view_width == w ) if( _view_width == w )
return; return;
_view_width = w; _view_width = w;
_status |= LAYOUT_DIRTY;
_texture.setViewSize(_view_width, _view_height); _texture.setViewSize(_view_width, _view_height);
} }
@@ -421,7 +411,6 @@ namespace canvas
if( _view_height == h ) if( _view_height == h )
return; return;
_view_height = h; _view_height = h;
_status |= LAYOUT_DIRTY;
_texture.setViewSize(_view_width, _view_height); _texture.setViewSize(_view_width, _view_height);
} }
+1 -2
View File
@@ -53,8 +53,7 @@ namespace canvas
{ {
STATUS_OK, STATUS_OK,
STATUS_DIRTY = 1, STATUS_DIRTY = 1,
LAYOUT_DIRTY = STATUS_DIRTY << 1, MISSING_SIZE_X = STATUS_DIRTY << 1,
MISSING_SIZE_X = LAYOUT_DIRTY << 1,
MISSING_SIZE_Y = MISSING_SIZE_X << 1, MISSING_SIZE_Y = MISSING_SIZE_X << 1,
MISSING_SIZE = MISSING_SIZE_X | MISSING_SIZE_Y, MISSING_SIZE = MISSING_SIZE_X | MISSING_SIZE_Y,
CREATE_FAILED = MISSING_SIZE_Y << 1 CREATE_FAILED = MISSING_SIZE_Y << 1
+21 -20
View File
@@ -229,26 +229,6 @@ namespace canvas
return _layout_data.has_hfw; return _layout_data.has_hfw;
} }
//----------------------------------------------------------------------------
int BoxLayout::heightForWidth(int w) const
{
if( !hasHeightForWidth() )
return -1;
updateWFHCache(w);
return _hfw_height;
}
//----------------------------------------------------------------------------
int BoxLayout::minimumHeightForWidth(int w) const
{
if( !hasHeightForWidth() )
return -1;
updateWFHCache(w);
return _hfw_min_height;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void BoxLayout::setCanvas(const CanvasWeakPtr& canvas) void BoxLayout::setCanvas(const CanvasWeakPtr& canvas)
{ {
@@ -400,6 +380,27 @@ namespace canvas
return _max_size; return _max_size;
} }
//----------------------------------------------------------------------------
int BoxLayout::heightForWidthImpl(int w) const
{
if( !hasHeightForWidth() )
return -1;
updateWFHCache(w);
return _hfw_height;
}
//----------------------------------------------------------------------------
int BoxLayout::minimumHeightForWidthImpl(int w) const
{
if( !hasHeightForWidth() )
return -1;
updateWFHCache(w);
return _hfw_min_height;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void BoxLayout::doLayout(const SGRecti& geom) void BoxLayout::doLayout(const SGRecti& geom)
{ {
+3 -2
View File
@@ -86,8 +86,6 @@ namespace canvas
Direction direction() const; Direction direction() const;
virtual bool hasHeightForWidth() const; virtual bool hasHeightForWidth() const;
virtual int heightForWidth(int w) const;
virtual int minimumHeightForWidth(int w) const;
virtual void setCanvas(const CanvasWeakPtr& canvas); virtual void setCanvas(const CanvasWeakPtr& canvas);
@@ -121,6 +119,9 @@ namespace canvas
virtual SGVec2i minimumSizeImpl() const; virtual SGVec2i minimumSizeImpl() const;
virtual SGVec2i maximumSizeImpl() const; virtual SGVec2i maximumSizeImpl() const;
virtual int heightForWidthImpl(int w) const;
virtual int minimumHeightForWidthImpl(int w) const;
virtual void doLayout(const SGRecti& geom); virtual void doLayout(const SGRecti& geom);
virtual void visibilityChanged(bool visible); virtual void visibilityChanged(bool visible);
+8 -30
View File
@@ -24,36 +24,6 @@ namespace simgear
namespace canvas namespace canvas
{ {
//----------------------------------------------------------------------------
void Layout::update()
{
if( !(_flags & (LAYOUT_DIRTY | SIZE_INFO_DIRTY)) || !isVisible() )
return;
doLayout(_geometry);
_flags &= ~LAYOUT_DIRTY;
}
//----------------------------------------------------------------------------
void Layout::invalidate()
{
LayoutItem::invalidate();
_flags |= LAYOUT_DIRTY;
}
//----------------------------------------------------------------------------
void Layout::setGeometry(const SGRecti& geom)
{
if( geom != _geometry )
{
_geometry = geom;
_flags |= LAYOUT_DIRTY;
}
update();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Layout::removeItem(const LayoutItemRef& item) void Layout::removeItem(const LayoutItemRef& item)
{ {
@@ -108,6 +78,14 @@ namespace canvas
return layout_item->minimumSize().y(); return layout_item->minimumSize().y();
} }
//----------------------------------------------------------------------------
void Layout::contentsRectChanged(const SGRecti& rect)
{
doLayout(rect);
_flags &= ~LAYOUT_DIRTY;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Layout::distribute(std::vector<ItemData>& items, const ItemData& space) void Layout::distribute(std::vector<ItemData>& items, const ItemData& space)
{ {
+3 -7
View File
@@ -31,11 +31,6 @@ namespace canvas
public LayoutItem public LayoutItem
{ {
public: public:
void update();
virtual void invalidate();
virtual void setGeometry(const SGRecti& geom);
virtual void addItem(const LayoutItemRef& item) = 0; virtual void addItem(const LayoutItemRef& item) = 0;
virtual void setSpacing(int spacing) = 0; virtual void setSpacing(int spacing) = 0;
virtual int spacing() const = 0; virtual int spacing() const = 0;
@@ -74,8 +69,7 @@ namespace canvas
protected: protected:
enum LayoutFlags enum LayoutFlags
{ {
LAYOUT_DIRTY = LayoutItem::LAST_FLAG << 1, LAST_FLAG = LayoutItem::LAST_FLAG
LAST_FLAG = LAYOUT_DIRTY
}; };
struct ItemData struct ItemData
@@ -99,6 +93,8 @@ namespace canvas
int mhfw(int w) const; int mhfw(int w) const;
}; };
virtual void contentsRectChanged(const SGRecti& rect);
/** /**
* Override to implement the actual layouting * Override to implement the actual layouting
*/ */
+120 -7
View File
@@ -23,6 +23,54 @@ namespace simgear
{ {
namespace canvas namespace canvas
{ {
//----------------------------------------------------------------------------
Margins::Margins(int m):
l(m), t(m), r(m), b(m)
{
}
//----------------------------------------------------------------------------
Margins::Margins(int h, int v):
l(h), t(v),
r(h), b(v)
{
}
//----------------------------------------------------------------------------
Margins::Margins(int l, int t, int r, int b):
l(l), t(t), r(r), b(b)
{
}
//----------------------------------------------------------------------------
int Margins::horiz() const
{
return l + r;
}
//----------------------------------------------------------------------------
int Margins::vert() const
{
return t + b;
}
//----------------------------------------------------------------------------
SGVec2i Margins::size() const
{
return SGVec2i(horiz(), vert());
}
//----------------------------------------------------------------------------
bool Margins::isNull() const
{
return l == 0 && t == 0 && r == 0 && b == 0;
}
//----------------------------------------------------------------------------
const SGVec2i LayoutItem::MAX_SIZE( SGLimits<int>::max(), const SGVec2i LayoutItem::MAX_SIZE( SGLimits<int>::max(),
SGLimits<int>::max() ); SGLimits<int>::max() );
@@ -42,6 +90,44 @@ namespace canvas
} }
//----------------------------------------------------------------------------
void LayoutItem::setContentsMargins(const Margins& margins)
{
_margins = margins;
}
//----------------------------------------------------------------------------
void LayoutItem::setContentsMargins(int left, int top, int right, int bottom)
{
_margins.l = left;
_margins.t = top;
_margins.r = right;
_margins.b = bottom;
}
//----------------------------------------------------------------------------
void LayoutItem::setContentsMargin(int margin)
{
setContentsMargins(margin, margin, margin, margin);
}
//----------------------------------------------------------------------------
Margins LayoutItem::getContentsMargins() const
{
return _margins;
}
//----------------------------------------------------------------------------
SGRecti LayoutItem::contentsRect() const
{
return SGRecti(
_geometry.x() + _margins.l,
_geometry.y() + _margins.t,
std::max(0, _geometry.width() - _margins.horiz()),
std::max(0, _geometry.height() - _margins.vert())
);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
SGVec2i LayoutItem::sizeHint() const SGVec2i LayoutItem::sizeHint() const
{ {
@@ -51,7 +137,7 @@ namespace canvas
_flags &= ~SIZE_HINT_DIRTY; _flags &= ~SIZE_HINT_DIRTY;
} }
return _size_hint; return addClipOverflow(_size_hint, _margins.size());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -63,7 +149,7 @@ namespace canvas
_flags &= ~MINIMUM_SIZE_DIRTY; _flags &= ~MINIMUM_SIZE_DIRTY;
} }
return _min_size; return addClipOverflow(_min_size, _margins.size());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -75,7 +161,7 @@ namespace canvas
_flags &= ~MAXIMUM_SIZE_DIRTY; _flags &= ~MAXIMUM_SIZE_DIRTY;
} }
return _max_size; return addClipOverflow(_max_size, _margins.size());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -87,13 +173,15 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int LayoutItem::heightForWidth(int w) const int LayoutItem::heightForWidth(int w) const
{ {
return -1; int h = heightForWidthImpl(w - _margins.horiz());
return h < 0 ? -1 : SGMisc<int>::addClipOverflow(h, _margins.vert());
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int LayoutItem::minimumHeightForWidth(int w) const int LayoutItem::minimumHeightForWidth(int w) const
{ {
return heightForWidth(w); int h = minimumHeightForWidthImpl(w - _margins.horiz());
return h < 0 ? -1 : SGMisc<int>::addClipOverflow(h, _margins.vert());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -122,7 +210,7 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void LayoutItem::invalidate() void LayoutItem::invalidate()
{ {
_flags |= SIZE_INFO_DIRTY; _flags |= SIZE_INFO_DIRTY | LAYOUT_DIRTY;
invalidateParent(); invalidateParent();
} }
@@ -134,10 +222,23 @@ namespace canvas
parent->invalidate(); parent->invalidate();
} }
//----------------------------------------------------------------------------
void LayoutItem::update()
{
if( (_flags & LAYOUT_DIRTY) && isVisible() )
contentsRectChanged( contentsRect() );
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void LayoutItem::setGeometry(const SGRecti& geom) void LayoutItem::setGeometry(const SGRecti& geom)
{ {
_geometry = geom; if( geom != _geometry )
{
_geometry = geom;
_flags |= LAYOUT_DIRTY;
}
update();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -197,6 +298,18 @@ namespace canvas
return _max_size; return _max_size;
} }
//----------------------------------------------------------------------------
int LayoutItem::heightForWidthImpl(int w) const
{
return -1;
}
//------------------------------------------------------------------------------
int LayoutItem::minimumHeightForWidthImpl(int w) const
{
return heightForWidth(w);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void LayoutItem::setVisibleInternal(bool visible) void LayoutItem::setVisibleInternal(bool visible)
{ {
+160 -4
View File
@@ -34,6 +34,53 @@ namespace canvas
typedef SGSharedPtr<LayoutItem> LayoutItemRef; typedef SGSharedPtr<LayoutItem> LayoutItemRef;
typedef SGWeakPtr<LayoutItem> LayoutItemWeakRef; typedef SGWeakPtr<LayoutItem> LayoutItemWeakRef;
/**
* Holds the four margins for a rectangle.
*/
struct Margins
{
int l, t, r, b;
/**
* Set all margins to the same value @a m.
*/
explicit Margins(int m = 0);
/**
* Set horizontal and vertical margins to the same values @a h and @a v
* respectively.
*
* @param h Horizontal margins
* @param v Vertical margins
*/
Margins(int h, int v);
/**
* Set the margins to the given values.
*/
Margins(int left, int top, int right, int bottom);
/**
* Get the total horizontal margin (sum of left and right margin).
*/
int horiz() const;
/**
* Get the total vertical margin (sum of top and bottom margin).
*/
int vert() const;
/**
* Get total horizontal and vertical margin as vector.
*/
SGVec2i size() const;
/**
* Returns true if all margins are 0.
*/
bool isNull() const;
};
/** /**
* Base class for all layouting elements. Specializations either implement a * Base class for all layouting elements. Specializations either implement a
* layouting algorithm or a widget. * layouting algorithm or a widget.
@@ -49,6 +96,49 @@ namespace canvas
LayoutItem(); LayoutItem();
virtual ~LayoutItem(); virtual ~LayoutItem();
/**
* Set the margins to use by the layout system around the item.
*
* The margins define the size of the clear area around an item. It
* increases the size hints and reduces the size of the geometry()
* available to child layouts and widgets.
*
* @see Margins
*/
void setContentsMargins(const Margins& margins);
/**
* Set the individual margins.
*
* @see setContentsMargins(const Margins&)
*/
void setContentsMargins(int left, int top, int right, int bottom);
/**
* Set all margins to the same value.
*
* @see setContentsMargins(const Margins&)
*/
void setContentsMargin(int margin);
/**
* Get the currently used margins.
*
* @see setContentsMargins(const Margins&)
* @see Margins
*/
Margins getContentsMargins() const;
/**
* Get the area available to the contents.
*
* This is equal to the geometry() reduced by the sizes of the margins.
*
* @see setContentsMargins(const Margins&)
* @see geometry()
*/
SGRecti contentsRect() const;
/** /**
* Get the preferred size of this item. * Get the preferred size of this item.
*/ */
@@ -64,9 +154,36 @@ namespace canvas
*/ */
SGVec2i maximumSize() const; SGVec2i maximumSize() const;
/**
* Returns true if this items preferred and minimum height depend on its
* width.
*
* The default implementation returns false. Reimplement for items
* providing height for width.
*
* @see heightForWidth()
* @see minimumHeightForWidth()
*/
virtual bool hasHeightForWidth() const; virtual bool hasHeightForWidth() const;
virtual int heightForWidth(int w) const;
virtual int minimumHeightForWidth(int w) const; /**
* Returns the preferred height for the given width @q w.
*
* Reimplement heightForWidthImpl() for items providing height for width.
*
* @see hasHeightForWidth()
*/
int heightForWidth(int w) const;
/**
* Returns the minimum height for the given width @q w.
*
* Reimplement minimumHeightForWidthImpl() for items providing height for
* width.
*
* @see hasHeightForWidth()
*/
int minimumHeightForWidth(int w) const;
virtual void setVisible(bool visible); virtual void setVisible(bool visible);
virtual bool isVisible() const; virtual bool isVisible() const;
@@ -82,10 +199,15 @@ namespace canvas
virtual void invalidate(); virtual void invalidate();
/** /**
* Mark all cached data of parent item as invalid (if it is known) * Mark all cached data of parent item as invalid (if the parent is set).
*/ */
void invalidateParent(); void invalidateParent();
/**
* Apply any changes not applied yet.
*/
void update();
/** /**
* Set position and size of this element. For layouts this triggers a * Set position and size of this element. For layouts this triggers a
* recalculation of the layout. * recalculation of the layout.
@@ -134,13 +256,15 @@ namespace canvas
| MAXIMUM_SIZE_DIRTY, | MAXIMUM_SIZE_DIRTY,
EXPLICITLY_HIDDEN = MAXIMUM_SIZE_DIRTY << 1, EXPLICITLY_HIDDEN = MAXIMUM_SIZE_DIRTY << 1,
VISIBLE = EXPLICITLY_HIDDEN << 1, VISIBLE = EXPLICITLY_HIDDEN << 1,
LAST_FLAG = VISIBLE LAYOUT_DIRTY = VISIBLE << 1,
LAST_FLAG = LAYOUT_DIRTY
}; };
CanvasWeakPtr _canvas; CanvasWeakPtr _canvas;
LayoutItemWeakRef _parent; LayoutItemWeakRef _parent;
SGRecti _geometry; SGRecti _geometry;
Margins _margins;
mutable uint32_t _flags; mutable uint32_t _flags;
mutable SGVec2i _size_hint, mutable SGVec2i _size_hint,
@@ -151,11 +275,43 @@ namespace canvas
virtual SGVec2i minimumSizeImpl() const; virtual SGVec2i minimumSizeImpl() const;
virtual SGVec2i maximumSizeImpl() const; virtual SGVec2i maximumSizeImpl() const;
/**
* Returns the preferred height for the given width @q w.
*
* The default implementation returns -1, indicating that the preferred
* height is independent of the given width.
*
* Reimplement this function for items supporting height for width.
*
* @note Do not take margins into account, as this is already handled
* before calling this function.
*
* @see hasHeightForWidth()
*/
virtual int heightForWidthImpl(int w) const;
/**
* Returns the minimum height for the given width @q w.
*
* The default implementation returns -1, indicating that the minimum
* height is independent of the given width.
*
* Reimplement this function for items supporting height for width.
*
* @note Do not take margins into account, as this is already handled
* before calling this function.
*
* @see hasHeightForWidth()
*/
virtual int minimumHeightForWidthImpl(int w) const;
/** /**
* @return whether the visibility has changed. * @return whether the visibility has changed.
*/ */
void setVisibleInternal(bool visible); void setVisibleInternal(bool visible);
virtual void contentsRectChanged(const SGRecti& rect) {};
virtual void visibilityChanged(bool visible) {} virtual void visibilityChanged(bool visible) {}
/** /**
+40 -51
View File
@@ -46,41 +46,6 @@ namespace canvas
onRemove(); onRemove();
} }
//----------------------------------------------------------------------------
void NasalWidget::invalidate()
{
LayoutItem::invalidate();
_flags |= LAYOUT_DIRTY;
}
//----------------------------------------------------------------------------
void NasalWidget::setGeometry(const SGRect<int>& geom)
{
if( _geometry != geom )
{
_geometry = geom;
_flags |= LAYOUT_DIRTY;
}
if( !_set_geometry || !(_flags & LAYOUT_DIRTY) )
return;
try
{
nasal::Context c;
_set_geometry(nasal::to_nasal(c, this), geom);
_flags &= ~LAYOUT_DIRTY;
}
catch( std::exception const& ex )
{
SG_LOG(
SG_GUI,
SG_WARN,
"NasalWidget::setGeometry: callback error: '" << ex.what() << "'"
);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void NasalWidget::onRemove() void NasalWidget::onRemove()
{ {
@@ -186,22 +151,6 @@ namespace canvas
return !_height_for_width.empty() || !_min_height_for_width.empty(); return !_height_for_width.empty() || !_min_height_for_width.empty();
} }
//----------------------------------------------------------------------------
int NasalWidget::heightForWidth(int w) const
{
return callHeightForWidthFunc( _height_for_width.empty()
? _min_height_for_width
: _height_for_width, w );
}
//----------------------------------------------------------------------------
int NasalWidget::minimumHeightForWidth(int w) const
{
return callHeightForWidthFunc( _min_height_for_width.empty()
? _height_for_width
: _min_height_for_width, w );
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static naRef f_makeNasalWidget(const nasal::CallContext& ctx) static naRef f_makeNasalWidget(const nasal::CallContext& ctx)
{ {
@@ -285,6 +234,46 @@ namespace canvas
); );
} }
//----------------------------------------------------------------------------
int NasalWidget::heightForWidthImpl(int w) const
{
return callHeightForWidthFunc( _height_for_width.empty()
? _min_height_for_width
: _height_for_width, w );
}
//----------------------------------------------------------------------------
int NasalWidget::minimumHeightForWidthImpl(int w) const
{
return callHeightForWidthFunc( _min_height_for_width.empty()
? _height_for_width
: _min_height_for_width, w );
}
//----------------------------------------------------------------------------
void NasalWidget::contentsRectChanged(const SGRect<int>& rect)
{
if( !_set_geometry )
return;
try
{
nasal::Context c;
_set_geometry(nasal::to_nasal(c, this), rect);
_flags &= ~LAYOUT_DIRTY;
}
catch( std::exception const& ex )
{
SG_LOG(
SG_GUI,
SG_WARN,
"NasalWidget::setGeometry: callback error: '" << ex.what() << "'"
);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void NasalWidget::visibilityChanged(bool visible) void NasalWidget::visibilityChanged(bool visible)
{ {
+5 -4
View File
@@ -51,8 +51,6 @@ namespace canvas
~NasalWidget(); ~NasalWidget();
virtual void invalidate();
virtual void setGeometry(const SGRecti& geom);
virtual void onRemove(); virtual void onRemove();
void setSetGeometryFunc(const SetGeometryFunc& func); void setSetGeometryFunc(const SetGeometryFunc& func);
@@ -85,8 +83,6 @@ namespace canvas
void setLayoutMaximumSize(const SGVec2i& s); void setLayoutMaximumSize(const SGVec2i& s);
virtual bool hasHeightForWidth() const; virtual bool hasHeightForWidth() const;
virtual int heightForWidth(int w) const;
virtual int minimumHeightForWidth(int w) const;
/** /**
* @param ns Namespace to register the class interface * @param ns Namespace to register the class interface
@@ -118,6 +114,11 @@ namespace canvas
virtual SGVec2i minimumSizeImpl() const; virtual SGVec2i minimumSizeImpl() const;
virtual SGVec2i maximumSizeImpl() const; virtual SGVec2i maximumSizeImpl() const;
virtual int heightForWidthImpl(int w) const;
virtual int minimumHeightForWidthImpl(int w) const;
virtual void contentsRectChanged(const SGRecti& rect);
virtual void visibilityChanged(bool visible); virtual void visibilityChanged(bool visible);
}; };
+94 -8
View File
@@ -64,13 +64,8 @@ class TestWidget:
void setMaxSize(const SGVec2i& size) { _max_size = size; } void setMaxSize(const SGVec2i& size) { _max_size = size; }
void setSizeHint(const SGVec2i& size) { _size_hint = size; } void setSizeHint(const SGVec2i& size) { _size_hint = size; }
virtual void setGeometry(const SGRecti& geom) { _geom = geom; }
virtual SGRecti geometry() const { return _geom; }
protected: protected:
SGRecti _geom;
virtual SGVec2i sizeHintImpl() const { return _size_hint; } virtual SGVec2i sizeHintImpl() const { return _size_hint; }
virtual SGVec2i minimumSizeImpl() const { return _min_size; } virtual SGVec2i minimumSizeImpl() const { return _min_size; }
virtual SGVec2i maximumSizeImpl() const { return _max_size; } virtual SGVec2i maximumSizeImpl() const { return _max_size; }
@@ -78,7 +73,7 @@ class TestWidget:
virtual void visibilityChanged(bool visible) virtual void visibilityChanged(bool visible)
{ {
if( !visible ) if( !visible )
_geom.set(0, 0, 0, 0); _geometry.set(0, 0, 0, 0);
} }
}; };
@@ -99,12 +94,12 @@ class TestWidgetHFW:
return true; return true;
} }
virtual int heightForWidth(int w) const virtual int heightForWidthImpl(int w) const
{ {
return _size_hint.x() * _size_hint.y() / w; return _size_hint.x() * _size_hint.y() / w;
} }
virtual int minimumHeightForWidth(int w) const virtual int minimumHeightForWidthImpl(int w) const
{ {
return _min_size.x() * _min_size.y() / w; return _min_size.x() * _min_size.y() / w;
} }
@@ -411,6 +406,96 @@ BOOST_AUTO_TEST_CASE( boxlayout_visibility )
BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(50, 0, 19, 32)); BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(50, 0, 19, 32));
} }
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( boxlayout_contents_margins )
{
sc::Margins m;
BOOST_REQUIRE(m.isNull());
m = sc::Margins(5);
BOOST_REQUIRE_EQUAL(m.l, 5);
BOOST_REQUIRE_EQUAL(m.t, 5);
BOOST_REQUIRE_EQUAL(m.r, 5);
BOOST_REQUIRE_EQUAL(m.b, 5);
m = sc::Margins(6, 7);
BOOST_REQUIRE_EQUAL(m.l, 6);
BOOST_REQUIRE_EQUAL(m.t, 7);
BOOST_REQUIRE_EQUAL(m.r, 6);
BOOST_REQUIRE_EQUAL(m.b, 7);
BOOST_REQUIRE_EQUAL(m.horiz(), 12);
BOOST_REQUIRE_EQUAL(m.vert(), 14);
BOOST_REQUIRE(!m.isNull());
m = sc::Margins(1, 2, 3, 4);
BOOST_REQUIRE_EQUAL(m.l, 1);
BOOST_REQUIRE_EQUAL(m.t, 2);
BOOST_REQUIRE_EQUAL(m.r, 3);
BOOST_REQUIRE_EQUAL(m.b, 4);
BOOST_REQUIRE_EQUAL(m.horiz(), 4);
BOOST_REQUIRE_EQUAL(m.vert(), 6);
BOOST_REQUIRE_EQUAL(m.size(), SGVec2i(4, 6));
sc::BoxLayoutRef hbox( new sc::HBoxLayout );
hbox->setContentsMargins(5, 10, 15, 20);
BOOST_CHECK_EQUAL(hbox->minimumSize(), SGVec2i(20, 30));
BOOST_CHECK_EQUAL(hbox->sizeHint(), SGVec2i(20, 30));
BOOST_CHECK_EQUAL(hbox->maximumSize(), SGVec2i(20, 30));
hbox->setGeometry(SGRecti(0, 0, 30, 40));
BOOST_CHECK_EQUAL(hbox->contentsRect(), SGRecti(5, 10, 10, 10));
TestWidgetRef w1( new TestWidget( SGVec2i(16, 16),
SGVec2i(32, 32) ) ),
w2( new TestWidget(*w1) ),
w3( new TestWidget(*w1) );
w1->setContentsMargin(5);
w2->setContentsMargin(6);
w3->setContentsMargin(7);
BOOST_CHECK_EQUAL(w1->minimumSize(), SGVec2i(26, 26));
BOOST_CHECK_EQUAL(w1->sizeHint(), SGVec2i(42, 42));
BOOST_CHECK_EQUAL(w1->maximumSize(), sc::LayoutItem::MAX_SIZE);
BOOST_CHECK_EQUAL(w2->minimumSize(), SGVec2i(28, 28));
BOOST_CHECK_EQUAL(w2->sizeHint(), SGVec2i(44, 44));
BOOST_CHECK_EQUAL(w2->maximumSize(), sc::LayoutItem::MAX_SIZE);
BOOST_CHECK_EQUAL(w3->minimumSize(), SGVec2i(30, 30));
BOOST_CHECK_EQUAL(w3->sizeHint(), SGVec2i(46, 46));
BOOST_CHECK_EQUAL(w3->maximumSize(), sc::LayoutItem::MAX_SIZE);
hbox->addItem(w1);
hbox->addItem(w2);
hbox->addItem(w3);
BOOST_CHECK_EQUAL(hbox->minimumSize(), SGVec2i(114, 60));
BOOST_CHECK_EQUAL(hbox->sizeHint(), SGVec2i(162, 76));
BOOST_CHECK_EQUAL(hbox->maximumSize(), sc::LayoutItem::MAX_SIZE);
hbox->setGeometry(SGRecti(0, 0, hbox->sizeHint().x(), hbox->sizeHint().y()));
BOOST_CHECK_EQUAL(hbox->contentsRect(), SGRecti(5, 10, 142, 46));
BOOST_CHECK_EQUAL(w1->geometry(), SGRecti(5, 10, 42, 46));
BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(52, 10, 44, 46));
BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(101, 10, 46, 46));
BOOST_CHECK_EQUAL(w1->contentsRect(), SGRecti(10, 15, 32, 36));
BOOST_CHECK_EQUAL(w2->contentsRect(), SGRecti(58, 16, 32, 34));
BOOST_CHECK_EQUAL(w3->contentsRect(), SGRecti(108, 17, 32, 32));
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( boxlayout_hfw ) BOOST_AUTO_TEST_CASE( boxlayout_hfw )
{ {
@@ -502,6 +587,7 @@ BOOST_AUTO_TEST_CASE( boxlayout_hfw )
BOOST_CHECK_EQUAL(w_no_hfw->geometry(), SGRecti(0, 90, 24, 32)); BOOST_CHECK_EQUAL(w_no_hfw->geometry(), SGRecti(0, 90, 24, 32));
} }
//------------------------------------------------------------------------------
// TODO extend to_nasal_helper for automatic argument conversion // TODO extend to_nasal_helper for automatic argument conversion
static naRef f_Widget_visibilityChanged(nasal::CallContext ctx) static naRef f_Widget_visibilityChanged(nasal::CallContext ctx)
{ {