4 * Created on: 03.07.2012
12 #include "CanvasWidget.hxx"
14 #include <Canvas/canvas_mgr.hxx>
15 #include <Main/fg_os.hxx> // fgGetKeyModifiers()
16 #include <Scripting/NasalSys.hxx>
18 //------------------------------------------------------------------------------
19 CanvasWidget::CanvasWidget( int x, int y,
20 int width, int height,
21 SGPropertyNode* props,
22 const std::string& module ):
23 puObject(x, y, width, height),
24 _canvas_mgr( dynamic_cast<CanvasMgr*>(globals->get_subsystem("Canvas")) ),
30 SG_LOG(SG_GENERAL, SG_ALERT, "CanvasWidget: failed to get canvas manager!");
34 // Get the first unused canvas slot
35 SGPropertyNode* canvas_root = fgGetNode("/canvas/by-index", true);
36 for(int index = 0;; ++index)
38 if( !canvas_root->getChild("texture", index) )
41 // Get canvas viewport size. If not specified use the widget dimensions
42 props->getIntValue("view[0]", width),
43 props->getIntValue("view[1]", height)
45 _canvas = canvas_root->getChild("texture", index, true);
46 _canvas->setIntValue("size[0]", view[0] * 2); // use higher resolution
47 _canvas->setIntValue("size[1]", view[1] * 2); // for antialias
48 _canvas->setIntValue("view[0]", view[0]);
49 _canvas->setIntValue("view[1]", view[1]);
50 _canvas->setBoolValue("render-always", true);
51 _canvas->setStringValue( "name",
52 props->getStringValue("name", "gui-anonymous") );
53 SGPropertyNode* input = _canvas->getChild("input", 0, true);
54 _mouse_x = input->getChild("mouse-x", 0, true);
55 _mouse_y = input->getChild("mouse-y", 0, true);
56 _mouse_down = input->getChild("mouse-down", 0, true);
57 _mouse_drag = input->getChild("mouse-drag", 0, true);
59 SGPropertyNode *nasal = props->getNode("nasal");
64 dynamic_cast<FGNasalSys*>(globals->get_subsystem("nasal"));
68 "CanvasWidget: Failed to get nasal subsystem!" );
70 const std::string file = std::string("__canvas:")
71 + _canvas->getStringValue("name");
73 SGPropertyNode *load = nasal->getNode("load");
76 const char *s = load->getStringValue();
77 nas->handleCommand(module.c_str(), file.c_str(), s, _canvas);
84 //------------------------------------------------------------------------------
85 CanvasWidget::~CanvasWidget()
89 ->removeChild(_canvas->getName(), _canvas->getIndex(), false);
92 //------------------------------------------------------------------------------
93 void CanvasWidget::doHit(int button, int updown, int x, int y)
95 puObject::doHit(button, updown, x, y);
97 // CTRL allows resizing and SHIFT allows moving the window
98 if( fgGetKeyModifiers() & (KEYMOD_CTRL | KEYMOD_SHIFT) )
101 _mouse_x->setIntValue(x - abox.min[0]);
102 _mouse_y->setIntValue(abox.max[1] - y);
104 if( updown == PU_DRAG )
105 _mouse_drag->setIntValue(button);
106 else if( updown == PU_DOWN )
107 _mouse_down->setIntValue(button);
109 if( button != active_mouse_button )
113 puDeactivateWidget();
114 else if (updown == PU_DOWN)
115 puSetActiveWidget(this, x, y);
118 //------------------------------------------------------------------------------
119 int CanvasWidget::checkKey(int key, int updown)
121 return puObject::checkKey(key, updown);
124 //------------------------------------------------------------------------------
125 void CanvasWidget::setSize(int w, int h)
127 puObject::setSize(w, h);
129 _canvas->setIntValue("view[0]", w);
130 _canvas->setIntValue("view[1]", h);
133 //------------------------------------------------------------------------------
134 void CanvasWidget::draw(int dx, int dy)
138 _tex_id = _canvas_mgr->getCanvasTexId(_canvas->getIndex());
140 // Normally we should be able to get the texture after one frame. I don't
141 // know if there are circumstances where it can take longer, so we don't
142 // log a warning message until we have tried a few times.
145 if( ++_no_tex_cnt == 5 )
146 SG_LOG(SG_GENERAL, SG_WARN, "CanvasWidget: failed to get texture!");
151 if( _no_tex_cnt >= 5 )
156 "CanvasWidget: got texture after " << _no_tex_cnt << " tries."
162 glEnable(GL_TEXTURE_2D);
163 glBindTexture(GL_TEXTURE_2D, _tex_id);
166 glTexCoord2f(0,0); glVertex2f(dx + abox.min[0], dy + abox.min[1]);
167 glTexCoord2f(1,0); glVertex2f(dx + abox.max[0], dy + abox.min[1]);
168 glTexCoord2f(1,1); glVertex2f(dx + abox.max[0], dy + abox.max[1]);
169 glTexCoord2f(0,1); glVertex2f(dx + abox.min[0], dy + abox.max[1]);
171 glDisable(GL_TEXTURE_2D);