Canvas: Ensure events are dispatched to canvas with no element hit.
This commit is contained in:
@@ -419,7 +419,8 @@ namespace canvas
|
|||||||
|
|
||||||
EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
|
EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
|
||||||
event->getClientPos(),
|
event->getClientPos(),
|
||||||
event->getDelta() );
|
event->getDelta(),
|
||||||
|
_root_group );
|
||||||
if( !_root_group->accept(visitor) )
|
if( !_root_group->accept(visitor) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ namespace canvas
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
EventVisitor::EventVisitor( TraverseMode mode,
|
EventVisitor::EventVisitor( TraverseMode mode,
|
||||||
const osg::Vec2f& pos,
|
const osg::Vec2f& pos,
|
||||||
const osg::Vec2f& delta ):
|
const osg::Vec2f& delta,
|
||||||
_traverse_mode( mode )
|
const ElementPtr& root ):
|
||||||
|
_traverse_mode( mode ),
|
||||||
|
_root(root)
|
||||||
{
|
{
|
||||||
if( mode == TRAVERSE_DOWN )
|
if( mode == TRAVERSE_DOWN )
|
||||||
{
|
{
|
||||||
@@ -70,10 +72,11 @@ namespace canvas
|
|||||||
m(0, 1) * pos[0] + m(1, 1) * pos[1] + m(3, 1)
|
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)
|
// Don't check specified root element for collision, as its purpose is to
|
||||||
// do event listeners attached to the canvas itself (its root group)
|
// catch all events which have no target. This allows for example calling
|
||||||
// always get called even if no element has been hit.
|
// event listeners attached to the canvas itself (its root group) even if
|
||||||
if( _target_path.size() > 1 && !el.hitBound(pos, local_pos) )
|
// no element has been hit.
|
||||||
|
if( _root.get() != &el && !el.hitBound(pos, local_pos) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const osg::Vec2f& delta = _target_path.back().local_delta;
|
const osg::Vec2f& delta = _target_path.back().local_delta;
|
||||||
@@ -86,7 +89,7 @@ namespace canvas
|
|||||||
EventTarget target = {el.getWeakPtr(), local_pos, local_delta};
|
EventTarget target = {el.getWeakPtr(), local_pos, local_delta};
|
||||||
_target_path.push_back(target);
|
_target_path.push_back(target);
|
||||||
|
|
||||||
if( el.traverse(*this) || _target_path.size() <= 2 )
|
if( el.traverse(*this) || &el == _root.get() )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
_target_path.pop_back();
|
_target_path.pop_back();
|
||||||
|
|||||||
@@ -38,9 +38,17 @@ namespace canvas
|
|||||||
TRAVERSE_DOWN
|
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,
|
EventVisitor( TraverseMode mode,
|
||||||
const osg::Vec2f& pos,
|
const osg::Vec2f& pos,
|
||||||
const osg::Vec2f& delta );
|
const osg::Vec2f& delta,
|
||||||
|
const ElementPtr& root = ElementPtr() );
|
||||||
virtual ~EventVisitor();
|
virtual ~EventVisitor();
|
||||||
virtual bool traverse(Element& el);
|
virtual bool traverse(Element& el);
|
||||||
virtual bool apply(Element& el);
|
virtual bool apply(Element& el);
|
||||||
@@ -51,6 +59,7 @@ namespace canvas
|
|||||||
|
|
||||||
TraverseMode _traverse_mode;
|
TraverseMode _traverse_mode;
|
||||||
EventPropagationPath _target_path;
|
EventPropagationPath _target_path;
|
||||||
|
ElementPtr _root;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user