]> git.mxchange.org Git - flightgear.git/commitdiff
MouseInput changes to support hover.
authorJames Turner <zakalawe@mac.com>
Sat, 9 Feb 2013 16:05:54 +0000 (16:05 +0000)
committerJames Turner <zakalawe@mac.com>
Mon, 4 Mar 2013 23:35:30 +0000 (23:35 +0000)
This adds the framework for platform cursor implementations; Windows and X11 to be done.
It also extend the mouse-input code to generate hover events suitable for driving tooltips.

Note there should be no visible functionality change from this commit, since everything
is inactive until fgdata changes are made.

17 files changed:
src/GUI/CMakeLists.txt
src/GUI/CocoaMouseCursor.hxx [new file with mode: 0644]
src/GUI/CocoaMouseCursor.mm [new file with mode: 0644]
src/GUI/MouseCursor.cxx [new file with mode: 0644]
src/GUI/MouseCursor.hxx [new file with mode: 0644]
src/Input/FGMouseInput.cxx
src/Input/FGMouseInput.hxx
src/Main/fg_commands.cxx
src/Main/fg_os.hxx
src/Scenery/scenery.cxx
src/Scripting/NasalSys.cxx
src/Scripting/NasalSys.hxx
src/Viewer/CameraGroup.cxx
src/Viewer/CameraGroup.hxx
src/Viewer/FGEventHandler.cxx
src/Viewer/renderer.cxx
src/Viewer/renderer.hxx

