canvas::Layout: support for contents margins.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user