canvas::Layout: support for contents margins.
This commit is contained in:
@@ -196,7 +196,6 @@ namespace canvas
|
||||
{
|
||||
_layout = layout;
|
||||
_layout->setCanvas(this);
|
||||
_status |= LAYOUT_DIRTY;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -256,15 +255,7 @@ namespace canvas
|
||||
}
|
||||
|
||||
if( _layout )
|
||||
{
|
||||
if( (_status & LAYOUT_DIRTY) )
|
||||
{
|
||||
_layout->setGeometry(SGRecti(0, 0, _view_width, _view_height));
|
||||
_status &= ~LAYOUT_DIRTY;
|
||||
}
|
||||
else
|
||||
_layout->update();
|
||||
}
|
||||
_layout->setGeometry(SGRecti(0, 0, _view_width, _view_height));
|
||||
|
||||
if( _visible || _render_always )
|
||||
{
|
||||
@@ -410,7 +401,6 @@ namespace canvas
|
||||
if( _view_width == w )
|
||||
return;
|
||||
_view_width = w;
|
||||
_status |= LAYOUT_DIRTY;
|
||||
|
||||
_texture.setViewSize(_view_width, _view_height);
|
||||
}
|
||||
@@ -421,7 +411,6 @@ namespace canvas
|
||||
if( _view_height == h )
|
||||
return;
|
||||
_view_height = h;
|
||||
_status |= LAYOUT_DIRTY;
|
||||
|
||||
_texture.setViewSize(_view_width, _view_height);
|
||||
}
|
||||
|
||||
@@ -53,8 +53,7 @@ namespace canvas
|
||||
{
|
||||
STATUS_OK,
|
||||
STATUS_DIRTY = 1,
|
||||
LAYOUT_DIRTY = STATUS_DIRTY << 1,
|
||||
MISSING_SIZE_X = LAYOUT_DIRTY << 1,
|
||||
MISSING_SIZE_X = STATUS_DIRTY << 1,
|
||||
MISSING_SIZE_Y = MISSING_SIZE_X << 1,
|
||||
MISSING_SIZE = MISSING_SIZE_X | MISSING_SIZE_Y,
|
||||
CREATE_FAILED = MISSING_SIZE_Y << 1
|
||||
|
||||
@@ -229,26 +229,6 @@ namespace canvas
|
||||
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)
|
||||
{
|
||||
@@ -400,6 +380,27 @@ namespace canvas
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -86,8 +86,6 @@ namespace canvas
|
||||
Direction direction() const;
|
||||
|
||||
virtual bool hasHeightForWidth() const;
|
||||
virtual int heightForWidth(int w) const;
|
||||
virtual int minimumHeightForWidth(int w) const;
|
||||
|
||||
virtual void setCanvas(const CanvasWeakPtr& canvas);
|
||||
|
||||
@@ -121,6 +119,9 @@ namespace canvas
|
||||
virtual SGVec2i minimumSizeImpl() 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 visibilityChanged(bool visible);
|
||||
|
||||
@@ -24,36 +24,6 @@ namespace simgear
|
||||
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)
|
||||
{
|
||||
@@ -108,6 +78,14 @@ namespace canvas
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -31,11 +31,6 @@ namespace canvas
|
||||
public LayoutItem
|
||||
{
|
||||
public:
|
||||
void update();
|
||||
|
||||
virtual void invalidate();
|
||||
virtual void setGeometry(const SGRecti& geom);
|
||||
|
||||
virtual void addItem(const LayoutItemRef& item) = 0;
|
||||
virtual void setSpacing(int spacing) = 0;
|
||||
virtual int spacing() const = 0;
|
||||
@@ -74,8 +69,7 @@ namespace canvas
|
||||
protected:
|
||||
enum LayoutFlags
|
||||
{
|
||||
LAYOUT_DIRTY = LayoutItem::LAST_FLAG << 1,
|
||||
LAST_FLAG = LAYOUT_DIRTY
|
||||
LAST_FLAG = LayoutItem::LAST_FLAG
|
||||
};
|
||||
|
||||
struct ItemData
|
||||
@@ -99,6 +93,8 @@ namespace canvas
|
||||
int mhfw(int w) const;
|
||||
};
|
||||
|
||||
virtual void contentsRectChanged(const SGRecti& rect);
|
||||
|
||||
/**
|
||||
* Override to implement the actual layouting
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,54 @@ namespace simgear
|
||||
{
|
||||
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(),
|
||||
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
|
||||
{
|
||||
@@ -51,7 +137,7 @@ namespace canvas
|
||||
_flags &= ~SIZE_HINT_DIRTY;
|
||||
}
|
||||
|
||||
return _size_hint;
|
||||
return addClipOverflow(_size_hint, _margins.size());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -63,7 +149,7 @@ namespace canvas
|
||||
_flags &= ~MINIMUM_SIZE_DIRTY;
|
||||
}
|
||||
|
||||
return _min_size;
|
||||
return addClipOverflow(_min_size, _margins.size());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -75,7 +161,7 @@ namespace canvas
|
||||
_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
|
||||
{
|
||||
return -1;
|
||||
int h = heightForWidthImpl(w - _margins.horiz());
|
||||
return h < 0 ? -1 : SGMisc<int>::addClipOverflow(h, _margins.vert());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
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()
|
||||
{
|
||||
_flags |= SIZE_INFO_DIRTY;
|
||||
_flags |= SIZE_INFO_DIRTY | LAYOUT_DIRTY;
|
||||
invalidateParent();
|
||||
}
|
||||
|
||||
@@ -134,10 +222,23 @@ namespace canvas
|
||||
parent->invalidate();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void LayoutItem::update()
|
||||
{
|
||||
if( (_flags & LAYOUT_DIRTY) && isVisible() )
|
||||
contentsRectChanged( contentsRect() );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int LayoutItem::heightForWidthImpl(int w) const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int LayoutItem::minimumHeightForWidthImpl(int w) const
|
||||
{
|
||||
return heightForWidth(w);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void LayoutItem::setVisibleInternal(bool visible)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,53 @@ namespace canvas
|
||||
typedef SGSharedPtr<LayoutItem> LayoutItemRef;
|
||||
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
|
||||
* layouting algorithm or a widget.
|
||||
@@ -49,6 +96,49 @@ namespace canvas
|
||||
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.
|
||||
*/
|
||||
@@ -64,9 +154,36 @@ namespace canvas
|
||||
*/
|
||||
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 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 bool isVisible() const;
|
||||
@@ -82,10 +199,15 @@ namespace canvas
|
||||
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();
|
||||
|
||||
/**
|
||||
* Apply any changes not applied yet.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Set position and size of this element. For layouts this triggers a
|
||||
* recalculation of the layout.
|
||||
@@ -134,13 +256,15 @@ namespace canvas
|
||||
| MAXIMUM_SIZE_DIRTY,
|
||||
EXPLICITLY_HIDDEN = MAXIMUM_SIZE_DIRTY << 1,
|
||||
VISIBLE = EXPLICITLY_HIDDEN << 1,
|
||||
LAST_FLAG = VISIBLE
|
||||
LAYOUT_DIRTY = VISIBLE << 1,
|
||||
LAST_FLAG = LAYOUT_DIRTY
|
||||
};
|
||||
|
||||
CanvasWeakPtr _canvas;
|
||||
LayoutItemWeakRef _parent;
|
||||
|
||||
SGRecti _geometry;
|
||||
Margins _margins;
|
||||
|
||||
mutable uint32_t _flags;
|
||||
mutable SGVec2i _size_hint,
|
||||
@@ -151,11 +275,43 @@ namespace canvas
|
||||
virtual SGVec2i minimumSizeImpl() 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.
|
||||
*/
|
||||
void setVisibleInternal(bool visible);
|
||||
|
||||
virtual void contentsRectChanged(const SGRecti& rect) {};
|
||||
|
||||
virtual void visibilityChanged(bool visible) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,41 +46,6 @@ namespace canvas
|
||||
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()
|
||||
{
|
||||
@@ -186,22 +151,6 @@ namespace canvas
|
||||
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)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -51,8 +51,6 @@ namespace canvas
|
||||
|
||||
~NasalWidget();
|
||||
|
||||
virtual void invalidate();
|
||||
virtual void setGeometry(const SGRecti& geom);
|
||||
virtual void onRemove();
|
||||
|
||||
void setSetGeometryFunc(const SetGeometryFunc& func);
|
||||
@@ -85,8 +83,6 @@ namespace canvas
|
||||
void setLayoutMaximumSize(const SGVec2i& s);
|
||||
|
||||
virtual bool hasHeightForWidth() const;
|
||||
virtual int heightForWidth(int w) const;
|
||||
virtual int minimumHeightForWidth(int w) const;
|
||||
|
||||
/**
|
||||
* @param ns Namespace to register the class interface
|
||||
@@ -118,6 +114,11 @@ namespace canvas
|
||||
virtual SGVec2i minimumSizeImpl() 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);
|
||||
|
||||
};
|
||||
|
||||
@@ -64,13 +64,8 @@ class TestWidget:
|
||||
void setMaxSize(const SGVec2i& size) { _max_size = size; }
|
||||
void setSizeHint(const SGVec2i& size) { _size_hint = size; }
|
||||
|
||||
virtual void setGeometry(const SGRecti& geom) { _geom = geom; }
|
||||
virtual SGRecti geometry() const { return _geom; }
|
||||
|
||||
protected:
|
||||
|
||||
SGRecti _geom;
|
||||
|
||||
virtual SGVec2i sizeHintImpl() const { return _size_hint; }
|
||||
virtual SGVec2i minimumSizeImpl() const { return _min_size; }
|
||||
virtual SGVec2i maximumSizeImpl() const { return _max_size; }
|
||||
@@ -78,7 +73,7 @@ class TestWidget:
|
||||
virtual void visibilityChanged(bool visible)
|
||||
{
|
||||
if( !visible )
|
||||
_geom.set(0, 0, 0, 0);
|
||||
_geometry.set(0, 0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -99,12 +94,12 @@ class TestWidgetHFW:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual int heightForWidth(int w) const
|
||||
virtual int heightForWidthImpl(int w) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -411,6 +406,96 @@ BOOST_AUTO_TEST_CASE( boxlayout_visibility )
|
||||
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 )
|
||||
{
|
||||
@@ -502,6 +587,7 @@ BOOST_AUTO_TEST_CASE( boxlayout_hfw )
|
||||
BOOST_CHECK_EQUAL(w_no_hfw->geometry(), SGRecti(0, 90, 24, 32));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TODO extend to_nasal_helper for automatic argument conversion
|
||||
static naRef f_Widget_visibilityChanged(nasal::CallContext ctx)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user