index d3bf72bdbd758d7651c3a310033258b6ff6b3566..469117e4f828fd99cda503a68d8e76f717a6fbe5 100644 (file)
@@ -20,6 +20,7 @@ set(SOURCES
        FGColor.cxx
     FileDialog.cxx
     PUIFileDialog.cxx
+    MouseCursor.cxx
        )
 
 set(HEADERS
@@ -39,11 +40,12 @@ set(HEADERS
        FGColor.hxx
     FileDialog.hxx
     PUIFileDialog.hxx
+    MouseCursor.hxx
        )
                
 if (APPLE)
-    list(APPEND HEADERS FGCocoaMenuBar.hxx CocoaFileDialog.hxx)
-    list(APPEND SOURCES FGCocoaMenuBar.mm CocoaFileDialog.mm)
+    list(APPEND HEADERS FGCocoaMenuBar.hxx CocoaFileDialog.hxx CocoaMouseCursor.hxx)
+    list(APPEND SOURCES FGCocoaMenuBar.mm CocoaFileDialog.mm CocoaMouseCursor.mm)
 endif()
                
 flightgear_component(GUI "${SOURCES}" "${HEADERS}")
diff --git a/src/GUI/CocoaMouseCursor.hxx b/src/GUI/CocoaMouseCursor.hxx
new file mode 100644 (file)
index 0000000..6ee3483
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef FG_GUI_COCOA_MOUSE_CURSOR_HXX
+#define FG_GUI_COCOA_MOUSE_CURSOR_HXX
+
+#include <memory> // for auto_ptr
+
+#include "MouseCursor.hxx"
+
+class CocoaMouseCursor : public FGMouseCursor
+{
+public:
+    CocoaMouseCursor();
+    virtual ~CocoaMouseCursor();
+    
+    virtual void setCursor(Cursor aCursor);
+    
+    virtual void setCursorVisible(bool aVis);
+    
+    virtual void hideCursorUntilMouseMove();
+    
+    virtual void mouseMoved();
+
+private:
+    class CocoaMouseCursorPrivate;
+    std::auto_ptr<CocoaMouseCursorPrivate> d;
+};
+
+
+#endif
diff --git a/src/GUI/CocoaMouseCursor.mm b/src/GUI/CocoaMouseCursor.mm
new file mode 100644 (file)
index 0000000..7cb631c
--- /dev/null
@@ -0,0 +1,93 @@
+#include "CocoaMouseCursor.hxx"
+
+#include <Cocoa/Cocoa.h>
+#include <map>
+
+#include <Main/globals.hxx>
+
+class CocoaMouseCursor::CocoaMouseCursorPrivate
+{
+public:
+    Cursor activeCursorKey;
+    
+    typedef std::map<Cursor, NSCursor*> CursorMap;
+    CursorMap cursors;
+};
+
+NSCursor* cocoaCursorForKey(FGMouseCursor::Cursor aKey)
+{
+    NSImage* img = nil;
+    
+    NSString* path = [NSString stringWithCString:globals->get_fg_root().c_str()
+                                            encoding:NSUTF8StringEncoding];
+    path = [path stringByAppendingPathComponent:@"gui"];
+    
+    switch (aKey) {
+    case FGMouseCursor::CURSOR_HAND: return [NSCursor pointingHandCursor];
+    case FGMouseCursor::CURSOR_CROSSHAIR: return [NSCursor crosshairCursor];
+    case FGMouseCursor::CURSOR_IBEAM: return [NSCursor IBeamCursor];
+    
+    // FIXME - use a proper left-right cursor here.
+    case FGMouseCursor::CURSOR_LEFT_RIGHT: return [NSCursor resizeLeftRightCursor];
+            
+    case FGMouseCursor::CURSOR_SPIN_CW:
+        path = [path stringByAppendingPathComponent:@"cursor-spin-cw.png"];
+        img = [[NSImage alloc] initWithContentsOfFile:path];
+        return [[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(16,16)];
+            
+    case FGMouseCursor::CURSOR_SPIN_CCW:
+        path = [path stringByAppendingPathComponent:@"cursor-spin-cw.png"];
+        img = [[NSImage alloc] initWithContentsOfFile:path];
+        return [[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(16,16)];
+            
+    default: return [NSCursor arrowCursor];
+    }
+
+}
+
+CocoaMouseCursor::CocoaMouseCursor() :
+    d(new CocoaMouseCursorPrivate)
+{
+    
+}
+
+CocoaMouseCursor::~CocoaMouseCursor()
+{
+    
+    
+}
+
+
+void CocoaMouseCursor::setCursor(Cursor aCursor)
+{
+    if (aCursor == d->activeCursorKey) {
+        return;
+    }
+    
+    d->activeCursorKey = aCursor;
+    if (d->cursors.find(aCursor) == d->cursors.end()) {
+        d->cursors[aCursor] = cocoaCursorForKey(aCursor);
+        [d->cursors[aCursor] retain];
+    }
+    
+    [d->cursors[aCursor] set];
+}
+
+void CocoaMouseCursor::setCursorVisible(bool aVis)
+{
+    if (aVis) {
+        [NSCursor unhide];
+    } else {
+        [NSCursor hide];
+    }
+}
+
+void CocoaMouseCursor::hideCursorUntilMouseMove()
+{
+    [NSCursor setHiddenUntilMouseMoves:YES];
+}
+
+void CocoaMouseCursor::mouseMoved()
+{
+    // no-op
+}
diff --git a/src/GUI/MouseCursor.cxx b/src/GUI/MouseCursor.cxx
new file mode 100644 (file)
index 0000000..c3c720f
--- /dev/null
@@ -0,0 +1,203 @@
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include "MouseCursor.hxx"
+
+#include <cstring>
+#include <boost/foreach.hpp>
+
+#include <osgViewer/GraphicsWindow>
+#include <osgViewer/Viewer>
+
+#include <simgear/debug/logstream.hxx>
+#include <simgear/simgear_config.h>
+#include <simgear/structure/commands.hxx>
+
+#ifdef SG_MAC
+#include "CocoaMouseCursor.hxx"
+#endif
+
+#include <Main/fg_props.hxx>
+#include <Main/globals.hxx>
+#include <Viewer/renderer.hxx>
+#include <Main/fg_os.hxx> // for fgWarpMouse
+
+namespace
+{
+    
+/**
+ * @brief when no native cursor implementation is available, use the osgViewer support. This
+ * has several limitations but is better than nothing
+ */
+class StockOSGCursor : public FGMouseCursor
+{
+public:
+    StockOSGCursor() :
+        mCursorObscured(false),
+        mCursorVisible(true),
+        mCursor(osgViewer::GraphicsWindow::InheritCursor)
+    {
+        mActualCursor = mCursor;
+        
+        globals->get_renderer()->getViewer()->getWindows(mWindows);
+    }
+
+    virtual void setCursor(Cursor aCursor)
+    {
+        mCursor = translateCursor(aCursor);
+        updateCursor();
+    }
+    
+    virtual void setCursorVisible(bool aVis)
+    {
+        if (mCursorObscured == aVis) {
+            return;
+        }
+        
+        mCursorVisible = aVis;
+        updateCursor();
+    }
+    
+    virtual void hideCursorUntilMouseMove()
+    {
+        if (mCursorObscured) {
+            return;
+        }
+        
+        mCursorObscured = true;
+        updateCursor();
+    }
+    
+    virtual void mouseMoved()
+    {
+        if (mCursorObscured) {
+            mCursorObscured = false;
+            updateCursor();
+        }
+    }
+private:
+    osgViewer::GraphicsWindow::MouseCursor translateCursor(Cursor aCursor)
+    {
+        switch (aCursor) {
+        case CURSOR_HAND: return osgViewer::GraphicsWindow::HandCursor;
+        case CURSOR_CROSSHAIR: return osgViewer::GraphicsWindow::CrosshairCursor;
+        case CURSOR_IBEAM: return osgViewer::GraphicsWindow::TextCursor;
+        case CURSOR_LEFT_RIGHT: return osgViewer::GraphicsWindow::LeftRightCursor;
+                    
+        default: return osgViewer::GraphicsWindow::InheritCursor;   
+        }
+    }
+    
+    void updateCursor()
+    {
+        osgViewer::GraphicsWindow::MouseCursor cur = osgViewer::GraphicsWindow::InheritCursor;
+        if (mCursorObscured || !mCursorVisible) {
+            cur = osgViewer::GraphicsWindow::NoCursor;
+        } else {
+            cur = mCursor;
+        }
+        
+        if (cur == mActualCursor) {
+            return;
+        }
+        
+        std::cout << "actually setting cursor" << std::endl;
+        BOOST_FOREACH(osgViewer::GraphicsWindow* gw, mWindows) {
+            gw->setCursor(cur);
+        }
+        
+        mActualCursor = cur;
+    }
+    
+    bool mCursorObscured;
+    bool mCursorVisible;
+    osgViewer::GraphicsWindow::MouseCursor mCursor, mActualCursor;
+    std::vector<osgViewer::GraphicsWindow*> mWindows;
+};
+    
+} // of anonymous namespace
+
+static FGMouseCursor* static_instance = NULL;
+
+FGMouseCursor::FGMouseCursor() :
+    mAutoHideTimeMsec(10000)
+{
+}
+
+FGMouseCursor* FGMouseCursor::instance()
+{
+    if (static_instance == NULL) {
+    #ifdef SG_MAC
+        if (true) {
+            static_instance = new CocoaMouseCursor;
+        }
+    #endif
+        
+        // windows
+        
+        // X11
+                
+        if (static_instance == NULL) {
+            static_instance = new StockOSGCursor;
+        }
+        
+        // initialise mouse-hide delay from global properties
+        
+        globals->get_commands()->addCommand("set-cursor", static_instance, &FGMouseCursor::setCursorCommand);
+    }
+    
+    return static_instance;
+}
+
+void FGMouseCursor::setAutoHideTimeMsec(unsigned int aMsec)
+{
+    mAutoHideTimeMsec = aMsec;
+}
+
+
+bool FGMouseCursor::setCursorCommand(const SGPropertyNode* arg)
+{
+    // JMT 2013 - I would prefer this was a seperate 'warp' command, but
+    // historically set-cursor has done both. 
+    if (arg->hasValue("x") || arg->hasValue("y")) {
+        SGPropertyNode *mx = fgGetNode("/devices/status/mice/mouse/x", true);
+        SGPropertyNode *my = fgGetNode("/devices/status/mice/mouse/y", true);
+        int x = arg->getIntValue("x", mx->getIntValue());
+        int y = arg->getIntValue("y", my->getIntValue());
+        fgWarpMouse(x, y);
+        mx->setIntValue(x);
+        my->setIntValue(y);
+    }
+
+    
+    Cursor c = cursorFromString(arg->getStringValue("cursor"));    
+    setCursor(c);
+    return true;
+}
+
+typedef struct {
+    const char * name;
+    FGMouseCursor::Cursor cursor;
+} MouseCursorMap;
+
+const MouseCursorMap mouse_cursor_map[] = {
+    { "inherit", FGMouseCursor::CURSOR_ARROW },
+    { "crosshair", FGMouseCursor::CURSOR_CROSSHAIR },
+    { "left-right", FGMouseCursor::CURSOR_LEFT_RIGHT },
+    { "hand", FGMouseCursor::CURSOR_HAND },
+    { "text", FGMouseCursor::CURSOR_IBEAM },
+    { 0, FGMouseCursor::CURSOR_ARROW }
+};
+
+FGMouseCursor::Cursor FGMouseCursor::cursorFromString(const char* cursor_name)
+{
+    for (unsigned int k = 0; mouse_cursor_map[k].name != 0; k++) {
+        if (!strcmp(mouse_cursor_map[k].name, cursor_name)) {
+            return mouse_cursor_map[k].cursor;
+        }
+    }
+
+    SG_LOG(SG_GENERAL, SG_WARN, "unknown cursor:" << cursor_name);
+    return CURSOR_ARROW;
+}
diff --git a/src/GUI/MouseCursor.hxx b/src/GUI/MouseCursor.hxx
new file mode 100644 (file)
index 0000000..d370c59
--- /dev/null
@@ -0,0 +1,47 @@
+
+// MouseCursor.hxx - abstract inteface for  mouse cursor control
+
+#ifndef FG_GUI_MOUSE_CURSOR_HXX
+#define FG_GUI_MOUSE_CURSOR_HXX 1
+
+class SGPropertyNode;
+
+class FGMouseCursor
+{
+public:
+    static FGMouseCursor* instance();
+
+    virtual void setAutoHideTimeMsec(unsigned int aMsec);
+  
+    enum Cursor
+    {
+        CURSOR_ARROW,
+        CURSOR_HAND,
+        CURSOR_CROSSHAIR,
+        CURSOR_IBEAM, ///< for editing text
+        CURSOR_IN_OUT, ///< arrow pointing into / out of the screen
+        CURSOR_LEFT_RIGHT,
+        CURSOR_UP_DOWN,
+        CURSOR_SPIN_CW,
+        CURSOR_SPIN_CCW
+    };
+  
+    virtual void setCursor(Cursor aCursor) = 0;
+    
+    virtual void setCursorVisible(bool aVis) = 0;
+    
+    virtual void hideCursorUntilMouseMove() = 0;
+    
+    virtual void mouseMoved() = 0;
+    
+    static Cursor cursorFromString(const char* str);
+
+protected:
+    FGMouseCursor();
+    
+    bool setCursorCommand(const SGPropertyNode* arg);
+    
+    unsigned int mAutoHideTimeMsec;
+};
+
+#endif // FG_GUI_MOUSE_CURSOR_HXX
index f55e7c41c82304b101dbea21732e62884e0249f0..bb76d10d520f86a09c6212691a66474ac459fc08 100644 (file)
 
 #include "FGMouseInput.hxx"
 
+#include <boost/foreach.hpp>
 #include <osgGA/GUIEventAdapter>
+
+#include <simgear/scene/util/SGPickCallback.hxx>
+#include <simgear/timing/timestamp.hxx>
+
+#include "FGButton.hxx"
 #include "Main/globals.hxx"
+#include <Viewer/renderer.hxx>
+#include <plib/pu.h>
+#include <Model/panelnode.hxx>
+#include <Cockpit/panel.hxx>
+#include <Viewer/FGEventHandler.hxx>
+#include <GUI/MouseCursor.hxx>
 
 using std::ios_base;
 
+const int MAX_MICE = 1;
+const int MAX_MOUSE_BUTTONS = 8;
+
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * List of currently pressed mouse button events
+ */
+class ActivePickCallbacks : public std::map<int, std::list<SGSharedPtr<SGPickCallback> > > {
+public:
+    void update( double dt );
+    void init( int button, const osgGA::GUIEventAdapter* ea );
+};
+
+
 void ActivePickCallbacks::init( int button, const osgGA::GUIEventAdapter* ea )
 {
+  osg::Vec2d windowPos;
+  flightgear::eventToWindowCoords(ea, windowPos.x(), windowPos.y());
+    
   // Get the list of hit callbacks. Take the first callback that
   // accepts the mouse button press and ignore the rest of them
   // That is they get sorted by distance and by scenegraph depth.
   // The nearest one is the first one and the deepest
   // (the most specialized one in the scenegraph) is the first.
   std::vector<SGSceneryPick> pickList;
-  if (!globals->get_renderer()->pick(pickList, ea)) {
+  if (!globals->get_renderer()->pick(pickList, windowPos)) {
     return;
   }
 
@@ -65,42 +95,155 @@ void ActivePickCallbacks::update( double dt )
   }
 }
 
+////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Settings for a mouse mode.
+ */
+struct mouse_mode {
+    mouse_mode ();
+    virtual ~mouse_mode ();
+    FGMouseCursor::Cursor cursor;
+    bool constrained;
+    bool pass_through;
+    FGButton * buttons;
+    SGBindingList x_bindings[KEYMOD_MAX];
+    SGBindingList y_bindings[KEYMOD_MAX];
+};
+
+
+/**
+ * Settings for a mouse.
+ */
+struct mouse {
+    mouse ();
+    virtual ~mouse ();
+    int x, y;
+    SGPropertyNode_ptr mode_node;
+    SGPropertyNode_ptr mouse_button_nodes[MAX_MOUSE_BUTTONS];
+    int nModes;
+    int current_mode;
+    
+    SGTimeStamp timeSinceLastMove;
+    mouse_mode * modes;
+};
+
+////////////////////////////////////////////////////////////////////////
+
+class FGMouseInput::FGMouseInputPrivate
+{
+public:
+    FGMouseInputPrivate() :
+        haveWarped(false),
+        xSizeNode(fgGetNode("/sim/startup/xsize", false ) ),
+        ySizeNode(fgGetNode("/sim/startup/ysize", false ) ),
+        xAccelNode(fgGetNode("/devices/status/mice/mouse/accel-x", true ) ),
+        yAccelNode(fgGetNode("/devices/status/mice/mouse/accel-y", true ) ),
+        hideCursorNode(fgGetNode("/sim/mouse/hide-cursor", true ) ),
+        cursorTimeoutNode(fgGetNode("/sim/mouse/cursor-timeout-sec", true ) ),
+        rightButtonModeCycleNode(fgGetNode("/sim/mouse/right-button-mode-cycle-enabled", true)),
+        tooltipShowDelayNode( fgGetNode("/sim/mouse/tooltip-delay-msec", true) ),
+        clickTriggersTooltipNode( fgGetNode("/sim/mouse/click-shows-tooltip", true) )
+    {
+        tooltipTimeoutDone = false;
+    }
+  
+    void centerMouseCursor(mouse& m)
+    {    
+      // center the cursor
+      m.x = (xSizeNode ? xSizeNode->getIntValue() : 800) / 2;
+      m.y = (ySizeNode ? ySizeNode->getIntValue() : 600) / 2;
+      fgWarpMouse(m.x, m.y);
+      haveWarped = true;
+    }
+    
+    void doHoverPick(const osg::Vec2d& windowPos)
+    {
+        std::vector<SGSceneryPick> pickList;
+        SGPickCallback::Priority priority = SGPickCallback::PriorityScenery;
+        
+        if (globals->get_renderer()->pick(pickList, windowPos)) {
+            
+            std::vector<SGSceneryPick>::const_iterator i;
+            for (i = pickList.begin(); i != pickList.end(); ++i) {
+                if (i->callback->hover(windowPos, i->info)) {
+                    return;
+                }
+                
+            // if the callback is of higher prioirty (lower enum index),
+            // record that.
+                if (i->callback->getPriority() < priority) {
+                    priority = i->callback->getPriority();
+                }
+            }
+        } // of have valid pick
+                
+        if (priority < SGPickCallback::PriorityScenery) {
+            FGMouseCursor::instance()->setCursor(FGMouseCursor::CURSOR_HAND);
+        } else {
+            // restore normal cursor
+            FGMouseCursor::instance()->setCursor(FGMouseCursor::CURSOR_ARROW);
+        }
+        
+        updateHover();
+    }
+    
+    void updateHover()
+    {
+        SGPropertyNode_ptr args(new SGPropertyNode);
+        globals->get_commands()->execute("update-hover", args);
+    }
+
+    
+    ActivePickCallbacks activePickCallbacks;
+
+    mouse mice[MAX_MICE];
+    
+    bool haveWarped;
+    bool tooltipTimeoutDone;
+  
+    SGPropertyNode_ptr xSizeNode;
+    SGPropertyNode_ptr ySizeNode;
+    SGPropertyNode_ptr xAccelNode;
+    SGPropertyNode_ptr yAccelNode;
+    SGPropertyNode_ptr hideCursorNode;
+    SGPropertyNode_ptr cursorTimeoutNode;
+    SGPropertyNode_ptr rightButtonModeCycleNode;
+    SGPropertyNode_ptr tooltipShowDelayNode;
+    SGPropertyNode_ptr clickTriggersTooltipNode;
+};
+
 
-#include <plib/pu.h>
-#include <Model/panelnode.hxx>
-#include <Cockpit/panel.hxx>
 ////////////////////////////////////////////////////////////////////////
 // The Mouse Input Implementation
 ////////////////////////////////////////////////////////////////////////
 
-const FGMouseInput::MouseCursorMap FGMouseInput::mouse_cursor_map[] = {
-    { "none", MOUSE_CURSOR_NONE },
-    { "inherit", MOUSE_CURSOR_POINTER },
-    { "wait", MOUSE_CURSOR_WAIT },
-    { "crosshair", MOUSE_CURSOR_CROSSHAIR },
-    { "left-right", MOUSE_CURSOR_LEFTRIGHT },
-    { 0, 0 }
-};
+static FGMouseInput* global_mouseInput = NULL;
+
+static void mouseClickHandler(int button, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter* ea)
+{
+    if(global_mouseInput)
+        global_mouseInput->doMouseClick(button, updown, x, y, mainWindow, ea);
+}
+
+static void mouseMotionHandler(int x, int y, const osgGA::GUIEventAdapter* ea)
+{
+    if (global_mouseInput != 0)
+        global_mouseInput->doMouseMotion(x, y, ea);
+}
+
 
-FGMouseInput * FGMouseInput::mouseInput = NULL;
 
 FGMouseInput::FGMouseInput() :
-  haveWarped(false),
-  xSizeNode(fgGetNode("/sim/startup/xsize", false ) ),
-  ySizeNode(fgGetNode("/sim/startup/ysize", false ) ),
-  xAccelNode(fgGetNode("/devices/status/mice/mouse/accel-x", true ) ),
-  yAccelNode(fgGetNode("/devices/status/mice/mouse/accel-y", true ) ),
-  hideCursorNode(fgGetNode("/sim/mouse/hide-cursor", true ) ),
-  cursorTimeoutNode(fgGetNode("/sim/mouse/cursor-timeout-sec", true ) )
+  d(new FGMouseInputPrivate)
 {
-  if( mouseInput == NULL )
-    mouseInput = this;
+    global_mouseInput = this;
 }
 
 FGMouseInput::~FGMouseInput()
 {
-  if( mouseInput == this )
-    mouseInput = NULL;
+    global_mouseInput = NULL;
 }
 
 void FGMouseInput::init()
@@ -117,7 +260,7 @@ void FGMouseInput::init()
   int j;
   for (int i = 0; i < MAX_MICE; i++) {
     SGPropertyNode * mouse_node = mouse_nodes->getChild("mouse", i, true);
-    mouse &m = bindings[i];
+    mouse &m = d->mice[i];
 
                                 // Grab node pointers
     std::ostringstream buf;
@@ -140,19 +283,11 @@ void FGMouseInput::init()
 
     for (int j = 0; j < m.nModes; j++) {
       int k;
-
-                                // Read the mouse cursor for this mode
       SGPropertyNode * mode_node = mouse_node->getChild("mode", j, true);
-      const char * cursor_name =
-        mode_node->getStringValue("cursor", "inherit");
-      m.modes[j].cursor = MOUSE_CURSOR_POINTER;
-      for (k = 0; mouse_cursor_map[k].name != 0; k++) {
-        if (!strcmp(mouse_cursor_map[k].name, cursor_name)) {
-          m.modes[j].cursor = mouse_cursor_map[k].cursor;
-          break;
-        }
-      }
 
+    // Read the mouse cursor for this mode
+      m.modes[j].cursor = FGMouseCursor::cursorFromString(mode_node->getStringValue("cursor", "inherit"));
+        
                                 // Read other properties for this mode
       m.modes[j].constrained = mode_node->getBoolValue("constrained", false);
       m.modes[j].pass_through = mode_node->getBoolValue("pass-through", false);
@@ -163,7 +298,6 @@ void FGMouseInput::init()
       for (k = 0; k < MAX_MOUSE_BUTTONS; k++) {
         buf.seekp(ios_base::beg);
         buf << "mouse button " << k;
-        SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse button " << k);
         m.modes[j].buttons[k].init( mode_node->getChild("button", k), buf.str(), module );
       }
 
@@ -179,70 +313,68 @@ void FGMouseInput::init()
 
 void FGMouseInput::update ( double dt )
 {
-  double cursorTimeout = cursorTimeoutNode ? cursorTimeoutNode->getDoubleValue() : 10.0;
-
-  mouse &m = bindings[0];
+  int cursorTimeoutMsec = d->cursorTimeoutNode->getDoubleValue() * 1000;
+  int tooltipDelayMsec = d->tooltipShowDelayNode->getIntValue();
+  
+  mouse &m = d->mice[0];
   int mode =  m.mode_node->getIntValue();
   if (mode != m.current_mode) {
+    // current mode has changed
     m.current_mode = mode;
-    m.timeout = cursorTimeout;
+    m.timeSinceLastMove.stamp();
+      
     if (mode >= 0 && mode < m.nModes) {
-      fgSetMouseCursor(m.modes[mode].cursor);
-      m.x = (xSizeNode ? xSizeNode->getIntValue() : 800) / 2;
-      m.y = (ySizeNode ? ySizeNode->getIntValue() : 600) / 2;
-      fgWarpMouse(m.x, m.y);
-      haveWarped = true;
+      FGMouseCursor::instance()->setCursor(m.modes[mode].cursor);
+      d->centerMouseCursor(m);
     } else {
-      SG_LOG(SG_INPUT, SG_DEBUG, "Mouse mode " << mode << " out of range");
-      fgSetMouseCursor(MOUSE_CURSOR_POINTER);
+      SG_LOG(SG_INPUT, SG_WARN, "Mouse mode " << mode << " out of range");
+      FGMouseCursor::instance()->setCursor(FGMouseCursor::CURSOR_ARROW);
     }
   }
 
-  if ( hideCursorNode ==NULL || hideCursorNode->getBoolValue() ) {
-      if ( m.x != m.save_x || m.y != m.save_y ) {
-          m.timeout = cursorTimeout;
-          if (fgGetMouseCursor() == MOUSE_CURSOR_NONE)
-              fgSetMouseCursor(m.modes[mode].cursor);
-      } else {
-          m.timeout -= dt;
-          if ( m.timeout <= 0.0 ) {
-              fgSetMouseCursor(MOUSE_CURSOR_NONE);
-              m.timeout = 0.0;
-          }
+  if ( d->hideCursorNode == NULL || d->hideCursorNode->getBoolValue() ) {
+      // if delay is <= 0, disable tooltips
+      if ( !d->tooltipTimeoutDone &&
+           (tooltipDelayMsec > 0) &&
+           (m.timeSinceLastMove.elapsedMSec() > tooltipDelayMsec))
+      {
+          d->tooltipTimeoutDone = true;
+          SGPropertyNode_ptr arg(new SGPropertyNode);
+          globals->get_commands()->execute("tooltip-timeout", arg);
+      }
+    
+      if ( m.timeSinceLastMove.elapsedMSec() > cursorTimeoutMsec) {
+          FGMouseCursor::instance()->hideCursorUntilMouseMove();
+          m.timeSinceLastMove.stamp();
       }
-      m.save_x = m.x;
-      m.save_y = m.y;
   }
-
-  activePickCallbacks.update( dt );
+    
+  d->activePickCallbacks.update( dt );
 }
 
-FGMouseInput::mouse::mouse ()
+mouse::mouse ()
   : x(-1),
     y(-1),
-    save_x(-1),
-    save_y(-1),
     nModes(1),
     current_mode(0),
-    timeout(0),
     modes(NULL)
 {
 }
 
-FGMouseInput::mouse::~mouse ()
+mouse::~mouse ()
 {
   delete [] modes;
 }
 
-FGMouseInput::mouse_mode::mouse_mode ()
-  : cursor(MOUSE_CURSOR_POINTER),
+mouse_mode::mouse_mode ()
+  : cursor(FGMouseCursor::CURSOR_ARROW),
     constrained(false),
     pass_through(false),
     buttons(NULL)
 {
 }
 
-FGMouseInput::mouse_mode::~mouse_mode ()
+mouse_mode::~mouse_mode ()
 {
                                 // FIXME: memory leak
 //   for (int i = 0; i < KEYMOD_MAX; i++) {
@@ -252,30 +384,36 @@ FGMouseInput::mouse_mode::~mouse_mode ()
 //     for (j = 0; j < y_bindings[i].size(); j++)
 //       delete bindings[i][j];
 //   }
-  delete [] buttons;
+  if (buttons) {
+    delete [] buttons;
+  }
 }
 
 void FGMouseInput::doMouseClick (int b, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter* ea)
 {
   int modifiers = fgGetKeyModifiers();
 
-  mouse &m = bindings[0];
+  mouse &m = d->mice[0];
   mouse_mode &mode = m.modes[m.current_mode];
-
                                 // Let the property manager know.
   if (b >= 0 && b < MAX_MOUSE_BUTTONS)
     m.mouse_button_nodes[b]->setBoolValue(updown == MOUSE_BUTTON_DOWN);
 
-                                // Pass on to PUI and the panel if
-                                // requested, and return if one of
-                                // them consumes the event.
+  if (!d->rightButtonModeCycleNode->getBoolValue() && (b == 2)) {
+    // in spring-loaded look mode, ignore right clicks entirely here
+    return;
+  }
+  
+  // Pass on to PUI and the panel if
+  // requested, and return if one of
+  // them consumes the event.
 
   if (updown != MOUSE_BUTTON_DOWN) {
     // Execute the mouse up event in any case, may be we should
     // stop processing here?
-    while (!activePickCallbacks[b].empty()) {
-      activePickCallbacks[b].front()->buttonReleased();
-      activePickCallbacks[b].pop_front();
+    while (!d->activePickCallbacks[b].empty()) {
+      d->activePickCallbacks[b].front()->buttonReleased();
+      d->activePickCallbacks[b].pop_front();
     }
   }
 
@@ -287,7 +425,7 @@ void FGMouseInput::doMouseClick (int b, int updown, int x, int y, bool mainWindo
       // pui didn't want the click event so compute a
       // scenegraph intersection point corresponding to the mouse click
       if (updown == MOUSE_BUTTON_DOWN) {
-        activePickCallbacks.init( b, ea );
+        d->activePickCallbacks.init( b, ea );
       }
     }
   }
@@ -300,54 +438,91 @@ void FGMouseInput::doMouseClick (int b, int updown, int x, int y, bool mainWindo
   }
 
   m.modes[m.current_mode].buttons[b].update( modifiers, 0 != updown, x, y);
+  
+  if (d->clickTriggersTooltipNode->getBoolValue()) {
+    SGPropertyNode_ptr args(new SGPropertyNode);
+    args->setStringValue("reason", "click");
+    globals->get_commands()->execute("tooltip-timeout", args);
+    d->tooltipTimeoutDone = true;
+  }
 }
 
-void FGMouseInput::doMouseMotion (int x, int y)
+void FGMouseInput::doMouseMotion (int x, int y, const osgGA::GUIEventAdapter* ea)
 {
-  // Don't call fgGetKeyModifiers() here, until we are using a
-  // toolkit that supports getting the mods from outside a key
-  // callback.  Glut doesn't.
-  int modifiers = KEYMOD_NONE;
+  int modifiers = fgGetKeyModifiers();
 
-  int xsize = xSizeNode ? xSizeNode->getIntValue() : 800;
-  int ysize = ySizeNode ? ySizeNode->getIntValue() : 600;
+  int xsize = d->xSizeNode ? d->xSizeNode->getIntValue() : 800;
+  int ysize = d->ySizeNode ? d->ySizeNode->getIntValue() : 600;
 
-  mouse &m = bindings[0];
+  mouse &m = d->mice[0];
 
   if (m.current_mode < 0 || m.current_mode >= m.nModes) {
       m.x = x;
       m.y = y;
       return;
   }
-  mouse_mode &mode = m.modes[m.current_mode];
 
-                                // Pass on to PUI if requested, and return
-                                // if PUI consumed the event.
+  if (!d->activePickCallbacks[0].empty()) {
+    SG_LOG(SG_GENERAL, SG_INFO, "mouse-motion, have active pick callback");
+    BOOST_FOREACH(SGPickCallback* cb, d->activePickCallbacks[0]) {
+      cb->mouseMoved(ea);
+    }
+    
+    m.x = x;
+    m.y = y;
+    return;
+  }
+  
+  m.timeSinceLastMove.stamp();
+  FGMouseCursor::instance()->mouseMoved();
+
+  int modeIndex = m.current_mode;
+  // are we in spring-loaded look mode?
+  if (!d->rightButtonModeCycleNode->getBoolValue()) {
+    if (m.mouse_button_nodes[2]->getBoolValue()) {
+      // right mouse is down, force look mode
+      modeIndex = 3;
+    }
+  }
+
+  if (modeIndex == 0) {
+    osg::Vec2d windowPos;
+    flightgear::eventToWindowCoords(ea, windowPos.x(), windowPos.y());
+    d->doHoverPick(windowPos);
+    // mouse has moved, so we may need to issue tooltip-timeout command
+    // again
+    d->tooltipTimeoutDone = false;
+  }
+
+  mouse_mode &mode = m.modes[modeIndex];
+
+    // Pass on to PUI if requested, and return
+    // if PUI consumed the event.
   if (mode.pass_through && puMouse(x, y)) {
       m.x = x;
       m.y = y;
       return;
   }
   
-  if (haveWarped)
+  if (d->haveWarped)
   {
       // don't fire mouse-movement events at the first update after warping the mouse,
       // just remember the new mouse position
-      haveWarped = false;
+      d->haveWarped = false;
   }
   else
   {
-                                // OK, PUI didn't want the event,
-                                // so we can play with it.
+      // OK, PUI didn't want the event,
+      // so we can play with it.
       if (x != m.x) {
         int delta = x - m.x;
-        xAccelNode->setIntValue( delta );
+        d->xAccelNode->setIntValue( delta );
         for (unsigned int i = 0; i < mode.x_bindings[modifiers].size(); i++)
           mode.x_bindings[modifiers][i]->fire(double(delta), double(xsize));
       }
       if (y != m.y) {
         int delta = y - m.y;
-        yAccelNode->setIntValue( -delta );
+        d->yAccelNode->setIntValue( -delta );
         for (unsigned int i = 0; i < mode.y_bindings[modifiers].size(); i++)
           mode.y_bindings[modifiers][i]->fire(double(delta), double(ysize));
       }
@@ -370,8 +545,7 @@ void FGMouseInput::doMouseMotion (int x, int y)
     if (need_warp)
     {
       fgWarpMouse(new_x, new_y);
-      haveWarped = true;
-      SG_LOG(SG_INPUT, SG_DEBUG, "Mouse warp: " << x << ", " << y << " => " << new_x << ", " << new_y);
+      d->haveWarped = true;
     }
   }
 
@@ -382,16 +556,5 @@ void FGMouseInput::doMouseMotion (int x, int y)
       fgSetInt("/devices/status/mice/mouse/y", m.y = y);
 }
 
-void FGMouseInput::mouseClickHandler(int button, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter* ea)
-{
-    if(mouseInput)
-      mouseInput->doMouseClick(button, updown, x, y, mainWindow, ea);
-}
-
-void FGMouseInput::mouseMotionHandler(int x, int y)
-{
-    if (mouseInput != 0)
-        mouseInput->doMouseMotion(x, y);
-}
 
 
index 01c6c2cbdcacef848ca45f99059be48b8d107db0..7e163441371b8c4a9d252d5d4d48c1f843146c13 100644 (file)
 #ifndef _FGMOUSEINPUT_HXX
 #define _FGMOUSEINPUT_HXX
 
-#ifndef __cplusplus                                                          
-# error This library requires C++
-#endif
-
 #include "FGCommonInput.hxx"
-#include "FGButton.hxx"
 
-#include <map>
-#include <list>
-#include <simgear/structure/subsystem_mgr.hxx>
-#include <simgear/scene/util/SGPickCallback.hxx>
-#include <Viewer/renderer.hxx>
+#include <memory>
 
-/**
-  * List of currently pressed mouse button events
-  */
-class ActivePickCallbacks : public std::map<int, std::list<SGSharedPtr<SGPickCallback> > > {
-public:
-  void update( double dt );
-  void init( int button, const osgGA::GUIEventAdapter* ea );
-};
+#include <simgear/structure/subsystem_mgr.hxx>
 
+// forward decls
+namespace osgGA { class GUIEventAdapter; }
 
 ////////////////////////////////////////////////////////////////////////
 // The Mouse Input Class
 ////////////////////////////////////////////////////////////////////////
-class FGMouseInput : public SGSubsystem,FGCommonInput {
+class FGMouseInput : public SGSubsystem, FGCommonInput {
 public:
   FGMouseInput();
   virtual ~FGMouseInput();
@@ -60,74 +46,12 @@ public:
   virtual void init();
   virtual void update( double dt );
 
-  static const int MAX_MICE = 1;
-  static const int MAX_MOUSE_BUTTONS = 8;
-
+    void doMouseClick (int b, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter* ea);
+    void doMouseMotion (int x, int y, const osgGA::GUIEventAdapter*);
 private:
-  void doMouseClick (int b, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter* ea);
-  void doMouseMotion (int x, int y);
-  static FGMouseInput * mouseInput;
-  static void mouseClickHandler(int button, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter*);
-  static void mouseMotionHandler(int x, int y);
-
-  ActivePickCallbacks activePickCallbacks;
-  /**
-   * Settings for a mouse mode.
-   */
-  struct mouse_mode {
-    mouse_mode ();
-    virtual ~mouse_mode ();
-    int cursor;
-    bool constrained;
-    bool pass_through;
-    FGButton * buttons;
-    binding_list_t x_bindings[KEYMOD_MAX];
-    binding_list_t y_bindings[KEYMOD_MAX];
-  };
-
-
-  /**
-   * Settings for a mouse.
-   */
-  struct mouse {
-    mouse ();
-    virtual ~mouse ();
-    int x;
-    int y;
-    int save_x;
-    int save_y;
-    SGPropertyNode_ptr mode_node;
-    SGPropertyNode_ptr mouse_button_nodes[MAX_MOUSE_BUTTONS];
-    int nModes;
-    int current_mode;
-    double timeout;
-    mouse_mode * modes;
-  };
-
-  // 
-  // Map of all known cursor names
-  // This used to contain all the Glut cursors, but those are
-  // not defined by other toolkits.  It now supports only the cursor
-  // images we actually use, in the interest of portability.  Someday,
-  // it would be cool to write an OpenGL cursor renderer, with the
-  // cursors defined as textures referenced in the property tree.  This
-  // list could then be eliminated. -Andy
-  //
-  const static struct MouseCursorMap {
-    const char * name;
-    int cursor;
-  } mouse_cursor_map[];
-
-  mouse bindings[MAX_MICE];
+  class FGMouseInputPrivate;
+  std::auto_ptr<FGMouseInputPrivate> d;
   
-  bool haveWarped;
-
-  SGPropertyNode_ptr xSizeNode;
-  SGPropertyNode_ptr ySizeNode;
-  SGPropertyNode_ptr xAccelNode;
-  SGPropertyNode_ptr yAccelNode;
-  SGPropertyNode_ptr hideCursorNode;
-  SGPropertyNode_ptr cursorTimeoutNode;
 };
 
 #endif
index c0e3887195664dd5081dc1b510f62de72bed570b..f1909c1fa551bca04d470942bc3f43af8fd9d4fa 100644 (file)
@@ -1108,32 +1108,6 @@ do_add_model (const SGPropertyNode * arg)
     return true;
 }
 
-
-/**
- * Set mouse cursor coordinates and cursor shape.
- */
-static bool
-do_set_cursor (const SGPropertyNode * arg)
-{
-    if (arg->hasValue("x") || arg->hasValue("y")) {
-        SGPropertyNode *mx = fgGetNode("/devices/status/mice/mouse/x", true);
-        SGPropertyNode *my = fgGetNode("/devices/status/mice/mouse/y", true);
-        int x = arg->getIntValue("x", mx->getIntValue());
-        int y = arg->getIntValue("y", my->getIntValue());
-        fgWarpMouse(x, y);
-        mx->setIntValue(x);
-        my->setIntValue(y);
-    }
-
-    SGPropertyNode *cursor = const_cast<SGPropertyNode *>(arg)->getNode("cursor", true);
-    if (cursor->getType() != simgear::props::NONE)
-        fgSetMouseCursor(cursor->getIntValue());
-
-    cursor->setIntValue(fgGetMouseCursor());
-    return true;
-}
-
-
 /**
  * Built-in command: play an audio message (i.e. a wav file) This is
  * fire and forget.  Call this once per message and it will get dumped
@@ -1612,7 +1586,6 @@ static struct {
     { "open-browser", do_open_browser },
     { "gui-redraw", do_gui_redraw },
     { "add-model", do_add_model },
-    { "set-cursor", do_set_cursor },
     { "play-audio-sample", do_play_audio_sample },
     { "presets-commit", do_presets_commit },
     { "log-level", do_log_level },
index 74d2e468bc28b09d99d6b235c1018ed890736648..46bc235a7ce09cd25502df73dc1bb1063a4759b5 100644 (file)
@@ -82,7 +82,7 @@ typedef void (*fgWindowResizeHandler)(int w, int h);
 
 typedef void (*fgKeyHandler)(int key, int keymod, int mousex, int mousey);
 typedef void (*fgMouseClickHandler)(int button, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter*);
-typedef void (*fgMouseMotionHandler)(int x, int y);
+typedef void (*fgMouseMotionHandler)(int x, int y, const osgGA::GUIEventAdapter*);
 
 void fgRegisterIdleHandler(fgIdleHandler func);
 void fgRegisterDrawHandler(fgDrawHandler func);
index f9878ba05e35f9736d1da8a29953e430a87d89b3..1f6d4c3c24825ac1c56be8e0da08383318433c83 100644 (file)
 #include <simgear/scene/model/CheckSceneryVisitor.hxx>
 #include <simgear/bvh/BVHNode.hxx>
 #include <simgear/bvh/BVHLineSegmentVisitor.hxx>
+#include <simgear/structure/commands.hxx>
 
 #include <Viewer/renderer.hxx>
 #include <Main/fg_props.hxx>
+#include <GUI/MouseCursor.hxx>
 
 #include "tilemgr.hxx"
 #include "scenery.hxx"
@@ -59,6 +61,9 @@ using namespace simgear;
 
 class FGGroundPickCallback : public SGPickCallback {
 public:
+  FGGroundPickCallback() : SGPickCallback(PriorityScenery)
+  { }
+    
   virtual bool buttonPressed(int button, const osgGA::GUIEventAdapter*, const Info& info)
   {
     // only on left mouse button
index f9e29b9afde8bb6d4e99402ab1e129ffb2331a49..bf1a1a21f5dd2c79bf16a6e8508d1037361ec6b9 100644 (file)
@@ -28,6 +28,7 @@
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/structure/event_mgr.hxx>
 #include <simgear/debug/BufferedLogCallback.hxx>
+#include <simgear/nasal/cppbind/NasalHash.hxx>
 
 #include "NasalSys.hxx"
 #include "NasalSys_private.hxx"
@@ -502,7 +503,7 @@ public:
     {
         _sys->setCmdArg(const_cast<SGPropertyNode*>(aNode));
         naRef args[1];
-        args[0] = _sys->cmdArgGhost();
+        args[0] = _sys->wrappedPropsNode(const_cast<SGPropertyNode*>(aNode));
     
         _sys->callMethod(_func, naNil(), 1, args, naNil() /* locals */);
 
@@ -697,6 +698,20 @@ void FGNasalSys::init()
     postinitNasalGUI(_globals, _context);
 }
 
+naRef FGNasalSys::wrappedPropsNode(SGPropertyNode* aProps)
+{
+    static naRef wrapNodeFunc = naNil();
+    if (naIsNil(wrapNodeFunc)) {
+        nasal::Hash g(_globals, _context);
+        nasal::Hash props = g.get<nasal::Hash>("props");
+        wrapNodeFunc = props.get("wrapNode");
+    }
+    
+    naRef args[1];
+    args[0] = propNodeGhost(aProps);
+    return naCall(_context, wrapNodeFunc, 1, args, naNil(), naNil());
+}
+
 void FGNasalSys::update(double)
 {
     if( NasalClipboard::getInstance() )
index 7a2048d7eaffc23850187363405a3935f336ccd0..fc24f9959b9d57fe3e53d73619b8a1a4a0c3753b 100644 (file)
@@ -64,6 +64,12 @@ public:
 
     void setCmdArg(SGPropertyNode* aNode);
     
+    /**
+     * create Nasal props.Node for an SGPropertyNode*
+     * This is the actual ghost, wrapped in a Nasal sugar class.
+     */
+    naRef wrappedPropsNode(SGPropertyNode* aProps);
+    
     // Callbacks for command and timer bindings
     virtual bool handleCommand( const char* moduleName,
                                 const char* fileName,
index 3d84717e5b8316e85c737c33e30afe337c8c6b97..255e675f4e9e7586878a9ffecba24b9c046f882b 100644 (file)
@@ -27,6 +27,8 @@
 #include "FGEventHandler.hxx"
 #include "WindowBuilder.hxx"
 #include "WindowSystemAdapter.hxx"
+
+#include <simgear/math/SGRect.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/structure/OSGUtils.hxx>
 #include <simgear/structure/OSGVersion.hxx>
@@ -1142,34 +1144,34 @@ Camera* getGUICamera(CameraGroup* cgroup)
     return info->getCamera(MAIN_CAMERA);
 }
 
-static bool computeCameraIntersection(const CameraInfo* cinfo,
-                                      const osgGA::GUIEventAdapter* ea,
+
+static bool computeCameraIntersection(const CameraInfo* cinfo, const osg::Vec2d& windowPos,
                                       osgUtil::LineSegmentIntersector::Intersections& intersections)
 {
   using osgUtil::Intersector;
   using osgUtil::LineSegmentIntersector;
-  double x, y;
-  eventToWindowCoords(ea, x, y);
-  
+
   if (!(cinfo->flags & CameraGroup::DO_INTERSECTION_TEST))
     return false;
   
   const Camera* camera = cinfo->getCamera(MAIN_CAMERA);
   if ( !camera )
     camera = cinfo->getCamera( GEOMETRY_CAMERA );
-  if (camera->getGraphicsContext() != ea->getGraphicsContext())
-    return false;
+  // if (camera->getGraphicsContext() != ea->getGraphicsContext())
+ //   return false;
   
   const Viewport* viewport = camera->getViewport();
+  SGRect<double> viewportRect(viewport->x(), viewport->y(),
+                              viewport->x() + viewport->width() - 1.0,
+                              viewport->y() + viewport->height()- 1.0);
+    
   double epsilon = 0.5;
-  if (!(x >= viewport->x() - epsilon
-        && x < viewport->x() + viewport->width() -1.0 + epsilon
-        && y >= viewport->y() - epsilon
-        && y < viewport->y() + viewport->height() -1.0 + epsilon))
+  if (!viewportRect.contains(windowPos.x(), windowPos.y(), epsilon))
     return false;
   
-  Vec4d start(x, y, 0.0, 1.0);
-  Vec4d end(x, y, 1.0, 1.0);
+  Vec4d start(windowPos.x(), windowPos.y(), 0.0, 1.0);
+  Vec4d end(windowPos.x(), windowPos.y(), 1.0, 1.0);
   Matrix windowMat = viewport->computeWindowMatrix();
   Matrix startPtMat = Matrix::inverse(camera->getProjectionMatrix()
                                       * windowMat);
@@ -1200,12 +1202,12 @@ static bool computeCameraIntersection(const CameraInfo* cinfo,
 }
   
 bool computeIntersections(const CameraGroup* cgroup,
-                          const osgGA::GUIEventAdapter* ea,
+                          const osg::Vec2d& windowPos,
                           osgUtil::LineSegmentIntersector::Intersections& intersections)
 {
     // test the GUI first
     const CameraInfo* guiCamera = cgroup->getGUICamera();
-    if (guiCamera && computeCameraIntersection(guiCamera, ea, intersections))
+    if (guiCamera && computeCameraIntersection(guiCamera, windowPos, intersections))
         return true;
     
     // Find camera that contains event
@@ -1217,7 +1219,7 @@ bool computeIntersections(const CameraGroup* cgroup,
         if (cinfo == guiCamera)
             continue;
         
-        if (computeCameraIntersection(cinfo, ea, intersections))
+        if (computeCameraIntersection(cinfo, windowPos, intersections))
             return true;
     }
   
index 1bdcd02de1638c502e5dc026ba7d068a3d9fcba2..1d5bd0aa06f9ff5530f58b0fc8b41a733269d0b5 100644 (file)
@@ -292,11 +292,6 @@ protected:
 
 }
 
-namespace osgGA
-{
-class GUIEventAdapter;
-}
-
 namespace flightgear
 {
 /** Get the osg::Camera that draws the GUI, if any, from a camera
@@ -315,7 +310,7 @@ osg::Camera* getGUICamera(CameraGroup* cgroup);
  * @return true if any intersections are found
  */
 bool computeIntersections(const CameraGroup* cgroup,
-                          const osgGA::GUIEventAdapter* ea,
+                          const osg::Vec2d& windowPos,
                           osgUtil::LineSegmentIntersector::Intersections&
                           intersections);
 /** Warp the pointer to coordinates in the GUI camera of a camera group.
index b877cc74685fd8af2c4400282a581b0863ebb377..aa3d5ac494758e06312944afe852f74e36e17bd7 100644 (file)
@@ -261,7 +261,7 @@ bool FGEventHandler::handle(const osgGA::GUIEventAdapter& ea,
         if (mouseWarped)
             return true;
         if (eventToViewport(ea, us, x, y) && mouseMotionHandler)
-            (*mouseMotionHandler)(x, y);
+            (*mouseMotionHandler)(x, y, &ea);
         return true;
     case osgGA::GUIEventAdapter::RESIZE:
         SG_LOG(SG_VIEW, SG_DEBUG, "FGEventHandler::handle: RESIZE event " << ea.getWindowHeight() << " x " << ea.getWindowWidth() << ", resizable: " << resizable);
@@ -417,6 +417,7 @@ void eventToWindowCoords(const osgGA::GUIEventAdapter* ea,
         y = (double)traits->height - y;
 }
 
+#if 0
 void eventToWindowCoordsYDown(const osgGA::GUIEventAdapter* ea,
                               double& x, double& y)
 {
@@ -431,4 +432,6 @@ void eventToWindowCoordsYDown(const osgGA::GUIEventAdapter* ea,
     if (ea->getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
         y = (double)traits->height - y;
 }
+#endif
+    
 }
index 2e8d8fe875cac2061b1692673370793611e3f4b7..2584df1414747d2bed96b966fb44185ca7b055ab 100644 (file)
@@ -1724,15 +1724,14 @@ FGRenderer::resize( int width, int height )
 }
 
 bool
-FGRenderer::pick(std::vector<SGSceneryPick>& pickList,
-                 const osgGA::GUIEventAdapter* ea)
+FGRenderer::pick(std::vector<SGSceneryPick>& pickList, const osg::Vec2& windowPos)
 {
     // wipe out the return ...
     pickList.clear();
     typedef osgUtil::LineSegmentIntersector::Intersections Intersections;
     Intersections intersections;
 
-    if (!computeIntersections(CameraGroup::getDefault(), ea, intersections))
+    if (!computeIntersections(CameraGroup::getDefault(), windowPos, intersections))
         return false;
     for (Intersections::iterator hit = intersections.begin(),
              e = intersections.end();
index a064dcd30ee67c3a60ea639dfe252cfeec012745..959847408b14eabd4ef6c2642c1be91b7d79c39d 100644 (file)
@@ -61,8 +61,7 @@ public:
   
     /** Just pick into the scene and return the pick callbacks on the way ...
      */
-    bool pick( std::vector<SGSceneryPick>& pickList,
-               const osgGA::GUIEventAdapter* ea );
+    bool pick( std::vector<SGSceneryPick>& pickList, const osg::Vec2& windowPos);
 
     /** Get and set the OSG Viewer object, if any.
      */