Forward mouse events from (PUI) CanvasWidget to Canvas for new DOM like callbacks
This commit is contained in:
parent
240c237489
commit
28f2779c4b
8 changed files with 133 additions and 24 deletions
|
@ -87,6 +87,12 @@ namespace canvas
|
|||
return nasal_sys;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naContext FGCanvasSystemAdapter::getNasalContext() const
|
||||
{
|
||||
return getNasalSys()->context();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int FGCanvasSystemAdapter::gcSave(naRef r)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace canvas
|
|||
virtual void removeCamera(osg::Camera* camera) const;
|
||||
virtual osg::Image* getImage(const std::string& path) const;
|
||||
|
||||
virtual naContext getNasalContext() const;
|
||||
virtual int gcSave(naRef r);
|
||||
virtual void gcRelease(int key);
|
||||
virtual naRef callMethod( naRef code,
|
||||
|
|
|
@ -336,9 +336,10 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea)
|
|||
event->type = sc::Event::MOUSE_UP;
|
||||
break;
|
||||
|
||||
// case osgGA::GUIEventAdapter::DRAG:
|
||||
// target_window = _last_push.lock();
|
||||
// break;
|
||||
case osgGA::GUIEventAdapter::DRAG:
|
||||
target_window = _last_push.lock();
|
||||
event->type = sc::Event::DRAG;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <Scripting/NasalSys.hxx>
|
||||
|
||||
#include <simgear/canvas/Canvas.hxx>
|
||||
#include <simgear/canvas/MouseEvent.hxx>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
CanvasWidget::CanvasWidget( int x, int y,
|
||||
|
@ -25,7 +26,9 @@ CanvasWidget::CanvasWidget( int x, int y,
|
|||
puObject(x, y, width, height),
|
||||
_canvas_mgr( dynamic_cast<CanvasMgr*>(globals->get_subsystem("Canvas")) ),
|
||||
_tex_id(0),
|
||||
_no_tex_cnt(0)
|
||||
_no_tex_cnt(0),
|
||||
_last_x(0),
|
||||
_last_y(0)
|
||||
{
|
||||
if( !_canvas_mgr )
|
||||
{
|
||||
|
@ -100,6 +103,62 @@ void CanvasWidget::doHit(int button, int updown, int x, int y)
|
|||
if( fgGetKeyModifiers() & (KEYMOD_CTRL | KEYMOD_SHIFT) )
|
||||
return;
|
||||
|
||||
namespace sc = simgear::canvas;
|
||||
sc::MouseEventPtr event(new sc::MouseEvent);
|
||||
event->pos.set(x - abox.min[0], y - abox.min[1]);
|
||||
event->delta.set(x - _last_x, y - _last_y);
|
||||
|
||||
_last_x = x;
|
||||
_last_y = y;
|
||||
|
||||
switch( button )
|
||||
{
|
||||
case PU_LEFT_BUTTON:
|
||||
event->button = osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON;
|
||||
break;
|
||||
case PU_MIDDLE_BUTTON:
|
||||
event->button = osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON;
|
||||
break;
|
||||
case PU_RIGHT_BUTTON:
|
||||
event->button = osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON;
|
||||
break;
|
||||
case PU_SCROLL_UP_BUTTON:
|
||||
case PU_SCROLL_DOWN_BUTTON:
|
||||
// Only let PU_DOWN trigger a scroll wheel event
|
||||
if( updown != PU_DOWN )
|
||||
return;
|
||||
|
||||
event->type = sc::Event::WHEEL;
|
||||
event->delta.y() = button == PU_SCROLL_UP_BUTTON ? 1 : -1;
|
||||
|
||||
_canvas->handleMouseEvent(event);
|
||||
|
||||
return;
|
||||
default:
|
||||
SG_LOG(SG_INPUT, SG_WARN, "CanvasWidget: Unknown button: " << button);
|
||||
return;
|
||||
}
|
||||
|
||||
switch( updown )
|
||||
{
|
||||
case PU_DOWN:
|
||||
event->type = sc::Event::MOUSE_DOWN;
|
||||
puSetActiveWidget(this, x, y);
|
||||
break;
|
||||
case PU_UP:
|
||||
event->type = sc::Event::MOUSE_UP;
|
||||
puDeactivateWidget();
|
||||
break;
|
||||
case PU_DRAG:
|
||||
event->type = sc::Event::DRAG;
|
||||
break;
|
||||
default:
|
||||
SG_LOG(SG_INPUT, SG_WARN, "CanvasWidget: Unknown updown: " << updown);
|
||||
return;
|
||||
}
|
||||
|
||||
_canvas->handleMouseEvent(event);
|
||||
|
||||
_mouse_x->setIntValue(x - abox.min[0]);
|
||||
_mouse_y->setIntValue(abox.max[1] - y);
|
||||
|
||||
|
@ -107,14 +166,6 @@ void CanvasWidget::doHit(int button, int updown, int x, int y)
|
|||
_mouse_drag->setIntValue(button);
|
||||
else if( updown == PU_DOWN )
|
||||
_mouse_down->setIntValue(button);
|
||||
|
||||
if( button != active_mouse_button )
|
||||
return;
|
||||
|
||||
if (updown == PU_UP)
|
||||
puDeactivateWidget();
|
||||
else if (updown == PU_DOWN)
|
||||
puSetActiveWidget(this, x, y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -44,6 +44,9 @@ class CanvasWidget:
|
|||
*_mouse_y,
|
||||
*_mouse_down,
|
||||
*_mouse_drag;
|
||||
|
||||
int _last_x,
|
||||
_last_y;
|
||||
};
|
||||
|
||||
#endif /* CANVASWIDGET_HXX_ */
|
||||
|
|
|
@ -139,7 +139,6 @@ void GUIInfo::apply_format(SGPropertyNode *n)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Key handler.
|
||||
*/
|
||||
|
@ -225,9 +224,16 @@ int fgPopup::checkHit(int button, int updown, int x, int y)
|
|||
int hit = getHitObjects(this, x, y);
|
||||
if (hit & PUCLASS_LIST) // ctrl-click in property browser (toggle bool)
|
||||
return result;
|
||||
if (!global_resize && hit & (PUCLASS_BUTTON|PUCLASS_ONESHOT|PUCLASS_INPUT
|
||||
if( !global_resize
|
||||
&& ( (hit & (PUCLASS_BUTTON|PUCLASS_ONESHOT|PUCLASS_INPUT
|
||||
|PUCLASS_LARGEINPUT|PUCLASS_SCROLLBAR))
|
||||
// The canvas should handle drag events on its own so exit
|
||||
// here if mouse is over a CanvasWidget
|
||||
|| (!global_drag && checkHitCanvas(this, x, y))
|
||||
) )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
getPosition(&_dlgX, &_dlgY);
|
||||
getSize(&_dlgW, &_dlgH);
|
||||
|
@ -340,6 +346,32 @@ int fgPopup::getHitObjects(puObject *object, int x, int y)
|
|||
return type;
|
||||
}
|
||||
|
||||
bool fgPopup::checkHitCanvas(puObject* object, int x, int y)
|
||||
{
|
||||
if( !object->isVisible() )
|
||||
return 0;
|
||||
|
||||
if( object->getType() & PUCLASS_GROUP )
|
||||
{
|
||||
for( puObject* obj = ((puGroup*)object)->getFirstChild();
|
||||
obj;
|
||||
obj = obj->getNextObject() )
|
||||
{
|
||||
if( checkHitCanvas(obj, x, y) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int cx, cy, cw, ch;
|
||||
object->getAbsolutePosition(&cx, &cy);
|
||||
object->getSize(&cw, &ch);
|
||||
if( x >= cx && x < cx + cw
|
||||
&& y >= cy && y < cy + ch
|
||||
&& dynamic_cast<CanvasWidget*>(object) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void fgPopup::applySize(puObject *object)
|
||||
{
|
||||
// compound plib widgets use setUserData() for internal purposes, so refuse
|
||||
|
@ -405,7 +437,8 @@ void FGPUIDialog::ConditionalObject::update(FGPUIDialog* aDlg)
|
|||
|
||||
aDlg->setNeedsLayout();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Callbacks.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -428,7 +461,6 @@ action_callback (puObject *object)
|
|||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Static helper functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -511,7 +543,6 @@ copy_from_pui (puObject *object, SGPropertyNode *node)
|
|||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGDialog.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1186,7 +1217,7 @@ FGPUIDialog::getKeyCode(const char *str)
|
|||
return key;
|
||||
}
|
||||
|
||||
voidFGPUIDialog::relayout()
|
||||
void FGPUIDialog::relayout()
|
||||
{
|
||||
_needsRelayout = false;
|
||||
|
||||
|
@ -1291,7 +1322,6 @@ FGPUIDialog::PropertyObject::PropertyObject(const char *n,
|
|||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of fgValueList and derived pui widgets
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -210,6 +210,7 @@ public:
|
|||
int checkHit(int b, int up, int x, int y);
|
||||
int checkKey(int key, int updown);
|
||||
int getHitObjects(puObject *, int x, int y);
|
||||
bool checkHitCanvas(puObject *, int x, int y);
|
||||
puObject *getKeyObject(puObject *, int key);
|
||||
puObject *getActiveInputField(puObject *);
|
||||
void applySize(puObject *);
|
||||
|
|
|
@ -149,16 +149,32 @@ naRef f_groupGetElementById(sc::Group& group, const nasal::CallContext& ctx)
|
|||
);
|
||||
}
|
||||
|
||||
// TODO allow directly exposing functions without parameters and return type
|
||||
naRef f_eventStopPropagation(sc::Event& event, const nasal::CallContext& ctx)
|
||||
{
|
||||
if( ctx.argc != 0 )
|
||||
naRuntimeError(ctx.c, "Event::stopPropagation no argument expected");
|
||||
event.stopPropagation();
|
||||
return naNil();
|
||||
}
|
||||
|
||||
naRef initNasalCanvas(naRef globals, naContext c, naRef gcSave)
|
||||
{
|
||||
NasalEvent::init("canvas.Event");
|
||||
NasalEvent::init("canvas.Event")
|
||||
.member("type", &sc::Event::getTypeString)
|
||||
.method_func<&f_eventStopPropagation>("stopPropagation");
|
||||
NasalMouseEvent::init("canvas.MouseEvent")
|
||||
.bases<NasalEvent>();
|
||||
.bases<NasalEvent>()
|
||||
.member("x", &sc::MouseEvent::getPosX)
|
||||
.member("y", &sc::MouseEvent::getPosY)
|
||||
.member("deltaX", &sc::MouseEvent::getDeltaX)
|
||||
.member("deltaY", &sc::MouseEvent::getDeltaY);
|
||||
NasalCanvas::init("Canvas")
|
||||
.member("_node_ghost", &elementGetNode<sc::Canvas>)
|
||||
.member("size_x", &sc::Canvas::getSizeX)
|
||||
.member("size_y", &sc::Canvas::getSizeY)
|
||||
.method_func<&f_canvasCreateGroup>("_createGroup");
|
||||
.method_func<&f_canvasCreateGroup>("_createGroup")
|
||||
.method<&sc::Canvas::addEventListener>("addEventListener");
|
||||
NasalElement::init("canvas.Element")
|
||||
.member("_node_ghost", &elementGetNode<sc::Element>)
|
||||
.method<&sc::Element::addEventListener>("addEventListener");
|
||||
|
|
Loading…
Reference in a new issue