]> git.mxchange.org Git - simgear.git/commitdiff
Canvas: Ensure events are dispatched to canvas with no element hit.
authorThomas Geymayer <tomgey@gmail.com>
Sat, 29 Jun 2013 12:14:12 +0000 (14:14 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Sat, 29 Jun 2013 12:14:12 +0000 (14:14 +0200)
simgear/canvas/Canvas.cxx
simgear/canvas/CanvasEventVisitor.cxx
simgear/canvas/CanvasEventVisitor.hxx

index 8c876a4cc84206fa77fcec1d78e712544ed66344..d2f97ed1ec85ff56c473a8bd2599abe0eab9a810 100644 (file)
@@ -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;
 
index 40d4e26b8a76f9a49290880fe6cc6e46b9e81827..6ba90a9f363a41c4f5c738545f584e5774ab2dea 100644 (file)
@@ -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();
index 9b1fe810ee65511ca705f2bd46721cfc0a7f499a..a82f09281d7bec9511c7b1e84ee36f73e6185570 100644 (file)
@@ -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;
 
   };