Canvas: Ensure events are dispatched to canvas with no element hit.

This commit is contained in:
Thomas Geymayer 2013-06-29 14:14:12 +02:00
parent c372591f36
commit b5dfaf170a
3 changed files with 22 additions and 9 deletions

View File

@ -419,7 +419,8 @@ namespace canvas
EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
event->getClientPos(),
event->getDelta() );
event->getDelta(),
_root_group );
if( !_root_group->accept(visitor) )
return false;

View File

@ -30,8 +30,10 @@ 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 )
{
@ -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() > 1 && !el.hitBound(pos, 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;
@ -86,7 +89,7 @@ namespace canvas
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();

View File

@ -38,9 +38,17 @@ namespace canvas
TRAVERSE_DOWN
};
/**
*
* @param mode
* @param pos Mouse position
* @param delta Mouse movement since last mouse move event
* @param root Element to dispatch events to if no element is hit
*/
EventVisitor( TraverseMode mode,
const osg::Vec2f& pos,
const osg::Vec2f& delta );
const osg::Vec2f& delta,
const ElementPtr& root = ElementPtr() );
virtual ~EventVisitor();
virtual bool traverse(Element& el);
virtual bool apply(Element& el);
@ -51,6 +59,7 @@ namespace canvas
TraverseMode _traverse_mode;
EventPropagationPath _target_path;
ElementPtr _root;
};