]> git.mxchange.org Git - flightgear.git/blob - src/Scripting/NasalCanvas.cxx
Canvas: update for new bounding box getters.
[flightgear.git] / src / Scripting / NasalCanvas.cxx
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 #ifdef HAVE_CONFIG_H
22 #  include "config.h"
23 #endif
24
25 #include "NasalCanvas.hxx"
26 #include <Canvas/canvas_mgr.hxx>
27 #include <Canvas/gui_mgr.hxx>
28 #include <Canvas/window.hxx>
29 #include <Main/globals.hxx>
30 #include <Scripting/NasalSys.hxx>
31
32 #include <osgGA/GUIEventAdapter>
33
34 #include <simgear/sg_inlines.h>
35
36 #include <simgear/canvas/Canvas.hxx>
37 #include <simgear/canvas/elements/CanvasElement.hxx>
38 #include <simgear/canvas/elements/CanvasText.hxx>
39 #include <simgear/canvas/MouseEvent.hxx>
40
41 #include <simgear/nasal/cppbind/from_nasal.hxx>
42 #include <simgear/nasal/cppbind/to_nasal.hxx>
43 #include <simgear/nasal/cppbind/NasalHash.hxx>
44 #include <simgear/nasal/cppbind/Ghost.hxx>
45
46 extern naRef propNodeGhostCreate(naContext c, SGPropertyNode* n);
47
48 namespace sc = simgear::canvas;
49
50 template<class Element>
51 naRef elementGetNode(naContext c, Element& element)
52 {
53   return propNodeGhostCreate(c, element.getProps());
54 }
55
56 typedef nasal::Ghost<sc::EventPtr> NasalEvent;
57 typedef nasal::Ghost<sc::MouseEventPtr> NasalMouseEvent;
58 typedef nasal::Ghost<sc::CanvasPtr> NasalCanvas;
59 typedef nasal::Ghost<sc::ElementPtr> NasalElement;
60 typedef nasal::Ghost<sc::GroupPtr> NasalGroup;
61 typedef nasal::Ghost<sc::TextPtr> NasalText;
62 typedef nasal::Ghost<canvas::WindowWeakPtr> NasalWindow;
63
64 naRef to_nasal_helper(naContext c, const osg::BoundingBox& bb)
65 {
66   std::vector<float> bb_vec(4);
67   bb_vec[0] = bb._min.x();
68   bb_vec[1] = bb._min.y();
69   bb_vec[2] = bb._max.x();
70   bb_vec[3] = bb._max.y();
71
72   return nasal::to_nasal(c, bb_vec);
73 }
74
75 SGPropertyNode* from_nasal_helper(naContext c, naRef ref, SGPropertyNode**)
76 {
77   SGPropertyNode* props = ghostToPropNode(ref);
78   if( !props )
79     naRuntimeError(c, "Not a SGPropertyNode ghost.");
80
81   return props;
82 }
83
84 CanvasMgr& requireCanvasMgr(naContext c)
85 {
86   CanvasMgr* canvas_mgr =
87     static_cast<CanvasMgr*>(globals->get_subsystem("Canvas"));
88   if( !canvas_mgr )
89     naRuntimeError(c, "Failed to get Canvas subsystem");
90
91   return *canvas_mgr;
92 }
93
94 GUIMgr& requireGUIMgr(naContext c)
95 {
96   GUIMgr* mgr =
97     static_cast<GUIMgr*>(globals->get_subsystem("CanvasGUI"));
98   if( !mgr )
99     naRuntimeError(c, "Failed to get CanvasGUI subsystem");
100
101   return *mgr;
102 }
103
104 /**
105  * Create new Canvas and get ghost for it.
106  */
107 static naRef f_createCanvas(const nasal::CallContext& ctx)
108 {
109   return NasalCanvas::create(ctx.c, requireCanvasMgr(ctx.c).createCanvas());
110 }
111
112 /**
113  * Create new Window and get ghost for it.
114  */
115 static naRef f_createWindow(const nasal::CallContext& ctx)
116 {
117   return NasalWindow::create
118   (
119     ctx.c,
120     requireGUIMgr(ctx.c).createWindow( ctx.getArg<std::string>(0) )
121   );
122 }
123
124 /**
125  * Get ghost for existing Canvas.
126  */
127 static naRef f_getCanvas(naContext c, naRef me, int argc, naRef* args)
128 {
129   nasal::CallContext ctx(c, argc, args);
130   SGPropertyNode& props = *ctx.requireArg<SGPropertyNode*>(0);
131   CanvasMgr& canvas_mgr = requireCanvasMgr(c);
132
133   sc::CanvasPtr canvas;
134   if( canvas_mgr.getPropertyRoot() == props.getParent() )
135   {
136     // get a canvas specified by its root node
137     canvas = canvas_mgr.getCanvas( props.getIndex() );
138     if( !canvas || canvas->getProps() != &props )
139       return naNil();
140   }
141   else
142   {
143     // get a canvas by name
144     if( props.hasValue("name") )
145       canvas = canvas_mgr.getCanvas( props.getStringValue("name") );
146     else if( props.hasValue("index") )
147       canvas = canvas_mgr.getCanvas( props.getIntValue("index") );
148   }
149
150   return NasalCanvas::create(c, canvas);
151 }
152
153 naRef f_canvasCreateGroup(sc::Canvas& canvas, const nasal::CallContext& ctx)
154 {
155   return NasalGroup::create
156   (
157     ctx.c,
158     canvas.createGroup( ctx.getArg<std::string>(0) )
159   );
160 }
161
162 /**
163  * Get group containing all gui windows
164  */
165 naRef f_getDesktop(naContext c, naRef me, int argc, naRef* args)
166 {
167   return NasalGroup::create(c, requireGUIMgr(c).getDesktop());
168 }
169
170 naRef f_groupCreateChild(sc::Group& group, const nasal::CallContext& ctx)
171 {
172   return NasalElement::create
173   (
174     ctx.c,
175     group.createChild( ctx.requireArg<std::string>(0),
176                        ctx.getArg<std::string>(1) )
177   );
178 }
179
180 naRef f_groupGetChild(sc::Group& group, const nasal::CallContext& ctx)
181 {
182   return NasalElement::create
183   (
184     ctx.c,
185     group.getChild( ctx.requireArg<SGPropertyNode*>(0) )
186   );
187 }
188
189 naRef f_groupGetElementById(sc::Group& group, const nasal::CallContext& ctx)
190 {
191   return NasalElement::create
192   (
193     ctx.c,
194     group.getElementById( ctx.requireArg<std::string>(0) )
195   );
196 }
197
198 template<int Mask>
199 naRef f_eventGetModifier(naContext, sc::MouseEvent& event)
200 {
201   return naNum((event.getModifiers() & Mask) != 0);
202 }
203
204 naRef to_nasal_helper(naContext c, const sc::ElementWeakPtr& el)
205 {
206   return NasalElement::create(c, el.lock());
207 }
208
209 naRef initNasalCanvas(naRef globals, naContext c)
210 {
211   using osgGA::GUIEventAdapter;
212   NasalEvent::init("canvas.Event")
213     .member("type", &sc::Event::getTypeString)
214     .member("target", &sc::Event::getTarget)
215     .member("currentTarget", &sc::Event::getCurrentTarget)
216     .method("stopPropagation", &sc::Event::stopPropagation);
217   NasalMouseEvent::init("canvas.MouseEvent")
218     .bases<NasalEvent>()
219     .member("screenX", &sc::MouseEvent::getScreenX)
220     .member("screenY", &sc::MouseEvent::getScreenY)
221     .member("clientX", &sc::MouseEvent::getClientX)
222     .member("clientY", &sc::MouseEvent::getClientY)
223     .member("localX", &sc::MouseEvent::getLocalX)
224     .member("localY", &sc::MouseEvent::getLocalY)
225     .member("deltaX", &sc::MouseEvent::getDeltaX)
226     .member("deltaY", &sc::MouseEvent::getDeltaY)
227     .member("button", &sc::MouseEvent::getButton)
228     .member("buttons", &sc::MouseEvent::getButtonMask)
229     .member("modifiers", &sc::MouseEvent::getModifiers)
230     .member("ctrlKey", &f_eventGetModifier<GUIEventAdapter::MODKEY_CTRL>)
231     .member("shiftKey", &f_eventGetModifier<GUIEventAdapter::MODKEY_SHIFT>)
232     .member("altKey", &f_eventGetModifier<GUIEventAdapter::MODKEY_ALT>)
233     .member("metaKey", &f_eventGetModifier<GUIEventAdapter::MODKEY_META>)
234     .member("click_count", &sc::MouseEvent::getCurrentClickCount);
235   NasalCanvas::init("Canvas")
236     .member("_node_ghost", &elementGetNode<sc::Canvas>)
237     .member("size_x", &sc::Canvas::getSizeX)
238     .member("size_y", &sc::Canvas::getSizeY)
239     .method("_createGroup", &f_canvasCreateGroup)
240     .method("_getGroup", &sc::Canvas::getGroup)
241     .method("addEventListener", &sc::Canvas::addEventListener);
242   NasalElement::init("canvas.Element")
243     .member("_node_ghost", &elementGetNode<sc::Element>)
244     .method("_getParent", &sc::Element::getParent)
245     .method("addEventListener", &sc::Element::addEventListener)
246     .method("getBoundingBox", &sc::Element::getBoundingBox)
247     .method("getTightBoundingBox", &sc::Element::getTightBoundingBox);
248   NasalGroup::init("canvas.Group")
249     .bases<NasalElement>()
250     .method("_createChild", &f_groupCreateChild)
251     .method("_getChild", &f_groupGetChild)
252     .method("_getElementById", &f_groupGetElementById);
253   NasalText::init("canvas.Text")
254     .bases<NasalElement>()
255     .method("getNearestCursor", &sc::Text::getNearestCursor);
256
257   NasalWindow::init("canvas.Window")
258     .bases<NasalElement>()
259     .member("_node_ghost", &elementGetNode<canvas::Window>)
260     .method("_getCanvasDecoration", &canvas::Window::getCanvasDecoration);
261     
262   nasal::Hash globals_module(globals, c),
263               canvas_module = globals_module.createHash("canvas");
264
265   canvas_module.set("_newCanvasGhost", f_createCanvas);
266   canvas_module.set("_newWindowGhost", f_createWindow);
267   canvas_module.set("_getCanvasGhost", f_getCanvas);
268   canvas_module.set("_getDesktopGhost", f_getDesktop);
269
270   return naNil();
271 }