]> git.mxchange.org Git - simgear.git/commitdiff
Canvas: Add local_pos to mouse event and fix transformation of event positions with...
authorThomas Geymayer <tomgey@gmail.com>
Sun, 12 May 2013 22:34:09 +0000 (00:34 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Sun, 12 May 2013 22:34:09 +0000 (00:34 +0200)
simgear/canvas/CanvasEventManager.cxx
simgear/canvas/MouseEvent.hxx
simgear/canvas/elements/CanvasElement.cxx
simgear/canvas/elements/CanvasElement.hxx
simgear/canvas/elements/CanvasImage.cxx
simgear/canvas/elements/CanvasImage.hxx

index 89f25719107d0303cbb6adb1cb45fc0b5663414f..8801d84aad2a2a120c60beda0d33f1e838075e04 100644 (file)
@@ -210,23 +210,22 @@ namespace canvas
         // (eg. removed by another event handler)
         continue;
 
-      // TODO provide functions to convert position and delta to local
-      //      coordinates on demand. Events shouldn't contain informations in
-      //      local coordinates as they might differe between different elements
-      //      receiving the same event.
-//      if( mouse_event && event->type != Event::DRAG )
-//      {
-//        // TODO transform pos and delta for drag events. Maybe we should just
-//        //      store the global coordinates and convert to local coordinates
-//        //      on demand.
-//
-//        // Position and delta are specified in local coordinate system of
-//        // current element
-//        mouse_event->pos = it->local_pos;
-//        mouse_event->delta = it->local_delta;
-//      }
+      // TODO provide functions to convert delta to local coordinates on demand.
+      //      Maybe also provide a clone method for events as local coordinates
+      //      might differ between different elements receiving the same event.
+      if( mouse_event ) //&& event->type != Event::DRAG )
+      {
+        // TODO transform pos and delta for drag events. Maybe we should just
+        //      store the global coordinates and convert to local coordinates
+        //      on demand.
+
+        // Position and delta are specified in local coordinate system of
+        // current element
+        mouse_event->local_pos = it->local_pos;
+        //mouse_event->delta = it->local_delta;
+      }
 
-      el->callListeners(event);
+      el->handleEvent(event);
 
       if( event->propagation_stopped )
         return true;
index c84fcd2757a76dad955eac8b095b70834a301d1b..f6faee76d8de3498d2d9694d9097143fdfe2ad1e 100644 (file)
@@ -49,6 +49,7 @@ namespace canvas
 
       osg::Vec2f getScreenPos() const { return screen_pos; }
       osg::Vec2f getClientPos() const { return client_pos; }
+      osg::Vec2f getLocalPos()  const { return  local_pos; }
       osg::Vec2f getDelta() const { return delta; }
 
       float getScreenX() const { return screen_pos.x(); }
@@ -57,6 +58,9 @@ namespace canvas
       float getClientX() const { return client_pos.x(); }
       float getClientY() const { return client_pos.y(); }
 
+      float getLocalX() const { return local_pos.x(); }
+      float getLocalY() const { return local_pos.y(); }
+
       float getDeltaX() const { return delta.x(); }
       float getDeltaY() const { return delta.y(); }
 
@@ -64,6 +68,7 @@ namespace canvas
 
       osg::Vec2f  screen_pos,   //<! Position in screen coordinates
                   client_pos,   //<! Position in window/canvas coordinates
+                  local_pos,    //<! Position in local/element coordinates
                   delta;
       int         button,       //<! Button for this event
                   state,        //<! Current button state
index 0d3a0589d1a0120021d635d6797a6b2e0b5ed6ff..cb18634228193a2b30232ceac81d6594f7a42acd 100644 (file)
@@ -185,14 +185,16 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  void Element::callListeners(const canvas::EventPtr& event)
+  bool Element::handleEvent(canvas::EventPtr event)
   {
     ListenerMap::iterator listeners = _listener.find(event->getType());
     if( listeners == _listener.end() )
-      return;
+      return false;
 
     BOOST_FOREACH(EventListenerPtr listener, listeners->second)
       listener->call(event);
+
+    return true;
   }
 
   //----------------------------------------------------------------------------
index 3196182576f406b0aaa1a1203c7fab72ac33b629..65e84dbf339be344ba8dc215a69ec527e25d12c5 100644 (file)
@@ -90,7 +90,7 @@ namespace canvas
       virtual bool ascend(EventVisitor& visitor);
       virtual bool traverse(EventVisitor& visitor);
 
-      void callListeners(const canvas::EventPtr& event);
+      virtual bool handleEvent(canvas::EventPtr event);
 
       virtual bool hitBound( const osg::Vec2f& pos,
                              const osg::Vec2f& local_pos ) const;
index d4e56601908788c8f4972a6c0fb72f94bc5d45f1..f7a4d92cd41346e170b3c9acbcdfb55d3f089658 100644 (file)
@@ -22,6 +22,7 @@
 #include <simgear/canvas/CanvasMgr.hxx>
 #include <simgear/canvas/CanvasSystemAdapter.hxx>
 #include <simgear/canvas/MouseEvent.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
 #include <simgear/scene/util/parse_color.hxx>
 #include <simgear/misc/sg_path.hxx>
 
@@ -411,26 +412,40 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  bool Image::handleMouseEvent(MouseEventPtr event)
+  bool Image::handleEvent(EventPtr event)
   {
-    CanvasPtr src_canvas = _src_canvas.lock();
+    bool handled = Element::handleEvent(event);
 
+    CanvasPtr src_canvas = _src_canvas.lock();
     if( !src_canvas )
-      return false;
+      return handled;
 
-    if( _outset.valid )
+    MouseEventPtr mouse_event = boost::dynamic_pointer_cast<MouseEvent>(event);
+    if( mouse_event )
     {
-      CSSOffsets outset = _outset.getAbsOffsets(getTextureDimensions());
-
-      event.reset( new MouseEvent(*event) );
-      event->client_pos += osg::Vec2f(outset.l, outset.t);
-      event->client_pos.x() *= src_canvas->getViewWidth()
-                             / (_region.width() + outset.l + outset.r);
-      event->client_pos.y() *= src_canvas->getViewHeight()
-                             / (_region.height() + outset.t + outset.b);
+      mouse_event.reset( new MouseEvent(*mouse_event) );
+      event = mouse_event;
+
+      mouse_event->client_pos = mouse_event->local_pos
+                              - toOsg(_region.getMin());
+
+      osg::Vec2f size(_region.width(), _region.height());
+      if( _outset.valid )
+      {
+        CSSOffsets outset = _outset.getAbsOffsets(getTextureDimensions());
+
+        mouse_event->client_pos += osg::Vec2f(outset.l, outset.t);
+        size.x() += outset.l + outset.r;
+        size.y() += outset.t + outset.b;
+      }
+
+      // Scale event pos according to canvas view size vs. displayed/screen size
+      mouse_event->client_pos.x() *= src_canvas->getViewWidth() / size.x();
+      mouse_event->client_pos.y() *= src_canvas->getViewHeight()/ size.y();
+      mouse_event->local_pos = mouse_event->client_pos;
     }
 
-    return src_canvas->handleMouseEvent(event);
+    return handled || src_canvas->handleMouseEvent(mouse_event);
   }
 
   //----------------------------------------------------------------------------
index fccc20f53757036677a9a87e1893860faeb038f1..453f7dce5d8dab0205f311529ee219737517c135 100644 (file)
@@ -81,7 +81,7 @@ namespace canvas
 
       const SGRect<float>& getRegion() const;
 
-      bool handleMouseEvent(MouseEventPtr event);
+      bool handleEvent(EventPtr event);
 
     protected: