#include "NasalWidget.hxx"
#include <simgear/canvas/Canvas.hxx>
+#include <simgear/nasal/cppbind/NasalContext.hxx>
#include <simgear/nasal/cppbind/Ghost.hxx>
namespace simgear
//----------------------------------------------------------------------------
NasalWidget::NasalWidget(naRef impl):
- Object(impl)
+ Object(impl),
+ _layout_size_hint(32, 32),
+ _layout_min_size(16, 16),
+ _layout_max_size(MAX_SIZE),
+ _user_size_hint(0, 0),
+ _user_min_size(0, 0),
+ _user_max_size(MAX_SIZE)
{
}
//----------------------------------------------------------------------------
- void NasalWidget::setGeometry(const SGRect<int>& geom)
+ NasalWidget::~NasalWidget()
{
- if( _geometry == geom )
- return;
- _geometry = geom;
-
- if( !_set_geometry )
- return;
+ onRemove();
+ }
- naContext c = naNewContext();
+ //----------------------------------------------------------------------------
+ void NasalWidget::onRemove()
+ {
try
{
- _set_geometry(nasal::to_nasal(c, this), geom);
+ callMethod<void>("onRemove");
}
catch( std::exception const& ex )
{
SG_LOG(
SG_GUI,
SG_WARN,
- "NasalWidget::setGeometry: callback error: '" << ex.what() << "'"
+ "NasalWidget::onRemove: callback error: '" << ex.what() << "'"
);
}
- naFreeContext(c);
}
//----------------------------------------------------------------------------
void NasalWidget::setHeightForWidthFunc(const HeightForWidthFunc& func)
{
_height_for_width = func;
- invalidateParent();
+ invalidate();
}
//----------------------------------------------------------------------------
void NasalWidget::setMinimumHeightForWidthFunc(const HeightForWidthFunc& func)
{
_min_height_for_width = func;
- invalidateParent();
+ invalidate();
}
//----------------------------------------------------------------------------
void NasalWidget::setSizeHint(const SGVec2i& s)
{
- if( _size_hint == s )
+ if( _user_size_hint == s )
return;
- _size_hint = s;
+ _user_size_hint = s;
// TODO just invalidate size_hint? Probably not a performance issue...
- invalidateParent();
+ invalidate();
}
//----------------------------------------------------------------------------
void NasalWidget::setMinimumSize(const SGVec2i& s)
{
- if( _min_size == s )
+ if( _user_min_size == s )
return;
- _min_size = s;
- invalidateParent();
+ _user_min_size = s;
+ invalidate();
}
//----------------------------------------------------------------------------
void NasalWidget::setMaximumSize(const SGVec2i& s)
{
- if( _max_size == s )
+ if( _user_max_size == s )
return;
- _max_size = s;
- invalidateParent();
+ _user_max_size = s;
+ invalidate();
}
//----------------------------------------------------------------------------
- bool NasalWidget::hasHeightForWidth() const
+ void NasalWidget::setLayoutSizeHint(const SGVec2i& s)
{
- return !_height_for_width.empty() || !_min_height_for_width.empty();
+ if( _layout_size_hint == s )
+ return;
+
+ _layout_size_hint = s;
+ invalidate();
}
//----------------------------------------------------------------------------
- int NasalWidget::heightForWidth(int w) const
+ void NasalWidget::setLayoutMinimumSize(const SGVec2i& s)
{
- return callHeightForWidthFunc( _height_for_width.empty()
- ? _min_height_for_width
- : _height_for_width, w );
+ if( _layout_min_size == s )
+ return;
+
+ _layout_min_size = s;
+ invalidate();
}
//----------------------------------------------------------------------------
- int NasalWidget::minimumHeightForWidth(int w) const
+ void NasalWidget::setLayoutMaximumSize(const SGVec2i& s)
{
- return callHeightForWidthFunc( _min_height_for_width.empty()
- ? _height_for_width
- : _min_height_for_width, w );
+ if( _layout_max_size == s )
+ return;
+
+ _layout_max_size = s;
+ invalidate();
+ }
+
+ //----------------------------------------------------------------------------
+ bool NasalWidget::hasHeightForWidth() const
+ {
+ return !_height_for_width.empty() || !_min_height_for_width.empty();
}
//----------------------------------------------------------------------------
.method("setHeightForWidthFunc", &NasalWidget::setHeightForWidthFunc)
.method("setSizeHint", &NasalWidget::setSizeHint)
.method("setMinimumSize", &NasalWidget::setMinimumSize)
- .method("setMaximumSize", &NasalWidget::setMaximumSize);
+ .method("setMaximumSize", &NasalWidget::setMaximumSize)
+ .method("setLayoutSizeHint", &NasalWidget::setLayoutSizeHint)
+ .method("setLayoutMinimumSize", &NasalWidget::setLayoutMinimumSize)
+ .method("setLayoutMaximumSize", &NasalWidget::setLayoutMaximumSize);
nasal::Hash widget_hash = ns.createHash("Widget");
widget_hash.set("new", &f_makeNasalWidget);
//----------------------------------------------------------------------------
SGVec2i NasalWidget::sizeHintImpl() const
{
- return _size_hint;
+ return SGVec2i(
+ _user_size_hint.x() > 0 ? _user_size_hint.x() : _layout_size_hint.x(),
+ _user_size_hint.y() > 0 ? _user_size_hint.y() : _layout_size_hint.y()
+ );
}
//----------------------------------------------------------------------------
SGVec2i NasalWidget::minimumSizeImpl() const
{
- return _min_size;
+ return SGVec2i(
+ _user_min_size.x() > 0 ? _user_min_size.x() : _layout_min_size.x(),
+ _user_min_size.y() > 0 ? _user_min_size.y() : _layout_min_size.y()
+ );
}
//----------------------------------------------------------------------------
SGVec2i NasalWidget::maximumSizeImpl() const
{
- return _max_size;
+ return SGVec2i(
+ _user_max_size.x() < MAX_SIZE.x() ? _user_max_size.x()
+ : _layout_max_size.x(),
+ _user_max_size.y() < MAX_SIZE.y() ? _user_max_size.y()
+ : _layout_max_size.y()
+ );
+ }
+
+
+ //----------------------------------------------------------------------------
+ int NasalWidget::heightForWidthImpl(int w) const
+ {
+ return callHeightForWidthFunc( _height_for_width.empty()
+ ? _min_height_for_width
+ : _height_for_width, w );
+ }
+
+ //----------------------------------------------------------------------------
+ int NasalWidget::minimumHeightForWidthImpl(int w) const
+ {
+ return callHeightForWidthFunc( _min_height_for_width.empty()
+ ? _height_for_width
+ : _min_height_for_width, w );
+ }
+
+
+ //----------------------------------------------------------------------------
+ void NasalWidget::contentsRectChanged(const SGRect<int>& rect)
+ {
+ if( !_set_geometry )
+ return;
+
+ try
+ {
+ nasal::Context c;
+ _set_geometry(nasal::to_nasal(c, this), rect);
+ _flags &= ~LAYOUT_DIRTY;
+ }
+ catch( std::exception const& ex )
+ {
+ SG_LOG(
+ SG_GUI,
+ SG_WARN,
+ "NasalWidget::setGeometry: callback error: '" << ex.what() << "'"
+ );
+ }
+ }
+
+ //----------------------------------------------------------------------------
+ void NasalWidget::visibilityChanged(bool visible)
+ {
+ try
+ {
+ callMethod<void>("visibilityChanged", visible);
+ }
+ catch( std::exception const& ex )
+ {
+ SG_LOG(
+ SG_GUI,
+ SG_WARN,
+ "NasalWidget::visibilityChanged: callback error: '" << ex.what() << "'"
+ );
+ }
}
} // namespace canvas