]> git.mxchange.org Git - flightgear.git/blob - src/Scripting/NasalCanvas.cxx
Clean up CanvasWidget and more work on Canvas/Nasal bindings
[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 <Main/globals.hxx>
28 #include <Scripting/NasalSys.hxx>
29
30 #include <osgGA/GUIEventAdapter>
31
32 #include <simgear/sg_inlines.h>
33
34 #include <simgear/canvas/Canvas.hxx>
35 #include <simgear/canvas/elements/CanvasElement.hxx>
36
37 #include <simgear/nasal/cppbind/from_nasal.hxx>
38 #include <simgear/nasal/cppbind/to_nasal.hxx>
39 #include <simgear/nasal/cppbind/NasalHash.hxx>
40 #include <simgear/nasal/cppbind/Ghost.hxx>
41
42 extern naRef propNodeGhostCreate(naContext c, SGPropertyNode* n);
43
44 namespace sc = simgear::canvas;
45
46 template<class Element>
47 naRef elementGetNode(naContext c, Element& element)
48 {
49   return propNodeGhostCreate(c, element.getProps());
50 }
51
52 typedef nasal::Ghost<sc::CanvasPtr> NasalCanvas;
53 typedef nasal::Ghost<sc::ElementPtr> NasalElement;
54 typedef nasal::Ghost<sc::GroupPtr> NasalGroup;
55
56 #if 0
57 typedef osg::ref_ptr<osgGA::GUIEventAdapter> GUIEventPtr;
58
59 class NasalCanvasEvent:
60   public NasalObject<GUIEventPtr, NasalCanvasEvent>
61 {
62   public:
63
64     naRef getEventType(naContext c, const GUIEventPtr& event)
65     {
66 #define RET_EVENT_STR(type, str)\
67   case osgGA::GUIEventAdapter::type:\
68     return nasal::to_nasal(c, str);
69
70       switch( event->getEventType() )
71       {
72         RET_EVENT_STR(PUSH,         "push");
73         RET_EVENT_STR(RELEASE,      "release");
74         RET_EVENT_STR(DOUBLECLICK,  "double-click");
75         RET_EVENT_STR(DRAG,         "drag");
76         RET_EVENT_STR(MOVE,         "move");
77         RET_EVENT_STR(SCROLL,       "scroll");
78         RET_EVENT_STR(KEYUP,        "key-up");
79         RET_EVENT_STR(KEYDOWN,      "key-down");
80
81 #undef RET_EVENT_STR
82
83         default:
84           return naNil();
85       }
86     }
87 };
88 #endif
89
90 SGPropertyNode& requireArg(naContext c, int argc, naRef* args, int index = 0)
91 {
92   if( argc <= index )
93     naRuntimeError(c, "missing argument #%d", index);
94
95   SGPropertyNode* props = ghostToPropNode(args[index]);
96   if( !props )
97     naRuntimeError(c, "arg #%d: not a SGPropertyNode ghost");
98
99   return *props;
100 }
101
102 CanvasMgr& requireCanvasMgr(naContext c)
103 {
104   CanvasMgr* canvas_mgr =
105     static_cast<CanvasMgr*>(globals->get_subsystem("Canvas"));
106   if( !canvas_mgr )
107     naRuntimeError(c, "Failed to get Canvas subsystem");
108
109   return *canvas_mgr;
110 }
111
112 /**
113  * Create new Canvas and get ghost for it.
114  */
115 static naRef f_createCanvas(naContext c, naRef me, int argc, naRef* args)
116 {
117   return NasalCanvas::create(c, requireCanvasMgr(c).createCanvas());
118 }
119
120 /**
121  * Get ghost for existing Canvas.
122  */
123 static naRef f_getCanvas(naContext c, naRef me, int argc, naRef* args)
124 {
125   SGPropertyNode& props = requireArg(c, argc, args);
126   CanvasMgr& canvas_mgr = requireCanvasMgr(c);
127
128   sc::CanvasPtr canvas;
129   if( canvas_mgr.getPropertyRoot() == props.getParent() )
130   {
131     // get a canvas specified by its root node
132     canvas = canvas_mgr.getCanvas( props.getIndex() );
133     if( !canvas || canvas->getProps() != &props )
134       return naNil();
135   }
136   else
137   {
138     // get a canvas by name
139     if( props.hasValue("name") )
140       canvas = canvas_mgr.getCanvas( props.getStringValue("name") );
141     else if( props.hasValue("index") )
142       canvas = canvas_mgr.getCanvas( props.getIntValue("index") );
143   }
144
145   return NasalCanvas::create(c, canvas);
146 }
147
148 naRef f_canvasCreateGroup( sc::Canvas& canvas,
149                            naContext c,
150                            int argc,
151                            naRef* args )
152 {
153   std::string name;
154   if( argc > 0 )
155     name = nasal::from_nasal<std::string>(c, args[0]);
156
157   return NasalGroup::create(c, canvas.createGroup(name));
158 }
159
160 naRef initNasalCanvas(naRef globals, naContext c, naRef gcSave)
161 {
162   NasalCanvas::init("Canvas")
163     .member("_node_ghost", &elementGetNode<sc::Canvas>)
164     .member("size_x", &sc::Canvas::getSizeX)
165     .member("size_y", &sc::Canvas::getSizeY)
166     .method_func<&f_canvasCreateGroup>("createGroup");
167   NasalElement::init("canvas.Element")
168     .member("_node_ghost", &elementGetNode<sc::Element>);
169   NasalGroup::init("canvas.Group")
170     .bases<NasalElement>();
171
172   nasal::Hash globals_module(globals, c),
173               canvas_module = globals_module.createHash("canvas");
174
175   canvas_module.set("_newCanvasGhost", f_createCanvas);
176   canvas_module.set("_getCanvasGhost", f_getCanvas);
177
178   return naNil();
179 }