canvas::Layout: proper cleanup/update on removing items.
This commit is contained in:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user