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/NasalContext.hxx>
23 #include <simgear/nasal/cppbind/Ghost.hxx>
30 //----------------------------------------------------------------------------
31 NasalWidget::NasalWidget(naRef impl):
33 _layout_size_hint(32, 32),
34 _layout_min_size(16, 16),
35 _layout_max_size(MAX_SIZE),
36 _user_size_hint(0, 0),
38 _user_max_size(MAX_SIZE)
43 //----------------------------------------------------------------------------
44 NasalWidget::~NasalWidget()
49 //----------------------------------------------------------------------------
50 void NasalWidget::onRemove()
54 callMethod<void>("onRemove");
56 catch( std::exception const& ex )
61 "NasalWidget::onRemove: callback error: '" << ex.what() << "'"
66 //----------------------------------------------------------------------------
67 void NasalWidget::setSetGeometryFunc(const SetGeometryFunc& func)
72 //----------------------------------------------------------------------------
73 void NasalWidget::setHeightForWidthFunc(const HeightForWidthFunc& func)
75 _height_for_width = func;
79 //----------------------------------------------------------------------------
80 void NasalWidget::setMinimumHeightForWidthFunc(const HeightForWidthFunc& func)
82 _min_height_for_width = func;
86 //----------------------------------------------------------------------------
87 void NasalWidget::setSizeHint(const SGVec2i& s)
89 if( _user_size_hint == s )
94 // TODO just invalidate size_hint? Probably not a performance issue...
98 //----------------------------------------------------------------------------
99 void NasalWidget::setMinimumSize(const SGVec2i& s)
101 if( _user_min_size == s )
108 //----------------------------------------------------------------------------
109 void NasalWidget::setMaximumSize(const SGVec2i& s)
111 if( _user_max_size == s )
118 //----------------------------------------------------------------------------
119 void NasalWidget::setLayoutSizeHint(const SGVec2i& s)
121 if( _layout_size_hint == s )
124 _layout_size_hint = s;
128 //----------------------------------------------------------------------------
129 void NasalWidget::setLayoutMinimumSize(const SGVec2i& s)
131 if( _layout_min_size == s )
134 _layout_min_size = s;
138 //----------------------------------------------------------------------------
139 void NasalWidget::setLayoutMaximumSize(const SGVec2i& s)
141 if( _layout_max_size == s )
144 _layout_max_size = s;
148 //----------------------------------------------------------------------------
149 bool NasalWidget::hasHeightForWidth() const
151 return !_height_for_width.empty() || !_min_height_for_width.empty();
154 //----------------------------------------------------------------------------
155 static naRef f_makeNasalWidget(const nasal::CallContext& ctx)
157 return ctx.to_nasal(NasalWidgetRef(
158 new NasalWidget( ctx.requireArg<naRef>(0) )
162 //----------------------------------------------------------------------------
163 void NasalWidget::setupGhost(nasal::Hash& ns)
165 nasal::Ghost<NasalWidgetRef>::init("canvas.Widget")
166 .bases<LayoutItemRef>()
167 .bases<nasal::ObjectRef>()
168 .method("setSetGeometryFunc", &NasalWidget::setSetGeometryFunc)
169 .method("setMinimumHeightForWidthFunc",
170 &NasalWidget::setMinimumHeightForWidthFunc)
171 .method("setHeightForWidthFunc", &NasalWidget::setHeightForWidthFunc)
172 .method("setSizeHint", &NasalWidget::setSizeHint)
173 .method("setMinimumSize", &NasalWidget::setMinimumSize)
174 .method("setMaximumSize", &NasalWidget::setMaximumSize)
175 .method("setLayoutSizeHint", &NasalWidget::setLayoutSizeHint)
176 .method("setLayoutMinimumSize", &NasalWidget::setLayoutMinimumSize)
177 .method("setLayoutMaximumSize", &NasalWidget::setLayoutMaximumSize);
179 nasal::Hash widget_hash = ns.createHash("Widget");
180 widget_hash.set("new", &f_makeNasalWidget);
183 //----------------------------------------------------------------------------
184 int NasalWidget::callHeightForWidthFunc( const HeightForWidthFunc& hfw,
190 naContext c = naNewContext();
193 return hfw(nasal::to_nasal(c, const_cast<NasalWidget*>(this)), w);
195 catch( std::exception const& ex )
200 "NasalWidget.heightForWidth: callback error: '" << ex.what() << "'"
208 //----------------------------------------------------------------------------
209 SGVec2i NasalWidget::sizeHintImpl() const
212 _user_size_hint.x() > 0 ? _user_size_hint.x() : _layout_size_hint.x(),
213 _user_size_hint.y() > 0 ? _user_size_hint.y() : _layout_size_hint.y()
217 //----------------------------------------------------------------------------
218 SGVec2i NasalWidget::minimumSizeImpl() const
221 _user_min_size.x() > 0 ? _user_min_size.x() : _layout_min_size.x(),
222 _user_min_size.y() > 0 ? _user_min_size.y() : _layout_min_size.y()
226 //----------------------------------------------------------------------------
227 SGVec2i NasalWidget::maximumSizeImpl() const
230 _user_max_size.x() < MAX_SIZE.x() ? _user_max_size.x()
231 : _layout_max_size.x(),
232 _user_max_size.y() < MAX_SIZE.y() ? _user_max_size.y()
233 : _layout_max_size.y()
238 //----------------------------------------------------------------------------
239 int NasalWidget::heightForWidthImpl(int w) const
241 return callHeightForWidthFunc( _height_for_width.empty()
242 ? _min_height_for_width
243 : _height_for_width, w );
246 //----------------------------------------------------------------------------
247 int NasalWidget::minimumHeightForWidthImpl(int w) const
249 return callHeightForWidthFunc( _min_height_for_width.empty()
251 : _min_height_for_width, w );
255 //----------------------------------------------------------------------------
256 void NasalWidget::contentsRectChanged(const SGRect<int>& rect)
264 _set_geometry(nasal::to_nasal(c, this), rect);
265 _flags &= ~LAYOUT_DIRTY;
267 catch( std::exception const& ex )
272 "NasalWidget::setGeometry: callback error: '" << ex.what() << "'"
277 //----------------------------------------------------------------------------
278 void NasalWidget::visibilityChanged(bool visible)
282 callMethod<void>("visibilityChanged", visible);
284 catch( std::exception const& ex )
289 "NasalWidget::visibilityChanged: callback error: '" << ex.what() << "'"
294 } // namespace canvas
295 } // namespace simgear