canvas::Layout: proper cleanup/update on removing items.
This commit is contained in:
@@ -32,6 +32,13 @@ namespace canvas
|
||||
setDirection(dir);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
BoxLayout::~BoxLayout()
|
||||
{
|
||||
_parent.reset(); // No need to invalidate parent again...
|
||||
clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void BoxLayout::addItem(const LayoutItemRef& item)
|
||||
{
|
||||
@@ -114,6 +121,7 @@ namespace canvas
|
||||
|
||||
LayoutItems::iterator it = _layout_items.begin() + index;
|
||||
LayoutItemRef item = it->layout_item;
|
||||
item->onRemove();
|
||||
_layout_items.erase(it);
|
||||
|
||||
invalidate();
|
||||
@@ -124,6 +132,12 @@ namespace canvas
|
||||
//----------------------------------------------------------------------------
|
||||
void BoxLayout::clear()
|
||||
{
|
||||
for( LayoutItems::iterator it = _layout_items.begin();
|
||||
it != _layout_items.end();
|
||||
++it )
|
||||
{
|
||||
it->layout_item->onRemove();
|
||||
}
|
||||
_layout_items.clear();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace canvas
|
||||
};
|
||||
|
||||
BoxLayout(Direction dir);
|
||||
~BoxLayout();
|
||||
|
||||
virtual void addItem(const LayoutItemRef& item);
|
||||
|
||||
|
||||
@@ -45,11 +45,11 @@ namespace canvas
|
||||
//----------------------------------------------------------------------------
|
||||
void Layout::setGeometry(const SGRecti& geom)
|
||||
{
|
||||
if( geom == _geometry )
|
||||
return;
|
||||
|
||||
_geometry = geom;
|
||||
_flags |= LAYOUT_DIRTY;
|
||||
if( geom != _geometry )
|
||||
{
|
||||
_geometry = geom;
|
||||
_flags |= LAYOUT_DIRTY;
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -99,10 +99,7 @@ namespace canvas
|
||||
//----------------------------------------------------------------------------
|
||||
void LayoutItem::invalidate()
|
||||
{
|
||||
_flags |= SIZE_HINT_DIRTY
|
||||
| MINIMUM_SIZE_DIRTY
|
||||
| MAXIMUM_SIZE_DIRTY;
|
||||
|
||||
_flags |= SIZE_INFO_DIRTY;
|
||||
invalidateParent();
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,9 @@ namespace canvas
|
||||
*/
|
||||
LayoutItemRef getParent() const;
|
||||
|
||||
/// Called before item is removed from a layout
|
||||
virtual void onRemove() {}
|
||||
|
||||
protected:
|
||||
|
||||
friend class Canvas;
|
||||
|
||||
@@ -33,20 +33,26 @@ namespace canvas
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void NasalWidget::invalidate()
|
||||
{
|
||||
LayoutItem::invalidate();
|
||||
_flags |= LAYOUT_DIRTY;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void NasalWidget::setGeometry(const SGRect<int>& geom)
|
||||
{
|
||||
if( _geometry == geom )
|
||||
return;
|
||||
_geometry = geom;
|
||||
|
||||
if( !_set_geometry )
|
||||
if( _geometry != geom )
|
||||
_geometry = geom;
|
||||
else if( !(_flags & LAYOUT_DIRTY) || !_set_geometry )
|
||||
return;
|
||||
|
||||
naContext c = naNewContext();
|
||||
try
|
||||
{
|
||||
_set_geometry(nasal::to_nasal(c, this), geom);
|
||||
_flags &= ~LAYOUT_DIRTY;
|
||||
}
|
||||
catch( std::exception const& ex )
|
||||
{
|
||||
@@ -59,6 +65,33 @@ namespace canvas
|
||||
naFreeContext(c);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void NasalWidget::onRemove()
|
||||
{
|
||||
if( !_nasal_impl.valid() )
|
||||
return;
|
||||
|
||||
typedef boost::function<void(nasal::Me)> Deleter;
|
||||
|
||||
naContext c = naNewContext();
|
||||
try
|
||||
{
|
||||
Deleter del =
|
||||
nasal::get_member<Deleter>(c, _nasal_impl.get_naRef(), "onRemove");
|
||||
if( del )
|
||||
del(_nasal_impl.get_naRef());
|
||||
}
|
||||
catch( std::exception const& ex )
|
||||
{
|
||||
SG_LOG(
|
||||
SG_GUI,
|
||||
SG_WARN,
|
||||
"NasalWidget::onRemove: callback error: '" << ex.what() << "'"
|
||||
);
|
||||
}
|
||||
naFreeContext(c);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void NasalWidget::setSetGeometryFunc(const SetGeometryFunc& func)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,9 @@ namespace canvas
|
||||
*/
|
||||
NasalWidget(naRef impl);
|
||||
|
||||
virtual void invalidate();
|
||||
virtual void setGeometry(const SGRecti& geom);
|
||||
virtual void onRemove();
|
||||
|
||||
void setSetGeometryFunc(const SetGeometryFunc& func);
|
||||
void setHeightForWidthFunc(const HeightForWidthFunc& func);
|
||||
@@ -69,6 +71,12 @@ namespace canvas
|
||||
static void setupGhost(nasal::Hash& ns);
|
||||
|
||||
protected:
|
||||
enum WidgetFlags
|
||||
{
|
||||
LAYOUT_DIRTY = LayoutItem::LAST_FLAG << 1,
|
||||
LAST_FLAG = LAYOUT_DIRTY
|
||||
};
|
||||
|
||||
SetGeometryFunc _set_geometry;
|
||||
HeightForWidthFunc _height_for_width,
|
||||
_min_height_for_width;
|
||||
|
||||
@@ -41,6 +41,12 @@ namespace nasal
|
||||
return _nasal_impl.get_naRef();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool Object::valid() const
|
||||
{
|
||||
return _nasal_impl.valid();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool Object::_set(naContext c, const std::string& key, naRef val)
|
||||
{
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace nasal
|
||||
void setImpl(naRef obj);
|
||||
naRef getImpl() const;
|
||||
|
||||
bool valid() const;
|
||||
|
||||
bool _set(naContext c, const std::string& key, naRef val);
|
||||
bool _get(naContext c, const std::string& key, naRef& out);
|
||||
|
||||
|
||||
@@ -63,6 +63,16 @@ namespace nasal
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T get_member(naContext c, naRef obj, const std::string& name)
|
||||
{
|
||||
naRef out;
|
||||
if( !naMember_get(c, obj, to_nasal(c, name), &out) )
|
||||
return T();
|
||||
|
||||
return from_nasal<T>(c, out);
|
||||
}
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#endif /* SG_FROM_NASAL_HXX_ */
|
||||
|
||||
Reference in New Issue
Block a user