X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FGUI%2FCanvasWidget.cxx;h=fc21d0c93cb1acfed2abd64a6061a129e2aa9a7f;hb=02a5261797998841e2c3d8580385e68a5d319929;hp=fea0f150f0667209db5956a949c5fc7eb07ccdbd;hpb=766014883c0fa89d3c86a3ea4751c502738736da;p=flightgear.git diff --git a/src/GUI/CanvasWidget.cxx b/src/GUI/CanvasWidget.cxx index fea0f150f..fc21d0c93 100644 --- a/src/GUI/CanvasWidget.cxx +++ b/src/GUI/CanvasWidget.cxx @@ -1,9 +1,20 @@ -/* - * CanvasWidget.cxx - * - * Created on: 03.07.2012 - * Author: tom - */ +// Airports forward declarations +// +// Copyright (C) 2012 Thomas Geymayer +// +// 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 @@ -15,6 +26,12 @@ #include
// fgGetKeyModifiers() #include +#include +#include + +SGPropertyNode_ptr CanvasWidget::_time, + CanvasWidget::_view_height; + //------------------------------------------------------------------------------ CanvasWidget::CanvasWidget( int x, int y, int width, int height, @@ -22,8 +39,10 @@ CanvasWidget::CanvasWidget( int x, int y, const std::string& module ): puObject(x, y, width, height), _canvas_mgr( dynamic_cast(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 ) { @@ -31,53 +50,44 @@ CanvasWidget::CanvasWidget( int x, int y, return; } - // Get the first unused canvas slot - SGPropertyNode* canvas_root = fgGetNode("/canvas", 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(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(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); } } @@ -85,10 +95,17 @@ CanvasWidget::CanvasWidget( int x, int y, CanvasWidget::~CanvasWidget() { if( _canvas ) - _canvas->getParent() - ->removeChild(_canvas->getName(), _canvas->getIndex(), false); + _canvas->destroy(); } +// 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) { @@ -98,21 +115,71 @@ 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); } //------------------------------------------------------------------------------ @@ -126,41 +193,18 @@ void CanvasWidget::setSize(int w, int h) { 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]);