]> git.mxchange.org Git - simgear.git/commitdiff
Canvas: Fix creating/forwarding of mouseenter/mouseleave events.
authorThomas Geymayer <tomgey@gmail.com>
Thu, 20 Jun 2013 21:13:10 +0000 (23:13 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Thu, 20 Jun 2013 21:13:47 +0000 (23:13 +0200)
simgear/canvas/CanvasEventManager.cxx
simgear/canvas/elements/CanvasImage.cxx

index 7a05a23ebe7253c0d1421aeb06c00666045fa5ed..ed4a90c1f91fc9acccd5118bb809fa9edc4c32e4 100644 (file)
@@ -157,21 +157,55 @@ namespace canvas
   void EventManager::handleMove( const MouseEventPtr& event,
                                  const EventPropagationPath& path )
   {
-    if( _last_mouse_over.path == path )
+    EventPropagationPath& last_path = _last_mouse_over.path;
+    if( last_path == path )
       return;
 
-    if( !_last_mouse_over.path.empty() )
+    // Leave old element
+    if( !last_path.empty() )
     {
       MouseEventPtr mouseout(new MouseEvent(*event));
       mouseout->type = Event::MOUSE_OUT;
-      propagateEvent(mouseout, _last_mouse_over.path);
+      propagateEvent(mouseout, last_path);
+
+      // Send a mouseleave event to all ancestors of the currently left element
+      // which are not ancestor of the new element currently entered
+      EventPropagationPath path_leave = last_path;
+      for(size_t i = path_leave.size() - 1; i > 0; --i)
+      {
+        if( i < path.size() && path[i] == path_leave[i] )
+          break;
+
+        MouseEventPtr mouseleave(new MouseEvent(*event));
+        mouseleave->type = Event::MOUSE_LEAVE;
+        propagateEvent(mouseleave, path_leave);
+
+        path_leave.pop_back();
+      }
     }
 
+    // Enter new element
     if( !path.empty() )
     {
       MouseEventPtr mouseover(new MouseEvent(*event));
       mouseover->type = Event::MOUSE_OVER;
       propagateEvent(mouseover, path);
+
+      // Send a mouseenter event to all ancestors of the currently entered
+      // element which are not ancestor of the old element currently being
+      // left
+      EventPropagationPath path_enter;
+      for(size_t i = 0; i < path.size(); ++i)
+      {
+        path_enter.push_back(path[i]);
+
+        if( i < last_path.size() && path[i] == last_path[i] )
+          continue;
+
+        MouseEventPtr mouseenter(new MouseEvent(*event));
+        mouseenter->type = Event::MOUSE_ENTER;
+        propagateEvent(mouseenter, path_enter);
+      }
     }
 
     _last_mouse_over.path = path;
@@ -248,6 +282,9 @@ namespace canvas
   EventManager::getCommonAncestor( const EventPropagationPath& path1,
                                    const EventPropagationPath& path2 ) const
   {
+    if( path1.empty() || path2.empty() )
+      return EventPropagationPath();
+
     if( path1.back().element.lock() == path2.back().element.lock() )
       return path2;
 
index 5500f32d01b93de7c111e7e82fbb1fbcb704e778..5b88807b5f9323319c59c67e19453c874ab93881 100644 (file)
@@ -470,7 +470,7 @@ namespace canvas
       mouse_event->local_pos = mouse_event->client_pos;
     }
 
-    return handled || src_canvas->handleMouseEvent(mouse_event);
+    return handled | src_canvas->handleMouseEvent(mouse_event);
   }
 
   //----------------------------------------------------------------------------