X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCanvas%2Fgui_mgr.cxx;h=cfee29c0747a1cf3419cae75566320f1693a2b90;hb=0239e9c8c8f6b258e82fbf701f91ef191f21ee15;hp=0190ba9f6b0afd7f023522edfc52295daf3dc262;hpb=c9976155d67731cfcd7bd300840125b8c7be290b;p=flightgear.git diff --git a/src/Canvas/gui_mgr.cxx b/src/Canvas/gui_mgr.cxx index 0190ba9f6..cfee29c07 100644 --- a/src/Canvas/gui_mgr.cxx +++ b/src/Canvas/gui_mgr.cxx @@ -27,12 +27,14 @@ #include #include +#include #include #include #include #include +#include /** * Event handler @@ -46,7 +48,7 @@ class GUIEventHandler: {} bool handle( const osgGA::GUIEventAdapter& ea, - osgGA::GUIActionAdapter& aa, + osgGA::GUIActionAdapter&, osg::Object*, osg::NodeVisitor* ) { @@ -82,8 +84,8 @@ class WindowPlacement: canvas::WindowPtr window = _window.lock(); simgear::canvas::CanvasPtr canvas = _canvas.lock(); - if( window && canvas && canvas == window->getCanvas().lock() ) - window->setCanvas( simgear::canvas::CanvasPtr() ); + if( window && canvas && canvas == window->getCanvasContent().lock() ) + window->setCanvasContent( simgear::canvas::CanvasPtr() ); } private: @@ -91,48 +93,35 @@ class WindowPlacement: simgear::canvas::CanvasWeakPtr _canvas; }; -/** - * Store pointer to window as user data - */ -class WindowUserData: - public osg::Referenced -{ - public: - canvas::WindowWeakPtr window; - WindowUserData(canvas::WindowPtr window): - window(window) - {} -}; - -//------------------------------------------------------------------------------ -typedef boost::shared_ptr WindowPtr; -WindowPtr windowFactory(SGPropertyNode* node) -{ - return WindowPtr(new canvas::Window(node)); -} - //------------------------------------------------------------------------------ GUIMgr::GUIMgr(): - PropertyBasedMgr( fgGetNode("/sim/gui/canvas", true), - "window", - &windowFactory ), + Group(simgear::canvas::CanvasPtr(), fgGetNode("/sim/gui/canvas", true)), _event_handler( new GUIEventHandler(this) ), - _transform( new osg::MatrixTransform ), - _width(_props, "size[0]"), - _height(_props, "size[1]"), + _cb_mouse_mode( this, + &GUIMgr::handleMouseMode, + fgGetNode("/devices/status/mice/mouse[0]/mode") ), + _handle_events(true), + _width(_node, "size[0]"), + _height(_node, "size[1]"), _resize(canvas::Window::NONE), _last_cursor(MOUSE_CURSOR_NONE), + _last_x(-1), + _last_y(-1), _last_scroll_time(0) { + // We handle the property listener manually within ::init and ::shutdown. + removeListener(); + _width = _height = -1; + // Do not change values on reinit + _width.node()->setAttribute(SGPropertyNode::PRESERVE, true); + _height.node()->setAttribute(SGPropertyNode::PRESERVE, true); + osg::Camera* camera = flightgear::getGUICamera( flightgear::CameraGroup::getDefault() ); assert(camera); - camera->addChild(_transform); - - osg::Viewport* vp = camera->getViewport(); - handleResize(vp->x(), vp->y(), vp->width(), vp->height()); + camera->addChild( getMatrixTransform() ); simgear::canvas::Canvas::addPlacementFactory ( @@ -156,22 +145,44 @@ GUIMgr::GUIMgr(): stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); } +//------------------------------------------------------------------------------ +canvas::WindowPtr GUIMgr::createWindow(const std::string& name) +{ + canvas::WindowPtr window = createChild(name); + if( name.empty() ) + window->set + ( + "id", + boost::lexical_cast(window->getProps()->getIndex()) + ); + return window; +} + //------------------------------------------------------------------------------ void GUIMgr::init() { - PropertyBasedMgr::init(); + handleResize + ( + 0, + 0, + fgGetInt("/sim/startup/xsize"), + fgGetInt("/sim/startup/ysize") + ); globals->get_renderer() ->getViewer() ->getEventHandlers() // GUI is on top of everything so lets install as first event handler .push_front( _event_handler ); + + _node->addChangeListener(this); + _node->fireCreatedRecursive(); } //------------------------------------------------------------------------------ void GUIMgr::shutdown() { - PropertyBasedMgr::shutdown(); + _node->removeChangeListener(this); globals->get_renderer() ->getViewer() @@ -179,29 +190,9 @@ void GUIMgr::shutdown() } //------------------------------------------------------------------------------ -void GUIMgr::elementCreated(simgear::PropertyBasedElementPtr element) +void GUIMgr::update(double dt) { - canvas::WindowPtr window = - boost::static_pointer_cast(element); - - size_t layer_index = std::max(0, window->getProps()->getIntValue("layer", 1)); - osg::Group *layer = 0; - - if( layer_index < _transform->getNumChildren() ) - { - layer = _transform->getChild(layer_index)->asGroup(); - assert(layer); - } - else - { - while( _transform->getNumChildren() <= layer_index ) - { - layer = new osg::Group; - _transform->addChild(layer); - } - } - window->getGroup()->setUserData(new WindowUserData(window)); - layer->addChild(window->getGroup()); + Group::update(dt); } //------------------------------------------------------------------------------ @@ -229,9 +220,12 @@ bool GUIMgr::handleEvent(const osgGA::GUIEventAdapter& ea) } //------------------------------------------------------------------------------ -canvas::WindowPtr GUIMgr::getWindow(size_t i) +GUIMgr::ElementFactory GUIMgr::getChildFactory(const std::string& type) const { - return boost::static_pointer_cast(_elements[i]); + if( type == "window" ) + return &Element::create; + + return Group::getChildFactory(type); } //------------------------------------------------------------------------------ @@ -239,19 +233,13 @@ simgear::canvas::Placements GUIMgr::addPlacement( SGPropertyNode* node, simgear::canvas::CanvasPtr canvas ) { - int placement_index = node->getIntValue("index", -1); + const std::string& id = node->getStringValue("id"); simgear::canvas::Placements placements; - for( size_t i = 0; i < _elements.size(); ++i ) + canvas::WindowPtr window = getChild(id); + if( window ) { - if( placement_index >= 0 && static_cast(i) != placement_index ) - continue; - - canvas::WindowPtr window = getWindow(i); - if( !window ) - continue; - - window->setCanvas(canvas); + window->setCanvasContent(canvas); placements.push_back( simgear::canvas::PlacementPtr(new WindowPlacement(node, window, canvas)) ); @@ -281,12 +269,11 @@ const float resize_corner = 20; //------------------------------------------------------------------------------ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea) { - if( !_transform->getNumChildren() ) + if( !_transform->getNumChildren() || !_handle_events ) return false; namespace sc = simgear::canvas; - sc::MouseEventPtr event(new sc::MouseEvent); - event->time = ea.getTime(); + sc::MouseEventPtr event(new sc::MouseEvent(ea)); event->screen_pos.x() = 0.5 * (ea.getXnormalized() + 1) * _width + 0.5; event->screen_pos.y() = 0.5 * (ea.getYnormalized() + 1) * _height + 0.5; @@ -300,10 +287,7 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea) _last_x = event->getScreenX(); _last_y = event->getScreenY(); - event->client_pos = event->screen_pos; - event->button = ea.getButton(); - event->state = ea.getButtonMask(); - event->mod = ea.getModKeyMask(); + event->local_pos = event->client_pos = event->screen_pos; if( !_resize_window.expired() ) { @@ -324,34 +308,33 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea) canvas::WindowPtr window_at_cursor; for( int i = _transform->getNumChildren() - 1; i >= 0; --i ) { - osg::Group *layer = _transform->getChild(i)->asGroup(); - assert(layer); - if( !layer->getNumChildren() ) + osg::Group *element = _transform->getChild(i)->asGroup(); + + assert(element); + assert(element->getUserData()); + + canvas::WindowPtr window = + boost::static_pointer_cast + ( + static_cast(element->getUserData())->element + ); + + if( !window->isCapturingEvents() || !window->isVisible() ) continue; - for( int j = layer->getNumChildren() - 1; j >= 0; --j ) + float margin = window->isResizable() ? resize_margin_pos : 0; + if( window->getScreenRegion().contains( event->getScreenX(), + event->getScreenY(), + margin ) ) { - assert(layer->getChild(j)->getUserData()); - canvas::WindowPtr window = - static_cast(layer->getChild(j)->getUserData()) - ->window.lock(); - float margin = window->isResizable() ? resize_margin_pos : 0; - if( window->getRegion().contains( event->getScreenX(), - event->getScreenY(), - margin ) ) - { - window_at_cursor = window; - break; - } - } - - if( window_at_cursor ) + window_at_cursor = window; break; + } } if( window_at_cursor ) { - const SGRect& reg = window_at_cursor->getRegion(); + const SGRect& reg = window_at_cursor->getScreenRegion(); if( window_at_cursor->isResizable() && ( ea.getEventType() == osgGA::GUIEventAdapter::MOVE @@ -392,7 +375,7 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea) if( ea.getEventType() == osgGA::GUIEventAdapter::PUSH ) { _resize_window = window_at_cursor; - window_at_cursor->doRaise(); + window_at_cursor->raise(); window_at_cursor->handleResize( _resize | canvas::Window::INIT, event->delta ); } @@ -444,13 +427,10 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea) { sc::MouseEventPtr move_event( new sc::MouseEvent(*event) ); move_event->type = sc::Event::MOUSE_LEAVE; + move_event->client_pos -= toOsg(last_mouse_over->getPosition()); + move_event->local_pos = move_event->client_pos; - // Let the event position be always relative to the top left window - // corner - move_event->client_pos.x() -= last_mouse_over->getRegion().x(); - move_event->client_pos.y() -= last_mouse_over->getRegion().y(); - - last_mouse_over->handleMouseEvent(move_event); + last_mouse_over->handleEvent(move_event); } _last_mouse_over = window_at_cursor; event->type = sc::Event::MOUSE_MOVE; @@ -473,11 +453,9 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea) if( target_window ) { - // Let the event position be always relative to the top left window corner - event->client_pos.x() -= target_window->getRegion().x(); - event->client_pos.y() -= target_window->getRegion().y(); - - return target_window->handleMouseEvent(event); + event->client_pos -= toOsg(target_window->getPosition()); + event->local_pos = event->client_pos; + return target_window->handleEvent(event); } else return false; @@ -500,3 +478,11 @@ void GUIMgr::handleResize(int x, int y, int width, int height) 0, _height, 0, 1 )); } + +//------------------------------------------------------------------------------ +void GUIMgr::handleMouseMode(SGPropertyNode* node) +{ + // pass-through indicates events should pass through to the UI + _handle_events = fgGetNode("/input/mice/mouse[0]/mode", node->getIntValue()) + ->getBoolValue("pass-through"); +}