]> git.mxchange.org Git - flightgear.git/blob - src/GUI/MouseCursor.cxx
Stray debug message, remove.
[flightgear.git] / src / GUI / MouseCursor.cxx
1 #ifdef HAVE_CONFIG_H
2   #include "config.h"
3 #endif
4
5 #include "MouseCursor.hxx"
6
7 #include <cstring>
8 #include <boost/foreach.hpp>
9
10 #include <osgViewer/GraphicsWindow>
11 #include <osgViewer/Viewer>
12
13 #include <simgear/debug/logstream.hxx>
14 #include <simgear/simgear_config.h>
15 #include <simgear/structure/commands.hxx>
16
17 #ifdef SG_MAC
18 #include "CocoaMouseCursor.hxx"
19 #endif
20
21 #include <Main/fg_props.hxx>
22 #include <Main/globals.hxx>
23 #include <Viewer/renderer.hxx>
24 #include <Main/fg_os.hxx> // for fgWarpMouse
25
26 namespace
27 {
28     
29 /**
30  * @brief when no native cursor implementation is available, use the osgViewer support. This
31  * has several limitations but is better than nothing
32  */
33 class StockOSGCursor : public FGMouseCursor
34 {
35 public:
36     StockOSGCursor() :
37         mCursorObscured(false),
38         mCursorVisible(true),
39         mCursor(osgViewer::GraphicsWindow::InheritCursor)
40     {
41         mActualCursor = mCursor;
42         
43         globals->get_renderer()->getViewer()->getWindows(mWindows);
44     }
45
46     virtual void setCursor(Cursor aCursor)
47     {
48         mCursor = translateCursor(aCursor);
49         updateCursor();
50     }
51     
52     virtual void setCursorVisible(bool aVis)
53     {
54         if (mCursorObscured == aVis) {
55             return;
56         }
57         
58         mCursorVisible = aVis;
59         updateCursor();
60     }
61     
62     virtual void hideCursorUntilMouseMove()
63     {
64         if (mCursorObscured) {
65             return;
66         }
67         
68         mCursorObscured = true;
69         updateCursor();
70     }
71     
72     virtual void mouseMoved()
73     {
74         if (mCursorObscured) {
75             mCursorObscured = false;
76             updateCursor();
77         }
78     }
79 private:
80     osgViewer::GraphicsWindow::MouseCursor translateCursor(Cursor aCursor)
81     {
82         switch (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;
87                     
88         default: return osgViewer::GraphicsWindow::InheritCursor;   
89         }
90     }
91     
92     void updateCursor()
93     {
94         osgViewer::GraphicsWindow::MouseCursor cur = osgViewer::GraphicsWindow::InheritCursor;
95         if (mCursorObscured || !mCursorVisible) {
96             cur = osgViewer::GraphicsWindow::NoCursor;
97         } else {
98             cur = mCursor;
99         }
100         
101         if (cur == mActualCursor) {
102             return;
103         }
104         
105         BOOST_FOREACH(osgViewer::GraphicsWindow* gw, mWindows) {
106             gw->setCursor(cur);
107         }
108         
109         mActualCursor = cur;
110     }
111     
112     bool mCursorObscured;
113     bool mCursorVisible;
114     osgViewer::GraphicsWindow::MouseCursor mCursor, mActualCursor;
115     std::vector<osgViewer::GraphicsWindow*> mWindows;
116 };
117     
118 } // of anonymous namespace
119
120 static FGMouseCursor* static_instance = NULL;
121
122 FGMouseCursor::FGMouseCursor() :
123     mAutoHideTimeMsec(10000)
124 {
125 }
126
127 FGMouseCursor* FGMouseCursor::instance()
128 {
129     if (static_instance == NULL) {
130     #ifdef SG_MAC
131         if (true) {
132             static_instance = new CocoaMouseCursor;
133         }
134     #endif
135         
136         // windows
137         
138         // X11
139                 
140         if (static_instance == NULL) {
141             static_instance = new StockOSGCursor;
142         }
143         
144         // initialise mouse-hide delay from global properties
145         
146         globals->get_commands()->addCommand("set-cursor", static_instance, &FGMouseCursor::setCursorCommand);
147     }
148     
149     return static_instance;
150 }
151
152 void FGMouseCursor::setAutoHideTimeMsec(unsigned int aMsec)
153 {
154     mAutoHideTimeMsec = aMsec;
155 }
156
157
158 bool FGMouseCursor::setCursorCommand(const SGPropertyNode* arg)
159 {
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());
167         fgWarpMouse(x, y);
168         mx->setIntValue(x);
169         my->setIntValue(y);
170     }
171
172     
173     Cursor c = cursorFromString(arg->getStringValue("cursor"));    
174     setCursor(c);
175     return true;
176 }
177
178 typedef struct {
179     const char * name;
180     FGMouseCursor::Cursor cursor;
181 } MouseCursorMap;
182
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 }
190 };
191
192 FGMouseCursor::Cursor FGMouseCursor::cursorFromString(const char* cursor_name)
193 {
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;
197         }
198     }
199
200     SG_LOG(SG_GENERAL, SG_WARN, "unknown cursor:" << cursor_name);
201     return CURSOR_ARROW;
202 }