canvas::Layout: proper cleanup/update on removing items.

This commit is contained in:
Thomas Geymayer
2014-06-15 16:30:25 +02:00
parent 1225e53162
commit 737b1948bf
10 changed files with 88 additions and 14 deletions
+14
View File
@@ -32,6 +32,13 @@ namespace canvas
setDirection(dir); setDirection(dir);
} }
//----------------------------------------------------------------------------
BoxLayout::~BoxLayout()
{
_parent.reset(); // No need to invalidate parent again...
clear();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void BoxLayout::addItem(const LayoutItemRef& item) void BoxLayout::addItem(const LayoutItemRef& item)
{ {
@@ -114,6 +121,7 @@ namespace canvas
LayoutItems::iterator it = _layout_items.begin() + index; LayoutItems::iterator it = _layout_items.begin() + index;
LayoutItemRef item = it->layout_item; LayoutItemRef item = it->layout_item;
item->onRemove();
_layout_items.erase(it); _layout_items.erase(it);
invalidate(); invalidate();
@@ -124,6 +132,12 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void BoxLayout::clear() void BoxLayout::clear()
{ {
for( LayoutItems::iterator it = _layout_items.begin();
it != _layout_items.end();
++it )
{
it->layout_item->onRemove();
}
_layout_items.clear(); _layout_items.clear();
invalidate(); invalidate();
} }
+1
View File
@@ -40,6 +40,7 @@ namespace canvas
}; };
BoxLayout(Direction dir); BoxLayout(Direction dir);
~BoxLayout();
virtual void addItem(const LayoutItemRef& item); virtual void addItem(const LayoutItemRef& item);
+5 -5
View File
@@ -45,11 +45,11 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Layout::setGeometry(const SGRecti& geom) void Layout::setGeometry(const SGRecti& geom)
{ {
if( geom == _geometry ) if( geom != _geometry )
return; {
_geometry = geom;
_geometry = geom; _flags |= LAYOUT_DIRTY;
_flags |= LAYOUT_DIRTY; }
update(); update();
} }
+1 -4
View File
@@ -99,10 +99,7 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void LayoutItem::invalidate() void LayoutItem::invalidate()
{ {
_flags |= SIZE_HINT_DIRTY _flags |= SIZE_INFO_DIRTY;
| MINIMUM_SIZE_DIRTY
| MAXIMUM_SIZE_DIRTY;
invalidateParent(); invalidateParent();
} }
+3
View File
@@ -108,6 +108,9 @@ namespace canvas
*/ */
LayoutItemRef getParent() const; LayoutItemRef getParent() const;
/// Called before item is removed from a layout
virtual void onRemove() {}
protected: protected:
friend class Canvas; friend class Canvas;
+38 -5
View File
@@ -33,20 +33,26 @@ namespace canvas
} }
//----------------------------------------------------------------------------
void NasalWidget::invalidate()
{
LayoutItem::invalidate();
_flags |= LAYOUT_DIRTY;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void NasalWidget::setGeometry(const SGRect<int>& geom) void NasalWidget::setGeometry(const SGRect<int>& geom)
{ {
if( _geometry == geom ) if( _geometry != geom )
return; _geometry = geom;
_geometry = geom; else if( !(_flags & LAYOUT_DIRTY) || !_set_geometry )
if( !_set_geometry )
return; return;
naContext c = naNewContext(); naContext c = naNewContext();
try try
{ {
_set_geometry(nasal::to_nasal(c, this), geom); _set_geometry(nasal::to_nasal(c, this), geom);
_flags &= ~LAYOUT_DIRTY;
} }
catch( std::exception const& ex ) catch( std::exception const& ex )
{ {
@@ -59,6 +65,33 @@ namespace canvas
naFreeContext(c); 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) void NasalWidget::setSetGeometryFunc(const SetGeometryFunc& func)
{ {
+8
View File
@@ -49,7 +49,9 @@ namespace canvas
*/ */
NasalWidget(naRef impl); NasalWidget(naRef impl);
virtual void invalidate();
virtual void setGeometry(const SGRecti& geom); virtual void setGeometry(const SGRecti& geom);
virtual void onRemove();
void setSetGeometryFunc(const SetGeometryFunc& func); void setSetGeometryFunc(const SetGeometryFunc& func);
void setHeightForWidthFunc(const HeightForWidthFunc& func); void setHeightForWidthFunc(const HeightForWidthFunc& func);
@@ -69,6 +71,12 @@ namespace canvas
static void setupGhost(nasal::Hash& ns); static void setupGhost(nasal::Hash& ns);
protected: protected:
enum WidgetFlags
{
LAYOUT_DIRTY = LayoutItem::LAST_FLAG << 1,
LAST_FLAG = LAYOUT_DIRTY
};
SetGeometryFunc _set_geometry; SetGeometryFunc _set_geometry;
HeightForWidthFunc _height_for_width, HeightForWidthFunc _height_for_width,
_min_height_for_width; _min_height_for_width;
+6
View File
@@ -41,6 +41,12 @@ namespace nasal
return _nasal_impl.get_naRef(); return _nasal_impl.get_naRef();
} }
//----------------------------------------------------------------------------
bool Object::valid() const
{
return _nasal_impl.valid();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Object::_set(naContext c, const std::string& key, naRef val) bool Object::_set(naContext c, const std::string& key, naRef val)
{ {
+2
View File
@@ -39,6 +39,8 @@ namespace nasal
void setImpl(naRef obj); void setImpl(naRef obj);
naRef getImpl() const; naRef getImpl() const;
bool valid() const;
bool _set(naContext c, const std::string& key, naRef val); bool _set(naContext c, const std::string& key, naRef val);
bool _get(naContext c, const std::string& key, naRef& out); bool _get(naContext c, const std::string& key, naRef& out);
+10
View File
@@ -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 } // namespace nasal
#endif /* SG_FROM_NASAL_HXX_ */ #endif /* SG_FROM_NASAL_HXX_ */