4 * Created on: 03.07.2012
8 #include "CanvasWidget.hxx"
10 #include <Canvas/canvas_mgr.hxx>
11 #include <Main/fg_os.hxx> // fgGetKeyModifiers()
12 #include <Scripting/NasalSys.hxx>
14 //------------------------------------------------------------------------------
15 CanvasWidget::CanvasWidget( int x, int y,
16 int width, int height,
17 SGPropertyNode* props,
18 const std::string& module ):
19 puObject(x, y, width, height),
20 _canvas_mgr( dynamic_cast<CanvasMgr*>(globals->get_subsystem("Canvas")) ),
26 SG_LOG(SG_GENERAL, SG_ALERT, "CanvasWidget: failed to get canvas manager!");
30 // Get the first unused canvas slot
31 SGPropertyNode* canvas_root = fgGetNode("/canvas", true);
32 for(int index = 0;; ++index)
34 if( !canvas_root->getChild("texture", index) )
37 // Get canvas viewport size. If not specified use the widget dimensions
38 props->getIntValue("view[0]", width),
39 props->getIntValue("view[1]", height)
41 _canvas = canvas_root->getChild("texture", index, true);
42 _canvas->setIntValue("size[0]", view[0] * 2); // use higher resolution
43 _canvas->setIntValue("size[1]", view[1] * 2); // for antialias
44 _canvas->setIntValue("view[0]", view[0]);
45 _canvas->setIntValue("view[1]", view[1]);
46 _canvas->setBoolValue("render-always", true);
47 _canvas->setStringValue( "name",
48 props->getStringValue("name", "gui-anonymous") );
49 SGPropertyNode* input = _canvas->getChild("input", 0, true);
50 _mouse_x = input->getChild("mouse-x", 0, true);
51 _mouse_y = input->getChild("mouse-y", 0, true);
52 _mouse_down = input->getChild("mouse-down", 0, true);
53 _mouse_drag = input->getChild("mouse-drag", 0, true);
55 SGPropertyNode *nasal = props->getNode("nasal");
60 dynamic_cast<FGNasalSys*>(globals->get_subsystem("nasal"));
64 "CanvasWidget: Failed to get nasal subsystem!" );
66 const std::string file = std::string("__canvas:")
67 + _canvas->getStringValue("name");
69 SGPropertyNode *load = nasal->getNode("load");
72 const char *s = load->getStringValue();
73 nas->handleCommand(module.c_str(), file.c_str(), s, _canvas);
80 //------------------------------------------------------------------------------
81 CanvasWidget::~CanvasWidget()
85 ->removeChild(_canvas->getName(), _canvas->getIndex(), false);
88 //------------------------------------------------------------------------------
89 void CanvasWidget::doHit(int button, int updown, int x, int y)
91 puObject::doHit(button, updown, x, y);
93 // CTRL allows resizing and SHIFT allows moving the window
94 if( fgGetKeyModifiers() & (KEYMOD_CTRL | KEYMOD_SHIFT) )
97 _mouse_x->setIntValue(x - abox.min[0]);
98 _mouse_y->setIntValue(y - abox.min[1]);
100 if( updown == PU_DRAG )
101 _mouse_drag->setIntValue(button);
102 else if( updown == PU_DOWN )
103 _mouse_down->setIntValue(button);
105 if( button != active_mouse_button )
109 puDeactivateWidget();
110 else if (updown == PU_DOWN)
111 puSetActiveWidget(this, x, y);
114 //------------------------------------------------------------------------------
115 int CanvasWidget::checkKey(int key, int updown)
117 return puObject::checkKey(key, updown);
120 //------------------------------------------------------------------------------
121 void CanvasWidget::setSize(int w, int h)
123 puObject::setSize(w, h);
125 _canvas->setIntValue("view[0]", w);
126 _canvas->setIntValue("view[1]", h);
129 //------------------------------------------------------------------------------
130 void CanvasWidget::draw(int dx, int dy)
134 _tex_id = _canvas_mgr->getCanvasTexId(_canvas->getIndex());
136 // Normally we should be able to get the texture after one frame. I don't
137 // know if there are circumstances where it can take longer, so we don't
138 // log a warning message until we have tried a few times.
141 if( ++_no_tex_cnt == 5 )
142 SG_LOG(SG_GENERAL, SG_WARN, "CanvasWidget: failed to get texture!");
147 if( _no_tex_cnt >= 5 )
152 "CanvasWidget: got texture after " << _no_tex_cnt << " tries."
158 glEnable(GL_TEXTURE_2D);
159 glBindTexture(GL_TEXTURE_2D, _tex_id);
162 glTexCoord2f(0,0); glVertex2f(dx + abox.min[0], dy + abox.min[1]);
163 glTexCoord2f(1,0); glVertex2f(dx + abox.max[0], dy + abox.min[1]);
164 glTexCoord2f(1,1); glVertex2f(dx + abox.max[0], dy + abox.max[1]);
165 glTexCoord2f(0,1); glVertex2f(dx + abox.min[0], dy + abox.max[1]);
167 glDisable(GL_TEXTURE_2D);