From: Thomas Geymayer Date: Wed, 19 Mar 2014 17:21:25 +0000 (+0100) Subject: Canvas: Respect clipping while event handling. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=01a43b49a5cb55e8218beb842e5743c04666dd8d;p=simgear.git Canvas: Respect clipping while event handling. --- diff --git a/simgear/canvas/CanvasEventVisitor.cxx b/simgear/canvas/CanvasEventVisitor.cxx index 9fbae2c8..065dce06 100644 --- a/simgear/canvas/CanvasEventVisitor.cxx +++ b/simgear/canvas/CanvasEventVisitor.cxx @@ -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}; diff --git a/simgear/canvas/elements/CanvasElement.cxx b/simgear/canvas/elements/CanvasElement.cxx index 4b199f04..373632fc 100644 --- a/simgear/canvas/elements/CanvasElement.cxx +++ b/simgear/canvas/elements/CanvasElement.cxx @@ -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) { diff --git a/simgear/canvas/elements/CanvasElement.hxx b/simgear/canvas/elements/CanvasElement.hxx index fb00d645..dc5e1bf7 100644 --- a/simgear/canvas/elements/CanvasElement.hxx +++ b/simgear/canvas/elements/CanvasElement.hxx @@ -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; /**