return nasal_sys;
}
+ //----------------------------------------------------------------------------
+ naContext FGCanvasSystemAdapter::getNasalContext() const
+ {
+ return getNasalSys()->context();
+ }
+
//----------------------------------------------------------------------------
int FGCanvasSystemAdapter::gcSave(naRef r)
{
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,
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;
#include <Scripting/NasalSys.hxx>
#include <simgear/canvas/Canvas.hxx>
+#include <simgear/canvas/MouseEvent.hxx>
//------------------------------------------------------------------------------
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 )
{
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);
_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);
}
//------------------------------------------------------------------------------
virtual ~CanvasWidget();
virtual void doHit (int button, int updown, int x, int y);
- virtual int checkKey(int key , int updown);
+ virtual int checkKey(int key, int updown);
virtual void setSize ( int w, int h );
virtual void draw(int dx, int dy);
*_mouse_y,
*_mouse_down,
*_mouse_drag;
+
+ int _last_x,
+ _last_y;
};
#endif /* CANVASWIDGET_HXX_ */
}
-\f
/**
* Key handler.
*/
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
- |PUCLASS_LARGEINPUT|PUCLASS_SCROLLBAR))
+ 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);
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
aDlg->setNeedsLayout();
}
-\f////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
// Callbacks.
////////////////////////////////////////////////////////////////////////
}
-\f
////////////////////////////////////////////////////////////////////////
// Static helper functions.
////////////////////////////////////////////////////////////////////////
}
-\f
////////////////////////////////////////////////////////////////////////
// Implementation of FGDialog.
////////////////////////////////////////////////////////////////////////
return key;
}
-void\fFGPUIDialog::relayout()
+void FGPUIDialog::relayout()
{
_needsRelayout = false;
-\f
////////////////////////////////////////////////////////////////////////
// Implementation of fgValueList and derived pui widgets
////////////////////////////////////////////////////////////////////////
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 *);
);
}
+// 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");