setDirection(dir);
}
+ //----------------------------------------------------------------------------
+ BoxLayout::~BoxLayout()
+ {
+ _parent.reset(); // No need to invalidate parent again...
+ clear();
+ }
+
//----------------------------------------------------------------------------
void BoxLayout::addItem(const LayoutItemRef& item)
{
LayoutItems::iterator it = _layout_items.begin() + index;
LayoutItemRef item = it->layout_item;
+ item->onRemove();
_layout_items.erase(it);
invalidate();
//----------------------------------------------------------------------------
void BoxLayout::clear()
{
+ for( LayoutItems::iterator it = _layout_items.begin();
+ it != _layout_items.end();
+ ++it )
+ {
+ it->layout_item->onRemove();
+ }
_layout_items.clear();
invalidate();
}
};
BoxLayout(Direction dir);
+ ~BoxLayout();
virtual void addItem(const LayoutItemRef& item);
//----------------------------------------------------------------------------
void Layout::setGeometry(const SGRecti& geom)
{
- if( geom == _geometry )
- return;
-
- _geometry = geom;
- _flags |= LAYOUT_DIRTY;
+ if( geom != _geometry )
+ {
+ _geometry = geom;
+ _flags |= LAYOUT_DIRTY;
+ }
update();
}
//----------------------------------------------------------------------------
void LayoutItem::invalidate()
{
- _flags |= SIZE_HINT_DIRTY
- | MINIMUM_SIZE_DIRTY
- | MAXIMUM_SIZE_DIRTY;
-
+ _flags |= SIZE_INFO_DIRTY;
invalidateParent();
}
*/
LayoutItemRef getParent() const;
+ /// Called before item is removed from a layout
+ virtual void onRemove() {}
+
protected:
friend class Canvas;
}
//----------------------------------------------------------------------------
- void NasalWidget::setGeometry(const SGRect<int>& geom)
+ void NasalWidget::invalidate()
{
- if( _geometry == geom )
- return;
- _geometry = geom;
+ LayoutItem::invalidate();
+ _flags |= LAYOUT_DIRTY;
+ }
- if( !_set_geometry )
+ //----------------------------------------------------------------------------
+ void NasalWidget::setGeometry(const SGRect<int>& geom)
+ {
+ 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 )
{
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)
{
*/
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);
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;
return _nasal_impl.get_naRef();
}
+ //----------------------------------------------------------------------------
+ bool Object::valid() const
+ {
+ return _nasal_impl.valid();
+ }
+
//----------------------------------------------------------------------------
bool Object::_set(naContext c, const std::string& key, naRef val)
{
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);
}
};
+ 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_ */