setDirection(dir);
}
+ //----------------------------------------------------------------------------
+ BoxLayout::~BoxLayout()
+ {
+ _parent.reset(); // No need to invalidate parent again...
+ clear();
+ }
+
//----------------------------------------------------------------------------
void BoxLayout::addItem(const LayoutItemRef& item)
{
item_data.layout_item = item;
item_data.stretch = std::max(0, stretch);
- item->setCanvas(_canvas);
- item->setParent(this);
+ if( SGWeakReferenced::count(this) )
+ item->setParent(this);
+ else
+ SG_LOG( SG_GUI,
+ SG_WARN,
+ "Adding item to expired or non-refcounted layout" );
if( index < 0 )
_layout_items.push_back(item_data);
LayoutItems::iterator it = _layout_items.begin() + index;
LayoutItemRef item = it->layout_item;
+ item->onRemove();
+ item->setParent(LayoutItemWeakRef());
_layout_items.erase(it);
invalidate();
//----------------------------------------------------------------------------
void BoxLayout::clear()
{
+ for( LayoutItems::iterator it = _layout_items.begin();
+ it != _layout_items.end();
+ ++it )
+ {
+ it->layout_item->onRemove();
+ it->layout_item->setParent(LayoutItemWeakRef());
+ }
_layout_items.clear();
invalidate();
}
invalidate();
}
+ //----------------------------------------------------------------------------
+ bool BoxLayout::setStretchFactor(const LayoutItemRef& item, int stretch)
+ {
+ for( LayoutItems::iterator it = _layout_items.begin();
+ it != _layout_items.end();
+ ++it )
+ {
+ if( item == it->layout_item )
+ {
+ it->stretch = std::max(0, stretch);
+ invalidate();
+ return true;
+ }
+ }
+
+ return false;
+ }
+
//----------------------------------------------------------------------------
int BoxLayout::stretch(size_t index) const
{
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)
{
for(size_t i = 0; i < _layout_items.size(); ++i)
{
- // TODO check visible
-
ItemData& item_data = _layout_items[i];
LayoutItem const& item = *item_data.layout_item;
+ item_data.visible = item.isVisible();
+ if( !item_data.visible )
+ continue;
+
item_data.min_size = (item.minimumSize().*_get_layout_coord)();
item_data.max_size = (item.maximumSize().*_get_layout_coord)();
item_data.size_hint = (item.sizeHint().*_get_layout_coord)();
}
// Add sizes of all children in layout direction
- safeAdd(min_size.x(), item_data.min_size);
- safeAdd(max_size.x(), item_data.max_size);
- safeAdd(size_hint.x(), item_data.size_hint);
+ SGMisc<int>::addClipOverflowInplace(min_size.x(), item_data.min_size);
+ SGMisc<int>::addClipOverflowInplace(max_size.x(), item_data.max_size);
+ SGMisc<int>::addClipOverflowInplace(size_hint.x(), item_data.size_hint);
// Take maximum in fixed (non-layouted) direction
min_size.y() = std::max( min_size.y(),
_layout_data.has_hfw = _layout_data.has_hfw || item.hasHeightForWidth();
}
- safeAdd(min_size.x(), _layout_data.padding);
- safeAdd(max_size.x(), _layout_data.padding);
- safeAdd(size_hint.x(), _layout_data.padding);
+ SGMisc<int>::addClipOverflowInplace(min_size.x(), _layout_data.padding);
+ SGMisc<int>::addClipOverflowInplace(max_size.x(), _layout_data.padding);
+ SGMisc<int>::addClipOverflowInplace(size_hint.x(), _layout_data.padding);
_layout_data.min_size = min_size.x();
_layout_data.max_size = max_size.x();
for(size_t i = 0; i < _layout_items.size(); ++i)
{
ItemData const& data = _layout_items[i];
+ if( !data.visible )
+ continue;
+
_hfw_height = std::max(_hfw_height, data.hfw(data.size));
_hfw_min_height = std::max(_hfw_min_height, data.mhfw(data.size));
}
for(size_t i = 0; i < _layout_items.size(); ++i)
{
ItemData const& data = _layout_items[i];
+ if( !data.visible )
+ continue;
+
_hfw_height += data.hfw(w) + data.padding_orig;
_hfw_min_height += data.mhfw(w) + data.padding_orig;
}
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)
{
for(size_t i = 0; i < _layout_items.size(); ++i)
{
ItemData& data = _layout_items[i];
+ if( !data.visible )
+ continue;
+
if( data.has_hfw )
{
int w = SGMisc<int>::clip( geom.width(),
data.layout_item->minimumSize().x(),
data.layout_item->maximumSize().x() );
- int d = data.layout_item->minimumHeightForWidth(w) - data.min_size;
- data.min_size += d;
- _layout_data.min_size += d;
+ data.min_size = data.mhfw(w);
+ data.size_hint = data.hfw(w);
- d = data.layout_item->heightForWidth(w) - data.size_hint;
- data.size_hint += d;
- _layout_data.size_hint += d;
+ // Update size hints for layouting with difference to size hints
+ // calculated by using the size hints provided (without trading
+ // height for width)
+ _layout_data.min_size += data.min_size
+ - data.layout_item->minimumSize().y();
+ _layout_data.size_hint += data.size_hint
+ - data.layout_item->sizeHint().y();
}
}
}
for(size_t i = 0; i < _layout_items.size(); ++i)
{
ItemData const& data = _layout_items[i];
+ if( !data.visible )
+ continue;
+
cur_pos.x() += reverse ? -data.padding - data.size : data.padding;
SGVec2i size(
}
}
+ //----------------------------------------------------------------------------
+ void BoxLayout::visibilityChanged(bool visible)
+ {
+ for(size_t i = 0; i < _layout_items.size(); ++i)
+ callSetVisibleInternal(_layout_items[i].layout_item.get(), visible);
+ }
+
//----------------------------------------------------------------------------
HBoxLayout::HBoxLayout():
BoxLayout(LeftToRight)