]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/CanvasEventVisitor.cxx
Canvas: Ensure all element types are initialized before first usage.
[simgear.git] / simgear / canvas / CanvasEventVisitor.cxx
index b74ee171690923b46ba5510d472bbbbb34b97524..6ba90a9f363a41c4f5c738545f584e5774ab2dea 100644 (file)
@@ -30,12 +30,14 @@ 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 )
     {
-      EventTarget target = {0, pos, delta};
+      EventTarget target = {ElementWeakPtr(), pos, delta};
       _target_path.push_back(target);
     }
   }
@@ -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() > 2 && !el.hitBound(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;
@@ -83,10 +86,10 @@ namespace canvas
         m(0, 1) * delta[0] + m(1, 1) * delta[1]
       );
 
-      EventTarget target = {&el, local_pos, local_delta};
+      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();
@@ -97,36 +100,9 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  bool EventVisitor::propagateEvent(const EventPtr& event)
+  const EventPropagationPath& EventVisitor::getPropagationPath() const
   {
-    // Event propagation similar to DOM Level 3 event flow:
-    // http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
-
-    // Capturing phase
-//    for( EventTargets::iterator it = _target_path.begin();
-//                                it != _target_path.end();
-//                              ++it )
-//    {
-//      if( it->element )
-//        std::cout << it->element->getProps()->getPath() << " "
-//                  << "(" << it->local_pos.x() << "|" << it->local_pos.y() << ")\n";
-//    }
-
-    // Bubbling phase
-    for( EventTargets::reverse_iterator it = _target_path.rbegin();
-                                        it != _target_path.rend();
-                                      ++it )
-    {
-      if( !it->element )
-        continue;
-
-      it->element->callListeners(event);
-
-      if( event->propagation_stopped )
-        return true;
-    }
-
-    return true;
+    return _target_path;
   }
 
 } // namespace canvas