]> git.mxchange.org Git - simgear.git/commitdiff
Canvas: Respect clipping while event handling.
authorThomas Geymayer <tomgey@gmail.com>
Wed, 19 Mar 2014 17:21:25 +0000 (18:21 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Wed, 19 Mar 2014 17:21:25 +0000 (18:21 +0100)
simgear/canvas/CanvasEventVisitor.cxx
simgear/canvas/elements/CanvasElement.cxx
simgear/canvas/elements/CanvasElement.hxx

index 9fbae2c84a73a64a784bcdd2c2d5ccd6d68e68c2..065dce060e31185d787c023db57a92c22b6abc65 100644 (file)
@@ -69,7 +69,8 @@ namespace canvas
       // 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) )
+      if(    _root.get() != &el
+          && !el.hitBound(_target_path.front().local_pos, pos, local_pos) )
         return false;
 
       EventTarget target = {el.getWeakPtr(), local_pos};
index 4b199f046fb3f16ab166b8e7ab3e658dab6f081b..373632fc4fbd4cbb79bcbbcd9bd3b482041046ea 100644 (file)
@@ -56,6 +56,26 @@ namespace canvas
         _coord_reference(GLOBAL)
       {}
 
+      bool contains(const osg::Vec2f& pos) const
+      {
+        return _x <= pos.x() && pos.x() <= _x + _width
+            && _y <= pos.y() && pos.y() <= _y + _height;
+      }
+
+      bool contains( const osg::Vec2f& global_pos,
+                     const osg::Vec2f& parent_pos,
+                     const osg::Vec2f& local_pos ) const
+      {
+        switch( _coord_reference )
+        {
+          case GLOBAL: return contains(global_pos);
+          case PARENT: return contains(parent_pos);
+          case LOCAL:  return contains(local_pos);
+        }
+
+        return false;
+      }
+
       virtual void apply(osg::State& state) const
       {
         const osg::Viewport* vp = state.getCurrentViewport();
@@ -264,19 +284,24 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  bool Element::hitBound( const osg::Vec2f& pos,
+  bool Element::hitBound( const osg::Vec2f& global_pos,
+                          const osg::Vec2f& parent_pos,
                           const osg::Vec2f& local_pos ) const
   {
-    const osg::Vec3f pos3(pos, 0);
+    if( _scissor && !_scissor->contains(global_pos, parent_pos, local_pos) )
+      return false;
+
+    const osg::Vec3f pos3(parent_pos, 0);
 
     // Drawables have a bounding box...
     if( _drawable )
       return _drawable->getBound().contains(osg::Vec3f(local_pos, 0));
-    // ... for other elements, i.e. groups only a bounding sphere is available
     else
-      return _transform->getBound().contains(osg::Vec3f(pos, 0));
+      // ... for other elements, i.e. groups only a bounding sphere is available
+      return _transform->getBound().contains(osg::Vec3f(parent_pos, 0));
   }
 
+
   //----------------------------------------------------------------------------
   void Element::setVisible(bool visible)
   {
index fb00d645da5dcfc63643c40db1e7cc343ced6b91..dc5e1bf7592985d125b588bc26470c5d4e770ead 100644 (file)
@@ -113,7 +113,14 @@ namespace canvas
 
       virtual bool handleEvent(canvas::EventPtr event);
 
-      virtual bool hitBound( const osg::Vec2f& pos,
+      /**
+       *
+       * @param global_pos Position in global (canvas) coordinate frame
+       * @param parent_pos Position in parent coordinate frame
+       * @param local_pos  Position in local (element) coordinate frame
+       */
+      virtual bool hitBound( const osg::Vec2f& global_pos,
+                             const osg::Vec2f& parent_pos,
                              const osg::Vec2f& local_pos ) const;
 
       /**