1 // Glue for GUI layout items implemented in Nasal space
3 // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Library General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Library General Public License for more details.
15 // You should have received a copy of the GNU Library General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "NasalWidget.hxx"
21 #include <simgear/canvas/Canvas.hxx>
22 #include <simgear/nasal/cppbind/Ghost.hxx>
29 //----------------------------------------------------------------------------
30 NasalWidget::NasalWidget(naRef impl):
36 //----------------------------------------------------------------------------
37 NasalWidget::~NasalWidget()
42 //----------------------------------------------------------------------------
43 void NasalWidget::invalidate()
45 LayoutItem::invalidate();
46 _flags |= LAYOUT_DIRTY;
49 //----------------------------------------------------------------------------
50 void NasalWidget::setGeometry(const SGRect<int>& geom)
52 if( _geometry != geom )
54 else if( !(_flags & LAYOUT_DIRTY) || !_set_geometry )
57 naContext c = naNewContext();
60 _set_geometry(nasal::to_nasal(c, this), geom);
61 _flags &= ~LAYOUT_DIRTY;
63 catch( std::exception const& ex )
68 "NasalWidget::setGeometry: callback error: '" << ex.what() << "'"
74 //----------------------------------------------------------------------------
75 void NasalWidget::onRemove()
77 if( !_nasal_impl.valid() )
80 typedef boost::function<void(nasal::Me)> Deleter;
82 naContext c = naNewContext();
86 nasal::get_member<Deleter>(c, _nasal_impl.get_naRef(), "onRemove");
88 del(_nasal_impl.get_naRef());
90 catch( std::exception const& ex )
95 "NasalWidget::onRemove: callback error: '" << ex.what() << "'"
101 //----------------------------------------------------------------------------
102 void NasalWidget::setSetGeometryFunc(const SetGeometryFunc& func)
104 _set_geometry = func;
107 //----------------------------------------------------------------------------
108 void NasalWidget::setHeightForWidthFunc(const HeightForWidthFunc& func)
110 _height_for_width = func;
114 //----------------------------------------------------------------------------
115 void NasalWidget::setMinimumHeightForWidthFunc(const HeightForWidthFunc& func)
117 _min_height_for_width = func;
121 //----------------------------------------------------------------------------
122 void NasalWidget::setSizeHint(const SGVec2i& s)
124 if( _size_hint == s )
129 // TODO just invalidate size_hint? Probably not a performance issue...
133 //----------------------------------------------------------------------------
134 void NasalWidget::setMinimumSize(const SGVec2i& s)
143 //----------------------------------------------------------------------------
144 void NasalWidget::setMaximumSize(const SGVec2i& s)
153 //----------------------------------------------------------------------------
154 bool NasalWidget::hasHeightForWidth() const
156 return !_height_for_width.empty() || !_min_height_for_width.empty();
159 //----------------------------------------------------------------------------
160 int NasalWidget::heightForWidth(int w) const
162 return callHeightForWidthFunc( _height_for_width.empty()
163 ? _min_height_for_width
164 : _height_for_width, w );
167 //----------------------------------------------------------------------------
168 int NasalWidget::minimumHeightForWidth(int w) const
170 return callHeightForWidthFunc( _min_height_for_width.empty()
172 : _min_height_for_width, w );
175 //----------------------------------------------------------------------------
176 static naRef f_makeNasalWidget(const nasal::CallContext& ctx)
178 return ctx.to_nasal(NasalWidgetRef(
179 new NasalWidget( ctx.requireArg<naRef>(0) )
183 //----------------------------------------------------------------------------
184 void NasalWidget::setupGhost(nasal::Hash& ns)
186 nasal::Ghost<NasalWidgetRef>::init("canvas.Widget")
187 .bases<LayoutItemRef>()
188 .bases<nasal::ObjectRef>()
189 .method("setSetGeometryFunc", &NasalWidget::setSetGeometryFunc)
190 .method("setMinimumHeightForWidthFunc",
191 &NasalWidget::setMinimumHeightForWidthFunc)
192 .method("setHeightForWidthFunc", &NasalWidget::setHeightForWidthFunc)
193 .method("setSizeHint", &NasalWidget::setSizeHint)
194 .method("setMinimumSize", &NasalWidget::setMinimumSize)
195 .method("setMaximumSize", &NasalWidget::setMaximumSize);
197 nasal::Hash widget_hash = ns.createHash("Widget");
198 widget_hash.set("new", &f_makeNasalWidget);
201 //----------------------------------------------------------------------------
202 int NasalWidget::callHeightForWidthFunc( const HeightForWidthFunc& hfw,
208 naContext c = naNewContext();
211 return hfw(nasal::to_nasal(c, const_cast<NasalWidget*>(this)), w);
213 catch( std::exception const& ex )
218 "NasalWidget.heightForWidth: callback error: '" << ex.what() << "'"
226 //----------------------------------------------------------------------------
227 SGVec2i NasalWidget::sizeHintImpl() const
232 //----------------------------------------------------------------------------
233 SGVec2i NasalWidget::minimumSizeImpl() const
238 //----------------------------------------------------------------------------
239 SGVec2i NasalWidget::maximumSizeImpl() const
244 } // namespace canvas
245 } // namespace simgear