Canvas: support for pointer grab.
This commit is contained in:
parent
b654477794
commit
271cf1420d
3 changed files with 100 additions and 31 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue