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() );
+
//----------------------------------------------------------------------------
LayoutItem::LayoutItem():
- _flags(0)
+ _flags(VISIBLE),
+ _size_hint(0, 0),
+ _min_size(0, 0),
+ _max_size(MAX_SIZE)
{
invalidate();
}
}
+ //----------------------------------------------------------------------------
+ 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
{
_flags &= ~SIZE_HINT_DIRTY;
}
- return _size_hint;
+ return addClipOverflow(_size_hint, _margins.size());
}
//----------------------------------------------------------------------------
_flags &= ~MINIMUM_SIZE_DIRTY;
}
- return _min_size;
+ return addClipOverflow(_min_size, _margins.size());
}
//----------------------------------------------------------------------------
_flags &= ~MAXIMUM_SIZE_DIRTY;
}
- return _max_size;
+ return addClipOverflow(_max_size, _margins.size());
}
//----------------------------------------------------------------------------
- void LayoutItem::invalidate()
+ bool LayoutItem::hasHeightForWidth() const
{
- _flags |= SIZE_HINT_DIRTY
- | MINIMUM_SIZE_DIRTY
- | MAXIMUM_SIZE_DIRTY;
+ return false;
+ }
+
+ //----------------------------------------------------------------------------
+ int LayoutItem::heightForWidth(int w) const
+ {
+ int h = heightForWidthImpl(w - _margins.horiz());
+ return h < 0 ? -1 : SGMisc<int>::addClipOverflow(h, _margins.vert());
+ }
+
+ //------------------------------------------------------------------------------
+ int LayoutItem::minimumHeightForWidth(int w) const
+ {
+ int h = minimumHeightForWidthImpl(w - _margins.horiz());
+ return h < 0 ? -1 : SGMisc<int>::addClipOverflow(h, _margins.vert());
+ }
+
+ //----------------------------------------------------------------------------
+ void LayoutItem::setVisible(bool visible)
+ {
+ if( visible )
+ _flags &= ~EXPLICITLY_HIDDEN;
+ else
+ _flags |= EXPLICITLY_HIDDEN;
+
+ setVisibleInternal(visible);
+ }
+
+ //----------------------------------------------------------------------------
+ bool LayoutItem::isVisible() const
+ {
+ return _flags & VISIBLE;
+ }
+
+ //----------------------------------------------------------------------------
+ bool LayoutItem::isExplicitlyHidden() const
+ {
+ return _flags & EXPLICITLY_HIDDEN;
+ }
+ //----------------------------------------------------------------------------
+ void LayoutItem::invalidate()
+ {
+ _flags |= SIZE_INFO_DIRTY | LAYOUT_DIRTY;
invalidateParent();
}
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();
}
//----------------------------------------------------------------------------
{
_parent = parent;
LayoutItemRef parent_ref = parent.lock();
- setCanvas(parent_ref ? parent_ref->_canvas : CanvasWeakPtr());
+
+ if( parent_ref )
+ // Only change the canvas if there is a new parent. If the item is removed
+ // keep the old canvas, as it may be used for example during the call to
+ // onRemove.
+ setCanvas(parent_ref->_canvas);
+
+ setVisibleInternal(!parent_ref || parent_ref->isVisible());
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
SGVec2i LayoutItem::sizeHintImpl() const
{
- return SGVec2i(16, 16);
+ return _size_hint;
}
//----------------------------------------------------------------------------
SGVec2i LayoutItem::minimumSizeImpl() const
{
- return SGVec2i(0, 0);
+ return _min_size;
}
//----------------------------------------------------------------------------
SGVec2i LayoutItem::maximumSizeImpl() const
{
- return SGVec2i(SGLimits<int>::max(), SGLimits<int>::max());
+ 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)
+ {
+ LayoutItemRef parent = getParent();
+ if( isExplicitlyHidden() || (parent && !parent->isVisible()) )
+ visible = false;
+
+ if( isVisible() == visible )
+ return;
+
+ invalidateParent();
+
+ if( visible )
+ _flags |= VISIBLE;
+ else
+ _flags &= ~VISIBLE;
+
+ visibilityChanged(visible);
+ }
+
+ //----------------------------------------------------------------------------
+ void LayoutItem::callSetVisibleInternal(LayoutItem* item, bool visible)
+ {
+ item->setVisibleInternal(visible);
}
} // namespace canvas