1
0
Fork 0

Canvas: support for pointer grab.

This commit is contained in:
Thomas Geymayer 2014-08-11 00:23:10 +02:00
parent b654477794
commit 271cf1420d
3 changed files with 100 additions and 31 deletions

View file

@ -103,6 +103,10 @@ class DesktopGroup:
DesktopGroup();
void setFocusWindow(const sc::WindowPtr& window);
bool grabPointer(const sc::WindowPtr& window);
void ungrabPointer(const sc::WindowPtr& window);
bool handleEvent(const osgGA::GUIEventAdapter& ea);
protected:
@ -118,7 +122,8 @@ class DesktopGroup:
sc::WindowWeakPtr _last_push,
_last_mouse_over,
_resize_window,
_focus_window;
_focus_window,
_pointer_grab_window;
uint8_t _resize;
int _last_cursor;
@ -210,6 +215,35 @@ DesktopGroup::DesktopGroup():
_width = _height = -1;
}
//------------------------------------------------------------------------------
void DesktopGroup::setFocusWindow(const sc::WindowPtr& window)
{
_focus_window = window;
}
//------------------------------------------------------------------------------
bool DesktopGroup::grabPointer(const sc::WindowPtr& window)
{
sc::WindowPtr resize = _resize_window.lock();
if( (resize && resize != window) || !_pointer_grab_window.expired() )
// Already grabbed (resize -> implicit grab)
return false;
_pointer_grab_window = window;
return true;
}
//------------------------------------------------------------------------------
void DesktopGroup::ungrabPointer(const sc::WindowPtr& window)
{
if( _pointer_grab_window.expired() )
SG_LOG(SG_GUI, SG_WARN, "ungrabPointer: no active grab.");
else if( window != _pointer_grab_window.lock() )
SG_LOG(SG_GUI, SG_WARN, "ungrabPointer: window is not owner of the grab.");
else
_pointer_grab_window.reset();
}
//------------------------------------------------------------------------------
bool DesktopGroup::handleEvent(const osgGA::GUIEventAdapter& ea)
{
@ -237,12 +271,6 @@ bool DesktopGroup::handleEvent(const osgGA::GUIEventAdapter& ea)
}
}
//------------------------------------------------------------------------------
void DesktopGroup::setFocusWindow(const sc::WindowPtr& window)
{
_focus_window = window;
}
/*
RESIZE AREAS
============
@ -301,32 +329,35 @@ bool DesktopGroup::handleMouse(const osgGA::GUIEventAdapter& ea)
}
}
sc::WindowPtr window_at_cursor;
for( int i = _transform->getNumChildren() - 1; i >= 0; --i )
sc::WindowPtr window_at_cursor = _pointer_grab_window.lock();
if( !window_at_cursor )
{
osg::Group *element = _transform->getChild(i)->asGroup();
assert(element);
assert(element->getUserData());
sc::WindowPtr window =
dynamic_cast<sc::Window*>
(
static_cast<sc::Element::OSGUserData*>(
element->getUserData()
)->element.get()
);
if( !window || !window->isCapturingEvents() || !window->isVisible() )
continue;
float margin = window->isResizable() ? resize_margin_pos : 0;
if( window->getScreenRegion().contains( event->getScreenX(),
event->getScreenY(),
margin ) )
for( int i = _transform->getNumChildren() - 1; i >= 0; --i )
{
window_at_cursor = window;
break;
osg::Group *element = _transform->getChild(i)->asGroup();
assert(element);
assert(element->getUserData());
sc::WindowPtr window =
dynamic_cast<sc::Window*>
(
static_cast<sc::Element::OSGUserData*>(
element->getUserData()
)->element.get()
);
if( !window || !window->isCapturingEvents() || !window->isVisible() )
continue;
float margin = window->isResizable() ? resize_margin_pos : 0;
if( window->getScreenRegion().contains( event->getScreenX(),
event->getScreenY(),
margin ) )
{
window_at_cursor = window;
break;
}
}
}
@ -650,6 +681,18 @@ void GUIMgr::setInputFocus(const simgear::canvas::WindowPtr& window)
static_cast<DesktopGroup*>(_desktop.get())->setFocusWindow(window);
}
//------------------------------------------------------------------------------
bool GUIMgr::grabPointer(const sc::WindowPtr& window)
{
return static_cast<DesktopGroup*>(_desktop.get())->grabPointer(window);
}
//------------------------------------------------------------------------------
void GUIMgr::ungrabPointer(const sc::WindowPtr& window)
{
static_cast<DesktopGroup*>(_desktop.get())->ungrabPointer(window);
}
//------------------------------------------------------------------------------
sc::Placements
GUIMgr::addWindowPlacement( SGPropertyNode* placement,

View file

@ -57,6 +57,17 @@ class GUIMgr:
*/
void setInputFocus(const simgear::canvas::WindowPtr& window);
/**
* Grabs the pointer so that all events are passed to this @a window until
* the pointer is ungrabbed with ungrabPointer().
*/
bool grabPointer(const simgear::canvas::WindowPtr& window);
/**
* Releases the grab acquired for this @a window with grabPointer().
*/
void ungrabPointer(const simgear::canvas::WindowPtr& window);
protected:
simgear::canvas::GroupPtr _desktop;

View file

@ -186,6 +186,19 @@ naRef f_setInputFocus(const nasal::CallContext& ctx)
return naNil();
}
naRef f_grabPointer(const nasal::CallContext& ctx)
{
return ctx.to_nasal(
requireGUIMgr(ctx.c).grabPointer(ctx.requireArg<sc::WindowPtr>(0))
);
}
naRef f_ungrabPointer(const nasal::CallContext& ctx)
{
requireGUIMgr(ctx.c).ungrabPointer(ctx.requireArg<sc::WindowPtr>(0));
return naNil();
}
static naRef f_groupCreateChild(sc::Group& group, const nasal::CallContext& ctx)
{
return ctx.to_nasal( group.createChild( ctx.requireArg<std::string>(0),
@ -564,6 +577,8 @@ naRef initNasalCanvas(naRef globals, naContext c)
canvas_module.set("_newWindowGhost", f_createWindow);
canvas_module.set("_getDesktopGhost", f_getDesktop);
canvas_module.set("setInputFocus", f_setInputFocus);
canvas_module.set("grabPointer", f_grabPointer);
canvas_module.set("ungrabPointer", f_ungrabPointer);
return naNil();
}