FlightGear next
NasalCanvas.cxx
Go to the documentation of this file.
1// NasalCanvas.cxx -- expose Canvas classes to Nasal
2//
3// Written by James Turner, started 2012.
4//
5// Copyright (C) 2012 James Turner
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21#include "config.h"
22
23#include "NasalCanvas.hxx"
24#include <Canvas/canvas_mgr.hxx>
25#include <Canvas/gui_mgr.hxx>
26#include <Main/globals.hxx>
27#include <Scripting/NasalCondition.hxx> // for NasalBinding
29
30#include <osgGA/GUIEventAdapter>
31
32#include <simgear/sg_inlines.h>
33
34#include <simgear/canvas/Canvas.hxx>
35#include <simgear/canvas/CanvasWindow.hxx>
36#include <simgear/canvas/elements/CanvasElement.hxx>
37#include <simgear/canvas/elements/CanvasText.hxx>
38#include <simgear/canvas/events/CanvasKeyBinding.hxx>
39#include <simgear/canvas/events/CustomEvent.hxx>
40#include <simgear/canvas/events/KeyboardEvent.hxx>
41#include <simgear/canvas/events/MouseEvent.hxx>
42#include <simgear/canvas/layout/BoxLayout.hxx>
43#include <simgear/canvas/layout/GridLayout.hxx>
44#include <simgear/canvas/layout/NasalWidget.hxx>
45#include <simgear/canvas/layout/SpacerItem.hxx>
46
47#include <simgear/nasal/cppbind/from_nasal.hxx>
48#include <simgear/nasal/cppbind/to_nasal.hxx>
49#include <simgear/nasal/cppbind/NasalHash.hxx>
50#include <simgear/nasal/cppbind/Ghost.hxx>
51
52extern naRef propNodeGhostCreate(naContext c, SGPropertyNode* n);
53
54namespace sc = simgear::canvas;
55
56template<class Element>
57naRef elementGetNode(Element& element, naContext c)
58{
59 return propNodeGhostCreate(c, element.getProps());
60}
61
62typedef nasal::Ghost<sc::EventPtr> NasalEvent;
63typedef nasal::Ghost<sc::CustomEventPtr> NasalCustomEvent;
64typedef nasal::Ghost<sc::DeviceEventPtr> NasalDeviceEvent;
65typedef nasal::Ghost<sc::KeyboardEventPtr> NasalKeyboardEvent;
66typedef nasal::Ghost<sc::MouseEventPtr> NasalMouseEvent;
67typedef nasal::Ghost<sc::KeyBindingRef> NasalKeyBinding;
68
70typedef SGSharedPtr<CustomEventDetailWrapper> CustomEventDetailPtr;
71typedef nasal::Ghost<CustomEventDetailPtr> NasalCustomEventDetail;
72
73typedef nasal::Ghost<simgear::PropertyBasedElementPtr> NasalPropertyBasedElement;
74typedef nasal::Ghost<sc::CanvasPtr> NasalCanvas;
75typedef nasal::Ghost<sc::ElementPtr> NasalElement;
76typedef nasal::Ghost<sc::GroupPtr> NasalGroup;
77typedef nasal::Ghost<sc::TextPtr> NasalText;
78typedef nasal::Ghost<sc::ImagePtr> NasalImage;
79
80typedef nasal::Ghost<sc::LayoutItemRef> NasalLayoutItem;
81typedef nasal::Ghost<sc::LayoutRef> NasalLayout;
82typedef nasal::Ghost<sc::BoxLayoutRef> NasalBoxLayout;
83typedef nasal::Ghost<sc::GridLayoutRef> NasalGridLayout;
84using NasalSpacerItem = nasal::Ghost<sc::SpacerItemRef>;
85
86typedef nasal::Ghost<sc::WindowPtr> NasalWindow;
87
88naRef to_nasal_helper(naContext c, const osg::BoundingBox& bb)
89{
90 std::vector<float> bb_vec(4);
91 bb_vec[0] = bb._min.x();
92 bb_vec[1] = bb._min.y();
93 bb_vec[2] = bb._max.x();
94 bb_vec[3] = bb._max.y();
95
96 return nasal::to_nasal(c, bb_vec);
97}
98
99SGPropertyNode* from_nasal_helper(naContext c, naRef ref, SGPropertyNode**)
100{
101 SGPropertyNode* props = ghostToPropNode(ref);
102 if( !props )
103 naRuntimeError(c, "Not a SGPropertyNode ghost.");
104
105 return props;
106}
107
108CanvasMgr& requireCanvasMgr(const nasal::ContextWrapper& ctx)
109{
110 auto canvas_mgr = globals->get_subsystem<CanvasMgr>();
111 if( !canvas_mgr )
112 ctx.runtimeError("Failed to get Canvas subsystem");
113
114 return *canvas_mgr;
115}
116
117GUIMgr& requireGUIMgr(const nasal::ContextWrapper& ctx)
118{
119 auto mgr = globals->get_subsystem<GUIMgr>();
120 if( !mgr )
121 ctx.runtimeError("Failed to get CanvasGUI subsystem");
122
123 return *mgr;
124}
125
129static naRef f_createCanvas(const nasal::CallContext& ctx)
130{
131 return ctx.to_nasal(requireCanvasMgr(ctx).createCanvas());
132}
133
137static naRef f_createWindow(const nasal::CallContext& ctx)
138{
139 return ctx.to_nasal<sc::WindowWeakPtr>
140 (
141 requireGUIMgr(ctx).createWindow( ctx.getArg<std::string>(0) )
142 );
143}
144
148static naRef f_getCanvas(const nasal::CallContext& ctx)
149{
150 SGPropertyNode& props = *ctx.requireArg<SGPropertyNode*>(0);
151 CanvasMgr& canvas_mgr = requireCanvasMgr(ctx);
152
153 sc::CanvasPtr canvas;
154 if( canvas_mgr.getPropertyRoot() == props.getParent() )
155 {
156 // get a canvas specified by its root node
157 canvas = canvas_mgr.getCanvas( props.getIndex() );
158 if( !canvas || canvas->getProps() != &props )
159 return naNil();
160 }
161 else
162 {
163 // get a canvas by name
164 if( props.hasValue("name") )
165 canvas = canvas_mgr.getCanvas( props.getStringValue("name") );
166 else if( props.hasValue("index") )
167 canvas = canvas_mgr.getCanvas( props.getIntValue("index") );
168 }
169
170 return ctx.to_nasal(canvas);
171}
172
173naRef f_canvasCreateGroup(sc::Canvas& canvas, const nasal::CallContext& ctx)
174{
175 return ctx.to_nasal( canvas.createGroup(ctx.getArg<std::string>(0)) );
176}
177
181naRef f_getDesktop(const nasal::CallContext& ctx)
182{
183 return ctx.to_nasal(requireGUIMgr(ctx).getDesktop());
184}
185
186naRef f_setInputFocus(const nasal::CallContext& ctx)
187{
188 requireGUIMgr(ctx).setInputFocus(ctx.requireArg<sc::WindowPtr>(0));
189 return naNil();
190}
191
192naRef f_grabPointer(const nasal::CallContext& ctx)
193{
194 return ctx.to_nasal(
195 requireGUIMgr(ctx).grabPointer(ctx.requireArg<sc::WindowPtr>(0))
196 );
197}
198
199naRef f_ungrabPointer(const nasal::CallContext& ctx)
200{
201 requireGUIMgr(ctx).ungrabPointer(ctx.requireArg<sc::WindowPtr>(0));
202 return naNil();
203}
204
205static naRef f_groupCreateChild(sc::Group& group, const nasal::CallContext& ctx)
206{
207 return ctx.to_nasal( group.createChild( ctx.requireArg<std::string>(0),
208 ctx.getArg<std::string>(1) ) );
209}
210
211static sc::ElementPtr f_groupGetChild(sc::Group& group, SGPropertyNode* node)
212{
213 return group.getChild(node);
214}
215
216static naRef f_groupAddKeyBinding(sc::Group& group, const nasal::CallContext& ctx)
217{
218 auto keyBinding = ctx.requireArg<sc::KeyBindingRef>(0);
219 group.getOrCreateFocusScope()->addKeyBinding(keyBinding);
220 return naNil();
221}
222
223static naRef f_windowAddKeyBinding(sc::Window& window, const nasal::CallContext& ctx)
224{
225 auto keyBinding = ctx.requireArg<sc::KeyBindingRef>(0);
226 window.focusScope()->addKeyBinding(keyBinding);
227 return naNil();
228}
229
230static void propElementSetData( simgear::PropertyBasedElement& el,
231 const std::string& name,
232 const nasal::ContextWrapper& ctx,
233 naRef ref )
234{
235 if( naIsNil(ref) )
236 return el.removeDataProp(name);
237
238 std::string val = ctx.from_nasal<std::string>(ref);
239
240 char* end = NULL;
241
242 long val_long = strtol(val.c_str(), &end, 10);
243 if( !*end )
244 return el.setDataProp(name, val_long);
245
246 double val_double = strtod(val.c_str(), &end);
247 if( !*end )
248 return el.setDataProp(name, val_double);
249
250 el.setDataProp(name, val);
251}
252
278static naRef f_propElementData( simgear::PropertyBasedElement& el,
279 const nasal::CallContext& ctx )
280{
281 if( ctx.isHash(0) )
282 {
283 // Add/delete properties given as hash
284 nasal::Hash obj = ctx.requireArg<nasal::Hash>(0);
285 for(nasal::Hash::iterator it = obj.begin(); it != obj.end(); ++it)
286 propElementSetData(el, it->getKey(), ctx, it->getValue<naRef>());
287
288 return ctx.to_nasal(&el);
289 }
290
291 std::string name = ctx.getArg<std::string>(0);
292 if( !name.empty() )
293 {
294 if( ctx.argc == 1 )
295 {
296 // name + additional argument -> add/delete property
297 SGPropertyNode* node = el.getDataProp<SGPropertyNode*>(name);
298 if( !node )
299 return naNil();
300
301 return ctx.to_nasal( node->getStringValue() );
302 }
303 else
304 {
305 // only name -> get property
306 propElementSetData(el, name, ctx, ctx.requireArg<naRef>(1));
307 return ctx.to_nasal(&el);
308 }
309 }
310
311 return naNil();
312}
313
314static naRef f_createCustomEvent(const nasal::CallContext& ctx)
315{
316 std::string const& type = ctx.requireArg<std::string>(0);
317 if( type.empty() )
318 return naNil();
319
320 bool bubbles = false;
321 simgear::StringMap detail;
322 if( ctx.isHash(1) )
323 {
324 nasal::Hash const& cfg = ctx.requireArg<nasal::Hash>(1);
325 naRef na_detail = cfg.get("detail");
326 if( naIsHash(na_detail) )
327 detail = ctx.from_nasal<simgear::StringMap>(na_detail);
328 bubbles = cfg.get<bool>("bubbles");
329 }
330
331 return ctx.to_nasal(
332 sc::CustomEventPtr(new sc::CustomEvent(type, bubbles, detail))
333 );
334}
335
337 public SGReferenced
338{
339 sc::CustomEventPtr _event;
340
341 CustomEventDetailWrapper(const sc::CustomEventPtr& event):
342 _event(event)
343 {
344
345 }
346
347 bool _get( const std::string& key,
348 std::string& value_out ) const
349 {
350 if( !_event )
351 return false;
352
353 simgear::StringMap::const_iterator it = _event->detail.find(key);
354 if( it == _event->detail.end() )
355 return false;
356
357 value_out = it->second;
358 return true;
359 }
360
361 bool _set( const std::string& key,
362 const std::string& value )
363 {
364 if( !_event )
365 return false;
366
367 _event->detail[ key ] = value;
368 return true;
369 }
370};
371
372static naRef f_customEventGetDetail( sc::CustomEvent& event,
373 naContext c )
374{
375 return nasal::to_nasal(
376 c,
378 );
379}
380
381static naRef f_layoutItemSetVisible(sc::LayoutItem& item,
382 const nasal::CallContext& ctx)
383{
384 item.setVisible(ctx.getArg<bool>(0, true));
385 return ctx.me;
386}
387
388static naRef f_boxLayoutAddItem( sc::BoxLayout& box,
389 const nasal::CallContext& ctx )
390{
391 const auto item = ctx.requireArg<sc::LayoutItemRef>(0);
392 if (!item) {
393 ctx.runtimeError("BoxLayout.addItem: argument 0 is not a layout item");
394 }
395
396 box.addItem(item,
397 ctx.getArg<int>(1),
398 ctx.getArg<int>(2, sc::AlignFill));
399 return naNil();
400}
401static naRef f_boxLayoutInsertItem( sc::BoxLayout& box,
402 const nasal::CallContext& ctx )
403{
404 const auto item = ctx.requireArg<sc::LayoutItemRef>(1);
405 if (!item) {
406 ctx.runtimeError("BoxLayout.insertItem: argument 1 is not a layout item");
407 }
408
409 box.insertItem(ctx.requireArg<int>(0),
410 item,
411 ctx.getArg<int>(2),
412 ctx.getArg<int>(3, sc::AlignFill));
413 return naNil();
414}
415
416static naRef f_boxLayoutAddStretch( sc::BoxLayout& box,
417 const nasal::CallContext& ctx )
418{
419 box.addStretch( ctx.getArg<int>(0) );
420 return naNil();
421}
422static naRef f_boxLayoutInsertStretch( sc::BoxLayout& box,
423 const nasal::CallContext& ctx )
424{
425 box.insertStretch( ctx.requireArg<int>(0),
426 ctx.getArg<int>(1) );
427 return naNil();
428}
429
430template<class Type, class Base>
431static naRef f_newAsBase(const nasal::CallContext& ctx)
432{
433 return ctx.to_nasal<Base*>(new Type());
434}
435
436static naRef f_imageFillRect(sc::Image& img, const nasal::CallContext& ctx)
437{
438 const SGRecti r = ctx.requireArg<SGRecti>(0);
439 if (ctx.isString(1)) {
440 img.fillRect(r, ctx.getArg<std::string>(1));
441 } else {
442 img.fillRect(r, ctx.requireArg<osg::Vec4>(1));
443 }
444 return naNil();
445}
446
447static naRef f_imageSetPixel(sc::Image& img, const nasal::CallContext& ctx)
448{
449 const int s = ctx.requireArg<int>(0);
450 const int t = ctx.requireArg<int>(1);
451 if (ctx.isString(2)) {
452 img.setPixel(s, t, ctx.getArg<std::string>(2));
453 } else {
454 img.setPixel(s, t, ctx.requireArg<osg::Vec4>(2));
455 }
456 return naNil();
457}
458
459static naRef f_canvasImageSize(sc::Image& img, const nasal::CallContext& ctx)
460{
461 auto osgImage = img.getImage();
462 osg::Vec2f sz{0.0f, 0.0f};
463 if (osgImage) {
464 sz = osg::Vec2f{static_cast<float>(osgImage->s()),
465 static_cast<float>(osgImage->t())};
466 }
467
468 return ctx.to_nasal(sz);
469}
470
471static naRef f_gridLayoutAddItem(sc::GridLayout& grid,
472 const nasal::CallContext& ctx)
473{
474 const auto item = ctx.requireArg<sc::LayoutItemRef>(0);
475 if (!item) {
476 ctx.runtimeError("GridLayout.addItem: argument 0 is not a layout item");
477 }
478
479
480 grid.addItem(item,
481 ctx.requireArg<int>(1),
482 ctx.requireArg<int>(2),
483 ctx.getArg<int>(3, 1),
484 ctx.getArg<int>(4, 1));
485 return naNil();
486}
487
488static naRef f_newGridLayout(const nasal::CallContext& ctx)
489{
490 return ctx.to_nasal(new sc::GridLayout);
491}
492
493static naRef f_newSpacerItem(const nasal::CallContext& ctx)
494{
495 return ctx.to_nasal(new sc::SpacerItem);
496}
497
498static naRef f_keyBindingAddBinding(sc::KeyBinding& keyBinding, const nasal::CallContext& ctx)
499{
500 auto cb = ctx.requireArg<NasalBinding::NasalCallback>(0);
501 keyBinding.addBinding(new NasalBinding{cb});
502 return naNil();
503}
504
505static naRef f_newKeyBinding(const nasal::CallContext& ctx)
506{
507 return ctx.to_nasal(new sc::KeyBinding);
508}
509
510naRef initNasalCanvas(naRef globals, naContext c)
511{
512 nasal::Hash globals_module(globals, c),
513 canvas_module = globals_module.createHash("canvas");
514
515 nasal::Object::setupGhost();
516
517 //----------------------------------------------------------------------------
518 // Events
519
520 using osgGA::GUIEventAdapter;
521 NasalEvent::init("canvas.Event")
522 .member("type", &sc::Event::getTypeString)
523 .member("target", &sc::Event::getTarget)
524 .member("currentTarget", &sc::Event::getCurrentTarget)
525 .member("defaultPrevented", &sc::Event::defaultPrevented)
526 .method("stopPropagation", &sc::Event::stopPropagation)
527 .method("preventDefault", &sc::Event::preventDefault);
528
529 NasalCustomEvent::init("canvas.CustomEvent")
530 .bases<NasalEvent>()
531 .member("detail", &f_customEventGetDetail, &sc::CustomEvent::setDetail);
532 NasalCustomEventDetail::init("canvas.CustomEventDetail")
535
536 canvas_module.createHash("CustomEvent")
537 .set("new", &f_createCustomEvent);
538
539 NasalDeviceEvent::init("canvas.DeviceEvent")
540 .bases<NasalEvent>()
541 .member("modifiers", &sc::DeviceEvent::getModifiers)
542 .member("ctrlKey", &sc::DeviceEvent::ctrlKey)
543 .member("shiftKey", &sc::DeviceEvent::shiftKey)
544 .member("altKey", &sc::DeviceEvent::altKey)
545 .member("metaKey", &sc::DeviceEvent::metaKey);
546
547 NasalKeyboardEvent::init("canvas.KeyboardEvent")
548 .bases<NasalDeviceEvent>()
549 .member("key", &sc::KeyboardEvent::key)
550 .member("location", &sc::KeyboardEvent::location)
551 .member("repeat", &sc::KeyboardEvent::repeat)
552 .member("charCode", &sc::KeyboardEvent::charCode)
553 .member("keyCode", &sc::KeyboardEvent::keyCode);
554
555 NasalMouseEvent::init("canvas.MouseEvent")
556 .bases<NasalDeviceEvent>()
557 .member("screenX", &sc::MouseEvent::getScreenX)
558 .member("screenY", &sc::MouseEvent::getScreenY)
559 .member("clientX", &sc::MouseEvent::getClientX)
560 .member("clientY", &sc::MouseEvent::getClientY)
561 .member("localX", &sc::MouseEvent::getLocalX)
562 .member("localY", &sc::MouseEvent::getLocalY)
563 .member("deltaX", &sc::MouseEvent::getDeltaX)
564 .member("deltaY", &sc::MouseEvent::getDeltaY)
565 .member("button", &sc::MouseEvent::getButton)
566 .member("buttons", &sc::MouseEvent::getButtonMask)
567 .member("click_count", &sc::MouseEvent::getCurrentClickCount);
568
569
570 NasalKeyBinding::init("canvas.KeyBinding")
571 .member("key", &sc::KeyBinding::key, &sc::KeyBinding::setKey)
572 .member("keyCode", &sc::KeyBinding::keyCode, &sc::KeyBinding::setKeyCode)
573 .member("modifiers", &sc::KeyBinding::modifiers, &sc::KeyBinding::setModifiers)
574 .method("addBinding", &f_keyBindingAddBinding);
575 canvas_module.createHash("KeyBinding")
576 .set("new", &f_newKeyBinding);
577
578 //----------------------------------------------------------------------------
579 // Canvas & elements
580
581 NasalPropertyBasedElement::init("PropertyBasedElement")
582 .method("data", &f_propElementData);
583 NasalCanvas::init("Canvas")
585 .bases<nasal::ObjectRef>()
586 .member("_node_ghost", &elementGetNode<sc::Canvas>)
587 .member("size_x", &sc::Canvas::getSizeX)
588 .member("size_y", &sc::Canvas::getSizeY)
589 .method("_createGroup", &f_canvasCreateGroup)
590 .method("_getGroup", &sc::Canvas::getGroup)
591 .method( "addEventListener",
592 static_cast<bool (sc::Canvas::*)( const std::string&,
593 const sc::EventListener& )>
594 (&sc::Canvas::addEventListener) )
595 .method("dispatchEvent", &sc::Canvas::dispatchEvent)
596 .method("setLayout", &sc::Canvas::setLayout)
597 .method("setFocusElement", &sc::Canvas::setFocusElement)
598 .method("clearFocusElement", &sc::Canvas::clearFocusElement);
599
600 canvas_module.set("_newCanvasGhost", f_createCanvas);
601 canvas_module.set("_getCanvasGhost", f_getCanvas);
602
603 NasalElement::init("canvas.Element")
605 .member("_node_ghost", &elementGetNode<sc::Element>)
606 .method("_getParent", &sc::Element::getParent)
607 .method("_getCanvas", &sc::Element::getCanvas)
608 .method("addEventListener", &sc::Element::addEventListener)
609 .method("setFocus", &sc::Element::setFocus)
610 .method("dispatchEvent", &sc::Element::dispatchEvent)
611 .method("getBoundingBox", &sc::Element::getBoundingBox)
612 .method("getTightBoundingBox", &sc::Element::getTightBoundingBox)
613 .method("_posToLocal", &sc::Element::posToLocal)
614 .method("_posFromLocal", &sc::Element::posFromLocal)
615 .method("canvasToLocal", &sc::Element::canvasToLocal)
616 .method("localToCanvas", &sc::Element::localToCanvas);
617
618 NasalGroup::init("canvas.Group")
619 .bases<NasalElement>()
620 .method("_createChild", &f_groupCreateChild)
621 .method("_getChild", &f_groupGetChild)
622 .method("_getElementById", &sc::Group::getElementById)
623 .method("addKeyBinding", &f_groupAddKeyBinding);
624 NasalText::init("canvas.Text")
625 .bases<NasalElement>()
626 .method("heightForWidth", &sc::Text::heightForWidth)
627 .method("maxWidth", &sc::Text::maxWidth)
628 .method("lineCount", &sc::Text::lineCount)
629 .method("lineLength", &sc::Text::lineLength)
630 .method("getNearestCursor", &sc::Text::getNearestCursor)
631 .method("getCursorPos", &sc::Text::getCursorPos);
632
633 NasalImage::init("canvas.Image")
634 .bases<NasalElement>()
635 .method("fillRect", &f_imageFillRect)
636 .method("setPixel", &f_imageSetPixel)
637 .method("dirtyPixels", &sc::Image::dirtyPixels)
638 .method("imageSize", &f_canvasImageSize);
639
640 //----------------------------------------------------------------------------
641 // Layouting
642
643#define ALIGN_ENUM_MAPPING(key, val, comment) canvas_module.set(#key, sc::key);
644# include <simgear/canvas/layout/AlignFlag_values.hxx>
645#undef ALIGN_ENUM_MAPPING
646
647 void (sc::LayoutItem::*f_layoutItemSetContentsMargins)(int, int, int, int)
648 = &sc::LayoutItem::setContentsMargins;
649
650 NasalLayoutItem::init("canvas.LayoutItem")
651 .method("getCanvas", &sc::LayoutItem::getCanvas)
652 .method("setCanvas", &sc::LayoutItem::setCanvas)
653 .method("getParent", &sc::LayoutItem::getParent)
654 .method("setParent", &sc::LayoutItem::setParent)
655 .method("setContentsMargins", f_layoutItemSetContentsMargins)
656 .method("setContentsMargin", &sc::LayoutItem::setContentsMargin)
657 .method("sizeHint", &sc::LayoutItem::sizeHint)
658 .method("minimumSize", &sc::LayoutItem::minimumSize)
659 .method("maximumSize", &sc::LayoutItem::maximumSize)
660 .method("hasHeightForWidth", &sc::LayoutItem::hasHeightForWidth)
661 .method("heightForWidth", &sc::LayoutItem::heightForWidth)
662 .method("minimumHeightForWidth", &sc::LayoutItem::minimumHeightForWidth)
663 .method("setAlignment", &sc::LayoutItem::setAlignment)
664 .method("alignment", &sc::LayoutItem::alignment)
665 .method("setVisible", f_layoutItemSetVisible)
666 .method("isVisible", &sc::LayoutItem::isVisible)
667 .method("isExplicitlyHidden", &sc::LayoutItem::isExplicitlyHidden)
668 .method("show", &sc::LayoutItem::show)
669 .method("hide", &sc::LayoutItem::hide)
670 .method("setGeometry", &sc::LayoutItem::setGeometry)
671 .method("geometry", &sc::LayoutItem::geometry)
672 .method("setGridLocation", &sc::LayoutItem::setGridLocation)
673 .method("setGridSpan", &sc::LayoutItem::setGridSpan);
674
675 sc::NasalWidget::setupGhost(canvas_module);
676
677 NasalLayout::init("canvas.Layout")
678 .bases<NasalLayoutItem>()
679 .method("addItem", &sc::Layout::addItem)
680 .method("setSpacing", &sc::Layout::setSpacing)
681 .method("spacing", &sc::Layout::spacing)
682 .method("count", &sc::Layout::count)
683 .method("itemAt", &sc::Layout::itemAt)
684 .method("takeAt", &sc::Layout::takeAt)
685 .method("removeItem", &sc::Layout::removeItem)
686 .method("clear", &sc::Layout::clear);
687
688 NasalBoxLayout::init("canvas.BoxLayout")
689 .bases<NasalLayout>()
690 .method("addItem", &f_boxLayoutAddItem)
691 .method("addSpacing", &sc::BoxLayout::addSpacing)
692 .method("addStretch", &f_boxLayoutAddStretch)
693 .method("insertItem", &f_boxLayoutInsertItem)
694 .method("insertSpacing", &sc::BoxLayout::insertSpacing)
695 .method("insertStretch", &f_boxLayoutInsertStretch)
696 .method("setStretch", &sc::BoxLayout::setStretch)
697 .method("setStretchFactor", &sc::BoxLayout::setStretchFactor)
698 .method("stretch", &sc::BoxLayout::stretch)
699 .method("setEquals", &sc::BoxLayout::setEqualsItem);
700
701 NasalGridLayout::init("canvas.GridLayout")
702 .bases<NasalLayout>()
703 .method("addItem", &f_gridLayoutAddItem)
704 .method("setRowStretch", &sc::GridLayout::setRowStretch)
705 .method("setColumnStretch", &sc::GridLayout::setColumnStretch);
706
707 NasalSpacerItem::init("canvas.SpacerItem")
708 .bases<NasalLayoutItem>();
709
710 canvas_module.createHash("HBoxLayout")
712 canvas_module.createHash("VBoxLayout")
714 canvas_module.createHash("GridLayout")
715 .set("new", &f_newGridLayout);
716 canvas_module.createHash("Spacer")
717 .set("new", &f_newSpacerItem);
718
719 canvas_module.set("MAX_SIZE", sc::LayoutItem::MAX_SIZE.x());
720
721 //----------------------------------------------------------------------------
722 // Window
723
724 NasalWindow::init("canvas.Window")
725 .bases<NasalElement>()
726 .bases<NasalLayoutItem>()
727 .member("_node_ghost", &elementGetNode<sc::Window>)
728 .method("_getCanvasDecoration", &sc::Window::getCanvasDecoration)
729 .method("setLayout", &sc::Window::setLayout)
730 .method("toScreenPosition", &sc::Window::toScreenPosition)
731 .method("addKeyBinding", &f_windowAddKeyBinding);
732
733 canvas_module.set("_newWindowGhost", f_createWindow);
734 canvas_module.set("_getDesktopGhost", f_getDesktop);
735 canvas_module.set("setInputFocus", f_setInputFocus);
736 canvas_module.set("grabPointer", f_grabPointer);
737 canvas_module.set("ungrabPointer", f_ungrabPointer);
738
739 return naNil();
740}
naRef f_setInputFocus(const nasal::CallContext &ctx)
static naRef f_newAsBase(const nasal::CallContext &ctx)
static naRef f_layoutItemSetVisible(sc::LayoutItem &item, const nasal::CallContext &ctx)
static naRef f_windowAddKeyBinding(sc::Window &window, const nasal::CallContext &ctx)
static naRef f_propElementData(simgear::PropertyBasedElement &el, const nasal::CallContext &ctx)
Accessor for HTML5 data properties.
nasal::Ghost< sc::BoxLayoutRef > NasalBoxLayout
nasal::Ghost< sc::CustomEventPtr > NasalCustomEvent
static naRef f_imageFillRect(sc::Image &img, const nasal::CallContext &ctx)
nasal::Ghost< CustomEventDetailPtr > NasalCustomEventDetail
static naRef f_imageSetPixel(sc::Image &img, const nasal::CallContext &ctx)
nasal::Ghost< sc::MouseEventPtr > NasalMouseEvent
naRef to_nasal_helper(naContext c, const osg::BoundingBox &bb)
static naRef f_groupAddKeyBinding(sc::Group &group, const nasal::CallContext &ctx)
static naRef f_boxLayoutInsertItem(sc::BoxLayout &box, const nasal::CallContext &ctx)
static naRef f_groupCreateChild(sc::Group &group, const nasal::CallContext &ctx)
naRef f_getDesktop(const nasal::CallContext &ctx)
Get group containing all gui windows.
naRef elementGetNode(Element &element, naContext c)
nasal::Ghost< sc::LayoutItemRef > NasalLayoutItem
nasal::Ghost< sc::ElementPtr > NasalElement
static naRef f_boxLayoutAddStretch(sc::BoxLayout &box, const nasal::CallContext &ctx)
nasal::Ghost< sc::TextPtr > NasalText
naRef f_canvasCreateGroup(sc::Canvas &canvas, const nasal::CallContext &ctx)
SGSharedPtr< CustomEventDetailWrapper > CustomEventDetailPtr
static naRef f_createCustomEvent(const nasal::CallContext &ctx)
static naRef f_boxLayoutAddItem(sc::BoxLayout &box, const nasal::CallContext &ctx)
static naRef f_canvasImageSize(sc::Image &img, const nasal::CallContext &ctx)
static sc::ElementPtr f_groupGetChild(sc::Group &group, SGPropertyNode *node)
nasal::Ghost< sc::GridLayoutRef > NasalGridLayout
nasal::Ghost< sc::CanvasPtr > NasalCanvas
nasal::Ghost< sc::KeyBindingRef > NasalKeyBinding
naRef propNodeGhostCreate(naContext c, SGPropertyNode *n)
naRef f_grabPointer(const nasal::CallContext &ctx)
static naRef f_boxLayoutInsertStretch(sc::BoxLayout &box, const nasal::CallContext &ctx)
SGPropertyNode * from_nasal_helper(naContext c, naRef ref, SGPropertyNode **)
static naRef f_gridLayoutAddItem(sc::GridLayout &grid, const nasal::CallContext &ctx)
naRef initNasalCanvas(naRef globals, naContext c)
naRef f_ungrabPointer(const nasal::CallContext &ctx)
nasal::Ghost< sc::WindowPtr > NasalWindow
nasal::Ghost< simgear::PropertyBasedElementPtr > NasalPropertyBasedElement
CanvasMgr & requireCanvasMgr(const nasal::ContextWrapper &ctx)
static naRef f_customEventGetDetail(sc::CustomEvent &event, naContext c)
static naRef f_newKeyBinding(const nasal::CallContext &ctx)
static naRef f_keyBindingAddBinding(sc::KeyBinding &keyBinding, const nasal::CallContext &ctx)
nasal::Ghost< sc::SpacerItemRef > NasalSpacerItem
static naRef f_createCanvas(const nasal::CallContext &ctx)
Create new Canvas and get ghost for it.
nasal::Ghost< sc::DeviceEventPtr > NasalDeviceEvent
static naRef f_newSpacerItem(const nasal::CallContext &ctx)
static void propElementSetData(simgear::PropertyBasedElement &el, const std::string &name, const nasal::ContextWrapper &ctx, naRef ref)
nasal::Ghost< sc::GroupPtr > NasalGroup
nasal::Ghost< sc::ImagePtr > NasalImage
GUIMgr & requireGUIMgr(const nasal::ContextWrapper &ctx)
static naRef f_createWindow(const nasal::CallContext &ctx)
Create new Window and get ghost for it.
nasal::Ghost< sc::LayoutRef > NasalLayout
static naRef f_newGridLayout(const nasal::CallContext &ctx)
nasal::Ghost< sc::EventPtr > NasalEvent
static naRef f_getCanvas(const nasal::CallContext &ctx)
Get ghost for existing Canvas.
nasal::Ghost< sc::KeyboardEventPtr > NasalKeyboardEvent
void setInputFocus(const simgear::canvas::WindowPtr &window)
Set the input (keyboard) focus to the given window.
Definition gui_mgr.cxx:745
simgear::canvas::WindowPtr createWindow(const std::string &name="")
Definition gui_mgr.cxx:657
void ungrabPointer(const simgear::canvas::WindowPtr &window)
Releases the grab acquired for this window with grabPointer().
Definition gui_mgr.cxx:757
implementation of SGAbstractBinding which invokes a Nasal callback.
std::function< void(naRef)> NasalCallback
const char * name
FGGlobals * globals
Definition globals.cxx:142
SGPropertyNode * ghostToPropNode(naRef ref)
CustomEventDetailWrapper(const sc::CustomEventPtr &event)
bool _get(const std::string &key, std::string &value_out) const
sc::CustomEventPtr _event
bool _set(const std::string &key, const std::string &value)