From b5dfaf170aa71d0c3c5c45622316e58870c0380e Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sat, 29 Jun 2013 14:14:12 +0200 Subject: [PATCH] Canvas: Ensure events are dispatched to canvas with no element hit. --- simgear/canvas/Canvas.cxx | 3 ++- simgear/canvas/CanvasEventVisitor.cxx | 17 ++++++++++------- simgear/canvas/CanvasEventVisitor.hxx | 11 ++++++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/simgear/canvas/Canvas.cxx b/simgear/canvas/Canvas.cxx index 8c876a4c..d2f97ed1 100644 --- a/simgear/canvas/Canvas.cxx +++ b/simgear/canvas/Canvas.cxx @@ -419,7 +419,8 @@ namespace canvas EventVisitor visitor( EventVisitor::TRAVERSE_DOWN, event->getClientPos(), - event->getDelta() ); + event->getDelta(), + _root_group ); if( !_root_group->accept(visitor) ) return false; diff --git a/simgear/canvas/CanvasEventVisitor.cxx b/simgear/canvas/CanvasEventVisitor.cxx index 40d4e26b..6ba90a9f 100644 --- a/simgear/canvas/CanvasEventVisitor.cxx +++ b/simgear/canvas/CanvasEventVisitor.cxx @@ -30,8 +30,10 @@ namespace canvas //---------------------------------------------------------------------------- EventVisitor::EventVisitor( TraverseMode mode, const osg::Vec2f& pos, - const osg::Vec2f& delta ): - _traverse_mode( mode ) + const osg::Vec2f& delta, + const ElementPtr& root ): + _traverse_mode( mode ), + _root(root) { if( mode == TRAVERSE_DOWN ) { @@ -70,10 +72,11 @@ namespace canvas m(0, 1) * pos[0] + m(1, 1) * pos[1] + m(3, 1) ); - // Don't check collision with root element (2nd element in _target_path) - // do event listeners attached to the canvas itself (its root group) - // always get called even if no element has been hit. - if( _target_path.size() > 1 && !el.hitBound(pos, local_pos) ) + // Don't check specified root element for collision, as its purpose is to + // catch all events which have no target. This allows for example calling + // event listeners attached to the canvas itself (its root group) even if + // no element has been hit. + if( _root.get() != &el && !el.hitBound(pos, local_pos) ) return false; const osg::Vec2f& delta = _target_path.back().local_delta; @@ -86,7 +89,7 @@ namespace canvas EventTarget target = {el.getWeakPtr(), local_pos, local_delta}; _target_path.push_back(target); - if( el.traverse(*this) || _target_path.size() <= 2 ) + if( el.traverse(*this) || &el == _root.get() ) return true; _target_path.pop_back(); diff --git a/simgear/canvas/CanvasEventVisitor.hxx b/simgear/canvas/CanvasEventVisitor.hxx index 9b1fe810..a82f0928 100644 --- a/simgear/canvas/CanvasEventVisitor.hxx +++ b/simgear/canvas/CanvasEventVisitor.hxx @@ -38,9 +38,17 @@ namespace canvas TRAVERSE_DOWN }; + /** + * + * @param mode + * @param pos Mouse position + * @param delta Mouse movement since last mouse move event + * @param root Element to dispatch events to if no element is hit + */ EventVisitor( TraverseMode mode, const osg::Vec2f& pos, - const osg::Vec2f& delta ); + const osg::Vec2f& delta, + const ElementPtr& root = ElementPtr() ); virtual ~EventVisitor(); virtual bool traverse(Element& el); virtual bool apply(Element& el); @@ -51,6 +59,7 @@ namespace canvas TraverseMode _traverse_mode; EventPropagationPath _target_path; + ElementPtr _root; }; -- 2.39.5