1
0
Fork 0

Improve mouse event capturing with Canvas windows.

- Don't capture mouse events if mouse mode has
   pass-through disabled. This behaviour is
   consistent with the PUI dialogs and allows
   changing moving view and controls while above
   any GUI dialog.
 - Add option to canvas windows to ignore all
   events and let them pass through
   ("capture-events").
This commit is contained in:
Thomas Geymayer 2013-02-07 23:08:36 +01:00
parent 2013f7149d
commit c0173cf2b5
4 changed files with 33 additions and 3 deletions

View file

@ -118,6 +118,10 @@ GUIMgr::GUIMgr():
&windowFactory ), &windowFactory ),
_event_handler( new GUIEventHandler(this) ), _event_handler( new GUIEventHandler(this) ),
_transform( new osg::MatrixTransform ), _transform( new osg::MatrixTransform ),
_cb_mouse_mode( this,
&GUIMgr::handleMouseMode,
fgGetNode("/devices/status/mice/mouse[0]/mode") ),
_handle_events(true),
_width(_props, "size[0]"), _width(_props, "size[0]"),
_height(_props, "size[1]"), _height(_props, "size[1]"),
_resize(canvas::Window::NONE), _resize(canvas::Window::NONE),
@ -286,7 +290,7 @@ const float resize_corner = 20;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea) bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea)
{ {
if( !_transform->getNumChildren() ) if( !_transform->getNumChildren() || !_handle_events )
return false; return false;
namespace sc = simgear::canvas; namespace sc = simgear::canvas;
@ -340,6 +344,10 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea)
canvas::WindowPtr window = canvas::WindowPtr window =
static_cast<WindowUserData*>(layer->getChild(j)->getUserData()) static_cast<WindowUserData*>(layer->getChild(j)->getUserData())
->window.lock(); ->window.lock();
if( !window->isCapturingEvents() )
continue;
float margin = window->isResizable() ? resize_margin_pos : 0; float margin = window->isResizable() ? resize_margin_pos : 0;
if( window->getRegion().contains( event->getScreenX(), if( window->getRegion().contains( event->getScreenX(),
event->getScreenY(), event->getScreenY(),
@ -505,3 +513,11 @@ void GUIMgr::handleResize(int x, int y, int width, int height)
0, _height, 0, 1 0, _height, 0, 1
)); ));
} }
//------------------------------------------------------------------------------
void GUIMgr::handleMouseMode(SGPropertyNode* node)
{
// pass-through indicates events should pass through to the UI
_handle_events = fgGetNode("/input/mice/mouse[0]/mode", node->getIntValue())
->getBoolValue("pass-through");
}

View file

@ -52,6 +52,8 @@ class GUIMgr:
osg::ref_ptr<GUIEventHandler> _event_handler; osg::ref_ptr<GUIEventHandler> _event_handler;
osg::ref_ptr<osg::MatrixTransform> _transform; osg::ref_ptr<osg::MatrixTransform> _transform;
SGPropertyChangeCallback<GUIMgr> _cb_mouse_mode;
bool _handle_events;
simgear::PropertyObject<int> _width, simgear::PropertyObject<int> _width,
_height; _height;
@ -68,10 +70,11 @@ class GUIMgr:
canvas::WindowPtr getWindow(size_t i); canvas::WindowPtr getWindow(size_t i);
simgear::canvas::Placements simgear::canvas::Placements
addPlacement(SGPropertyNode*, simgear::canvas::CanvasPtr canvas ); addPlacement(SGPropertyNode*, simgear::canvas::CanvasPtr canvas);
bool handleMouse(const osgGA::GUIEventAdapter& ea); bool handleMouse(const osgGA::GUIEventAdapter& ea);
void handleResize(int x, int y, int width, int height); void handleResize(int x, int y, int width, int height);
void handleMouseMode(SGPropertyNode* node);
}; };
#endif /* CANVAS_GUI_MGR_HXX_ */ #endif /* CANVAS_GUI_MGR_HXX_ */

View file

@ -32,6 +32,7 @@ namespace canvas
node, node,
simgear::canvas::Style() ), simgear::canvas::Style() ),
_resizable(false), _resizable(false),
_capture_events(true),
_resize_top(node, "resize-top"), _resize_top(node, "resize-top"),
_resize_right(node, "resize-right"), _resize_right(node, "resize-right"),
_resize_bottom(node, "resize-bottom"), _resize_bottom(node, "resize-bottom"),
@ -74,6 +75,8 @@ namespace canvas
doRaise(node); doRaise(node);
else if( node->getNameString() == "resize" ) else if( node->getNameString() == "resize" )
_resizable = node->getBoolValue(); _resizable = node->getBoolValue();
else if( node->getNameString() == "capture-events" )
_capture_events = node->getBoolValue();
else else
handled = false; handled = false;
} }
@ -112,6 +115,12 @@ namespace canvas
return _resizable; return _resizable;
} }
//----------------------------------------------------------------------------
bool Window::isCapturingEvents() const
{
return _capture_events;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Window::handleMouseEvent(const simgear::canvas::MouseEventPtr& event) bool Window::handleMouseEvent(const simgear::canvas::MouseEventPtr& event)
{ {

View file

@ -57,6 +57,7 @@ namespace canvas
simgear::canvas::CanvasWeakPtr getCanvas() const; simgear::canvas::CanvasWeakPtr getCanvas() const;
bool isResizable() const; bool isResizable() const;
bool isCapturingEvents() const;
bool handleMouseEvent(const simgear::canvas::MouseEventPtr& event); bool handleMouseEvent(const simgear::canvas::MouseEventPtr& event);
@ -67,7 +68,8 @@ namespace canvas
protected: protected:
simgear::canvas::Image _image; simgear::canvas::Image _image;
bool _resizable; bool _resizable,
_capture_events;
simgear::PropertyObject<int> _resize_top, simgear::PropertyObject<int> _resize_top,
_resize_right, _resize_right,