5 #include "MouseCursor.hxx"
8 #include <boost/foreach.hpp>
10 #include <osgViewer/GraphicsWindow>
11 #include <osgViewer/Viewer>
13 #include <simgear/debug/logstream.hxx>
14 #include <simgear/simgear_config.h>
15 #include <simgear/structure/commands.hxx>
18 #include "CocoaMouseCursor.hxx"
21 #include <Main/fg_props.hxx>
22 #include <Main/globals.hxx>
23 #include <Viewer/renderer.hxx>
24 #include <Main/fg_os.hxx> // for fgWarpMouse
30 * @brief when no native cursor implementation is available, use the osgViewer support. This
31 * has several limitations but is better than nothing
33 class StockOSGCursor : public FGMouseCursor
37 mCursorObscured(false),
39 mCursor(osgViewer::GraphicsWindow::InheritCursor)
41 mActualCursor = mCursor;
43 globals->get_renderer()->getViewer()->getWindows(mWindows);
46 virtual void setCursor(Cursor aCursor)
48 mCursor = translateCursor(aCursor);
52 virtual void setCursorVisible(bool aVis)
54 if (mCursorObscured == aVis) {
58 mCursorVisible = aVis;
62 virtual void hideCursorUntilMouseMove()
64 if (mCursorObscured) {
68 mCursorObscured = true;
72 virtual void mouseMoved()
74 if (mCursorObscured) {
75 mCursorObscured = false;
80 osgViewer::GraphicsWindow::MouseCursor translateCursor(Cursor aCursor)
83 case CURSOR_HAND: return osgViewer::GraphicsWindow::HandCursor;
84 case CURSOR_CROSSHAIR: return osgViewer::GraphicsWindow::CrosshairCursor;
85 case CURSOR_IBEAM: return osgViewer::GraphicsWindow::TextCursor;
86 case CURSOR_LEFT_RIGHT: return osgViewer::GraphicsWindow::LeftRightCursor;
88 default: return osgViewer::GraphicsWindow::InheritCursor;
94 osgViewer::GraphicsWindow::MouseCursor cur = osgViewer::GraphicsWindow::InheritCursor;
95 if (mCursorObscured || !mCursorVisible) {
96 cur = osgViewer::GraphicsWindow::NoCursor;
101 if (cur == mActualCursor) {
105 BOOST_FOREACH(osgViewer::GraphicsWindow* gw, mWindows) {
112 bool mCursorObscured;
114 osgViewer::GraphicsWindow::MouseCursor mCursor, mActualCursor;
115 std::vector<osgViewer::GraphicsWindow*> mWindows;
118 } // of anonymous namespace
120 static FGMouseCursor* static_instance = NULL;
122 FGMouseCursor::FGMouseCursor() :
123 mAutoHideTimeMsec(10000)
127 FGMouseCursor* FGMouseCursor::instance()
129 if (static_instance == NULL) {
132 static_instance = new CocoaMouseCursor;
140 if (static_instance == NULL) {
141 static_instance = new StockOSGCursor;
144 // initialise mouse-hide delay from global properties
146 globals->get_commands()->addCommand("set-cursor", static_instance, &FGMouseCursor::setCursorCommand);
149 return static_instance;
152 void FGMouseCursor::setAutoHideTimeMsec(unsigned int aMsec)
154 mAutoHideTimeMsec = aMsec;
158 bool FGMouseCursor::setCursorCommand(const SGPropertyNode* arg)
160 // JMT 2013 - I would prefer this was a seperate 'warp' command, but
161 // historically set-cursor has done both.
162 if (arg->hasValue("x") || arg->hasValue("y")) {
163 SGPropertyNode *mx = fgGetNode("/devices/status/mice/mouse/x", true);
164 SGPropertyNode *my = fgGetNode("/devices/status/mice/mouse/y", true);
165 int x = arg->getIntValue("x", mx->getIntValue());
166 int y = arg->getIntValue("y", my->getIntValue());
173 Cursor c = cursorFromString(arg->getStringValue("cursor"));
180 FGMouseCursor::Cursor cursor;
183 const MouseCursorMap mouse_cursor_map[] = {
184 { "inherit", FGMouseCursor::CURSOR_ARROW },
185 { "crosshair", FGMouseCursor::CURSOR_CROSSHAIR },
186 { "left-right", FGMouseCursor::CURSOR_LEFT_RIGHT },
187 { "hand", FGMouseCursor::CURSOR_HAND },
188 { "text", FGMouseCursor::CURSOR_IBEAM },
189 { 0, FGMouseCursor::CURSOR_ARROW }
192 FGMouseCursor::Cursor FGMouseCursor::cursorFromString(const char* cursor_name)
194 for (unsigned int k = 0; mouse_cursor_map[k].name != 0; k++) {
195 if (!strcmp(mouse_cursor_map[k].name, cursor_name)) {
196 return mouse_cursor_map[k].cursor;
200 SG_LOG(SG_GENERAL, SG_WARN, "unknown cursor:" << cursor_name);