-/*
- * CanvasWidget.cxx
- *
- * Created on: 03.07.2012
- * Author: tom
- */
+// Airports forward declarations
+//
+// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef HAVE_CONFIG_H
# include <config.h>
#include <Main/fg_os.hxx> // fgGetKeyModifiers()
#include <Scripting/NasalSys.hxx>
+#include <simgear/canvas/Canvas.hxx>
+#include <simgear/canvas/MouseEvent.hxx>
+
+SGPropertyNode_ptr CanvasWidget::_time,
+ CanvasWidget::_view_height;
+
//------------------------------------------------------------------------------
CanvasWidget::CanvasWidget( int x, int y,
int width, int height,
const std::string& module ):
puObject(x, y, width, height),
_canvas_mgr( dynamic_cast<CanvasMgr*>(globals->get_subsystem("Canvas")) ),
- _tex_id(0),
- _no_tex_cnt(0)
+ _last_x(0),
+ _last_y(0),
+ // automatically resize viewport of canvas if no size is given
+ _auto_viewport( !props->hasChild("view") )
{
if( !_canvas_mgr )
{
return;
}
- // Get the first unused canvas slot
- SGPropertyNode* canvas_root = fgGetNode("/canvas/by-index", true);
- for(int index = 0;; ++index)
+ _canvas = _canvas_mgr->createCanvas
+ (
+ props->getStringValue("name", "gui-anonymous")
+ );
+
+ int view[2] = {
+ // Get canvas viewport size. If not specified use the widget dimensions
+ props->getIntValue("view[0]", width),
+ props->getIntValue("view[1]", height)
+ };
+
+ SGPropertyNode* cprops = _canvas->getProps();
+ cprops->setIntValue("size[0]", view[0] * 2); // use higher resolution
+ cprops->setIntValue("size[1]", view[1] * 2); // for antialias
+ cprops->setIntValue("view[0]", view[0]);
+ cprops->setIntValue("view[1]", view[1]);
+ cprops->setBoolValue("render-always", true);
+ cprops->setStringValue( "name",
+ props->getStringValue("name", "gui-anonymous") );
+
+ SGPropertyNode *nasal = props->getNode("nasal");
+ if( !nasal )
+ return;
+
+ FGNasalSys *nas = dynamic_cast<FGNasalSys*>(globals->get_subsystem("nasal"));
+ if( !nas )
+ SG_LOG( SG_GENERAL,
+ SG_ALERT,
+ "CanvasWidget: Failed to get nasal subsystem!" );
+
+ const std::string file = std::string("__canvas:")
+ + cprops->getStringValue("name");
+
+ SGPropertyNode *load = nasal->getNode("load");
+ if( load )
{
- if( !canvas_root->getChild("texture", index) )
- {
- int view[2] = {
- // Get canvas viewport size. If not specified use the widget dimensions
- props->getIntValue("view[0]", width),
- props->getIntValue("view[1]", height)
- };
- _canvas = canvas_root->getChild("texture", index, true);
- _canvas->setIntValue("size[0]", view[0] * 2); // use higher resolution
- _canvas->setIntValue("size[1]", view[1] * 2); // for antialias
- _canvas->setIntValue("view[0]", view[0]);
- _canvas->setIntValue("view[1]", view[1]);
- _canvas->setBoolValue("render-always", true);
- _canvas->setStringValue( "name",
- props->getStringValue("name", "gui-anonymous") );
- SGPropertyNode* input = _canvas->getChild("input", 0, true);
- _mouse_x = input->getChild("mouse-x", 0, true);
- _mouse_y = input->getChild("mouse-y", 0, true);
- _mouse_down = input->getChild("mouse-down", 0, true);
- _mouse_drag = input->getChild("mouse-drag", 0, true);
-
- SGPropertyNode *nasal = props->getNode("nasal");
- if( !nasal )
- break;
-
- FGNasalSys *nas =
- dynamic_cast<FGNasalSys*>(globals->get_subsystem("nasal"));
- if( !nas )
- SG_LOG( SG_GENERAL,
- SG_ALERT,
- "CanvasWidget: Failed to get nasal subsystem!" );
-
- const std::string file = std::string("__canvas:")
- + _canvas->getStringValue("name");
-
- SGPropertyNode *load = nasal->getNode("load");
- if( load )
- {
- const char *s = load->getStringValue();
- nas->handleCommand(module.c_str(), file.c_str(), s, _canvas);
- }
- break;
- }
+ const char *s = load->getStringValue();
+ nas->handleCommand(module.c_str(), file.c_str(), s, cprops);
}
}
CanvasWidget::~CanvasWidget()
{
if( _canvas )
- _canvas->getParent()
- ->removeChild(_canvas->getName(), _canvas->getIndex(), false);
+ // TODO check if really not in use anymore
+ _canvas->getProps()
+ ->getParent()
+ ->removeChild( _canvas->getProps()->getName(),
+ _canvas->getProps()->getIndex(),
+ false );
}
+// Old versions of PUI are missing this defines...
+#ifndef PU_SCROLL_UP_BUTTON
+# define PU_SCROLL_UP_BUTTON 3
+#endif
+#ifndef PU_SCROLL_DOWN_BUTTON
+# define PU_SCROLL_DOWN_BUTTON 4
+#endif
+
//------------------------------------------------------------------------------
void CanvasWidget::doHit(int button, int updown, int x, int y)
{
if( fgGetKeyModifiers() & (KEYMOD_CTRL | KEYMOD_SHIFT) )
return;
- _mouse_x->setIntValue(x - abox.min[0]);
- _mouse_y->setIntValue(abox.max[1] - y);
+ namespace sc = simgear::canvas;
+ sc::MouseEventPtr event(new sc::MouseEvent);
- if( updown == PU_DRAG )
- _mouse_drag->setIntValue(button);
- else if( updown == PU_DOWN )
- _mouse_down->setIntValue(button);
+ if( !_time )
+ _time = globals->get_props()->getNode("/sim/time/elapsed-sec");
+ event->time = _time->getDoubleValue();
- if( button != active_mouse_button )
- return;
+ if( !_view_height )
+ _view_height = globals->get_props()->getNode("/sim/gui/canvas/size[1]");
+ event->screen_pos.set(x, _view_height->getIntValue() - y);
+
+ event->client_pos.set(x - abox.min[0], abox.max[1] - y);
+ event->delta.set( event->getScreenX() - _last_x,
+ event->getScreenY() - _last_y );
+
+ _last_x = event->getScreenX();
+ _last_y = event->getScreenY();
+
+ switch( button )
+ {
+ case PU_LEFT_BUTTON:
+ event->button = osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON;
+ break;
+ case PU_MIDDLE_BUTTON:
+ event->button = osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON;
+ break;
+ case PU_RIGHT_BUTTON:
+ event->button = osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON;
+ break;
+ case PU_SCROLL_UP_BUTTON:
+ case PU_SCROLL_DOWN_BUTTON:
+ // Only let PU_DOWN trigger a scroll wheel event
+ if( updown != PU_DOWN )
+ return;
+
+ event->type = sc::Event::WHEEL;
+ event->delta.y() = button == PU_SCROLL_UP_BUTTON ? 1 : -1;
- if (updown == PU_UP)
- puDeactivateWidget();
- else if (updown == PU_DOWN)
- puSetActiveWidget(this, x, y);
+ _canvas->handleMouseEvent(event);
+
+ return;
+ default:
+ SG_LOG(SG_INPUT, SG_WARN, "CanvasWidget: Unknown button: " << button);
+ return;
+ }
+
+ switch( updown )
+ {
+ case PU_DOWN:
+ event->type = sc::Event::MOUSE_DOWN;
+ puSetActiveWidget(this, x, y);
+ break;
+ case PU_UP:
+ event->type = sc::Event::MOUSE_UP;
+ puDeactivateWidget();
+ break;
+ case PU_DRAG:
+ event->type = sc::Event::DRAG;
+ break;
+ default:
+ SG_LOG(SG_INPUT, SG_WARN, "CanvasWidget: Unknown updown: " << updown);
+ return;
+ }
+
+ _canvas->handleMouseEvent(event);
}
//------------------------------------------------------------------------------
{
puObject::setSize(w, h);
- _canvas->setIntValue("view[0]", w);
- _canvas->setIntValue("view[1]", h);
+ if( _auto_viewport )
+ {
+ _canvas->getProps()->setIntValue("view[0]", w);
+ _canvas->getProps()->setIntValue("view[1]", h);
+ }
}
//------------------------------------------------------------------------------
void CanvasWidget::draw(int dx, int dy)
{
- if( !_tex_id )
- {
- _tex_id = _canvas_mgr->getCanvasTexId(_canvas->getIndex());
-
- // Normally we should be able to get the texture after one frame. I don't
- // know if there are circumstances where it can take longer, so we don't
- // log a warning message until we have tried a few times.
- if( !_tex_id )
- {
- if( ++_no_tex_cnt == 5 )
- SG_LOG(SG_GENERAL, SG_WARN, "CanvasWidget: failed to get texture!");
- return;
- }
- else
- {
- if( _no_tex_cnt >= 5 )
- SG_LOG
- (
- SG_GENERAL,
- SG_INFO,
- "CanvasWidget: got texture after " << _no_tex_cnt << " tries."
- );
- _no_tex_cnt = 0;
- }
- }
-
glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, _tex_id);
+ glBindTexture(GL_TEXTURE_2D, _canvas_mgr->getCanvasTexId(_canvas));
glBegin( GL_QUADS );
glColor3f(1,1,1);
glTexCoord2f(0,0); glVertex2f(dx + abox.min[0], dy + abox.min[1]);