1
0
Fork 0

Forward mouse events from (PUI) CanvasWidget to Canvas for new DOM like callbacks

This commit is contained in:
Thomas Geymayer 2012-12-02 13:27:37 +01:00
parent 240c237489
commit 28f2779c4b
8 changed files with 133 additions and 24 deletions

View file

@ -87,6 +87,12 @@ namespace canvas
return nasal_sys;
}
//----------------------------------------------------------------------------
naContext FGCanvasSystemAdapter::getNasalContext() const
{
return getNasalSys()->context();
}
//----------------------------------------------------------------------------
int FGCanvasSystemAdapter::gcSave(naRef r)
{

View file

@ -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,

View file

@ -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;

View file

@ -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);
}
//------------------------------------------------------------------------------

View file

@ -44,6 +44,9 @@ class CanvasWidget:
*_mouse_y,
*_mouse_down,
*_mouse_drag;
int _last_x,
_last_y;
};
#endif /* CANVASWIDGET_HXX_ */

View file

@ -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;
}
void FGPUIDialog::relayout()
void FGPUIDialog::relayout()
{
_needsRelayout = false;
@ -1291,7 +1322,6 @@ FGPUIDialog::PropertyObject::PropertyObject(const char *n,
////////////////////////////////////////////////////////////////////////
// Implementation of fgValueList and derived pui widgets
////////////////////////////////////////////////////////////////////////

View file

@ -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 *);

View file

@ -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");