]> git.mxchange.org Git - flightgear.git/commitdiff
Forward mouse events from (PUI) CanvasWidget to Canvas for new DOM like callbacks
authorThomas Geymayer <tomgey@gmail.com>
Sun, 2 Dec 2012 12:27:37 +0000 (13:27 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Sun, 2 Dec 2012 12:33:16 +0000 (13:33 +0100)
src/Canvas/FGCanvasSystemAdapter.cxx
src/Canvas/FGCanvasSystemAdapter.hxx
src/Canvas/gui_mgr.cxx
src/GUI/CanvasWidget.cxx
src/GUI/CanvasWidget.hxx
src/GUI/FGPUIDialog.cxx
src/GUI/FGPUIDialog.hxx
src/Scripting/NasalCanvas.cxx

index 84db82d55f2646804479713d95fbc6f7a27911c6..f6c94522ea92a3b5e0c7a4443fc5892a6070fde4 100644 (file)
@@ -87,6 +87,12 @@ namespace canvas
     return nasal_sys;
   }
 
+  //----------------------------------------------------------------------------
+  naContext FGCanvasSystemAdapter::getNasalContext() const
+  {
+    return getNasalSys()->context();
+  }
+
   //----------------------------------------------------------------------------
   int FGCanvasSystemAdapter::gcSave(naRef r)
   {
index 0f13057ccdca045ae1cdf20974b6855d463ceb1c..d56397a088c19ab0278d1ceeabfb668ac27230b7 100644 (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,
index d2a0b332ff29b7bf802fb32da13b175e8cc62145..02d8073c78b3644f8702b14e628c213c50a758c6 100644 (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;
index 624ef1acadbc1b51f4dd6920e645f42a22b7dd6d..8c8ea3158eab2c9bbbc2456a6be2be7f55bf5eb3 100644 (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);
 }
 
 //------------------------------------------------------------------------------
index 3297eafc1a8474dca05491b67e56ebaaba20feb1..976b336ae07c64e62fc887080ea24dda9efb5bc0 100644 (file)
@@ -26,7 +26,7 @@ class CanvasWidget:
     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);
@@ -44,6 +44,9 @@ class CanvasWidget:
                        *_mouse_y,
                        *_mouse_down,
                        *_mouse_drag;
+
+    int _last_x,
+        _last_y;
 };
 
 #endif /* CANVASWIDGET_HXX_ */
index 3555d5039044645bf5888d72891769c6d3caa165..ebaba3cd079c3e6a6d376b9efa55a4fecf980b93 100644 (file)
@@ -139,7 +139,6 @@ void GUIInfo::apply_format(SGPropertyNode *n)
 }
 
 
-\f
 /**
  * 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
-                |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);
@@ -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();
 }
-\f////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
 // Callbacks.
 ////////////////////////////////////////////////////////////////////////
 
@@ -428,7 +461,6 @@ action_callback (puObject *object)
 }
 
 
-\f
 ////////////////////////////////////////////////////////////////////////
 // Static helper functions.
 ////////////////////////////////////////////////////////////////////////
@@ -511,7 +543,6 @@ copy_from_pui (puObject *object, SGPropertyNode *node)
 }
 
 
-\f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGDialog.
 ////////////////////////////////////////////////////////////////////////
@@ -1186,7 +1217,7 @@ FGPUIDialog::getKeyCode(const char *str)
     return key;
 }
 
-void\fFGPUIDialog::relayout()
+void FGPUIDialog::relayout()
 {
   _needsRelayout = false;
   
@@ -1291,7 +1322,6 @@ FGPUIDialog::PropertyObject::PropertyObject(const char *n,
 
 
 
-\f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of fgValueList and derived pui widgets
 ////////////////////////////////////////////////////////////////////////
index e3a158e8bc2daef1205e158d40c0d81f64fe70b9..71024ca837e30059503f756dabd3bdc744f15ede 100644 (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 *);
index df5c6936368c66ad53b169a52aba68eadd28843d..8c70b51ac4a6b8c96d54fbc620d04a5a2036d8a4 100644 (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");