]> git.mxchange.org Git - flightgear.git/blob - src/Main/FGManipulator.cxx
loadxml, savexml: don't pop up a GUI error message on error, but use a
[flightgear.git] / src / Main / FGManipulator.cxx
1 #ifdef HAVE_CONFIG_H
2 #  include <config.h>
3 #endif
4 #include <osg/Math>
5 #include <osgViewer/Viewer>
6 #include <plib/pu.h>
7 #include "FGManipulator.hxx"
8
9 // The manipulator is responsible for updating a Viewer's camera. It's
10 // event handling method is also a convenient place to run the the FG
11 // idle and draw handlers.
12
13 FGManipulator::FGManipulator() :
14     idleHandler(0), drawHandler(0), windowResizeHandler(0), keyHandler(0),
15     mouseClickHandler(0), mouseMotionHandler(0), currentModifiers(0),
16     osgModifiers(0)
17 {
18     keyMaskMap[osgGA::GUIEventAdapter::KEY_Shift_L]
19         = osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT;
20     keyMaskMap[osgGA::GUIEventAdapter::KEY_Shift_R]
21         = osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT;
22     keyMaskMap[osgGA::GUIEventAdapter::KEY_Control_L]
23         = osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL;
24     keyMaskMap[osgGA::GUIEventAdapter::KEY_Control_R]
25         = osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL;
26     keyMaskMap[osgGA::GUIEventAdapter::KEY_Alt_L]
27         = osgGA::GUIEventAdapter::MODKEY_LEFT_ALT;
28     keyMaskMap[osgGA::GUIEventAdapter::KEY_Alt_R]
29         = osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT;
30 }
31
32 void FGManipulator::setByMatrix(const osg::Matrixd& matrix)
33 {
34     // Yuck
35     position = matrix.getTrans();
36     attitude = matrix.getRotate();
37 }
38
39 osg::Matrixd FGManipulator::getMatrix() const
40 {
41     return osg::Matrixd::rotate(attitude) * osg::Matrixd::translate(position);
42 }
43
44 osg::Matrixd FGManipulator::getInverseMatrix() const
45 {
46     return (osg::Matrixd::translate(-position)
47             * osg::Matrixd::rotate(attitude.inverse())) ;
48 }
49
50 // Not used, but part of the interface.
51 void FGManipulator::setNode(osg::Node* node)
52 {
53     _node = node;
54 }
55     
56 const osg::Node* FGManipulator::getNode() const
57 {
58     return _node.get();
59 }
60
61 osg::Node* FGManipulator::getNode()
62 {
63     return _node.get();
64 }
65
66 // All the usual translation from window system to FG / plib
67 static int osgToFGModifiers(int modifiers)
68 {
69     int result = 0;
70     if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT |
71                      osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT))
72         result |= KEYMOD_SHIFT;
73     if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL |
74                      osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL))
75         result |= KEYMOD_CTRL;
76     if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_ALT |
77                      osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT))
78         result |= KEYMOD_ALT;
79     return result;
80 }
81
82 void FGManipulator::init(const osgGA::GUIEventAdapter& ea,
83                          osgGA::GUIActionAdapter& us)
84 {
85     currentModifiers = osgToFGModifiers(ea.getModKeyMask());
86     (void)handle(ea, us);
87 }
88
89 static bool
90 eventToViewport(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us,
91                 int& x, int& y)
92 {
93   x = -1;
94   y = -1;
95
96   const osgViewer::Viewer* viewer;
97   viewer = dynamic_cast<const osgViewer::Viewer*>(&us);
98   if (!viewer)
99       return false;
100
101   float lx, ly;
102   const osg::Camera* camera;
103   camera = viewer->getCameraContainingPosition(ea.getX(), ea.getY(), lx, ly);
104
105   if (!fgOSIsMainCamera(camera))
106       return false;
107
108   x = int(lx);
109   y = int(camera->getViewport()->height() - ly);
110
111   return true;
112 }
113
114 bool FGManipulator::handle(const osgGA::GUIEventAdapter& ea,
115                            osgGA::GUIActionAdapter& us)
116 {
117     int x, y;
118     switch (ea.getEventType()) {
119     case osgGA::GUIEventAdapter::FRAME:
120         if (idleHandler)
121             (*idleHandler)();
122         if (drawHandler)
123             (*drawHandler)();
124         return true;
125     case osgGA::GUIEventAdapter::KEYDOWN:
126     case osgGA::GUIEventAdapter::KEYUP:
127     {
128         int key, modmask;
129         handleKey(ea, key, modmask);
130         eventToViewport(ea, us, x, y);
131         if (keyHandler)
132             (*keyHandler)(key, modmask, x, y);
133         return true;
134     }
135     case osgGA::GUIEventAdapter::PUSH:
136     case osgGA::GUIEventAdapter::RELEASE:
137     {
138         bool mainWindow = eventToViewport(ea, us, x, y);
139         int button = 0;
140         switch (ea.getButton()) {
141         case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
142             button = 0;
143             break;
144         case osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
145             button = 1;
146             break;
147         case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
148             button = 2;
149             break;
150         }
151         if (mouseClickHandler)
152             (*mouseClickHandler)(button,
153                                  (ea.getEventType()
154                                   == osgGA::GUIEventAdapter::RELEASE), x, y, mainWindow, &ea);
155         return true;
156     }
157     case osgGA::GUIEventAdapter::MOVE:
158     case osgGA::GUIEventAdapter::DRAG:
159         eventToViewport(ea, us, x, y);
160         if (mouseMotionHandler)
161             (*mouseMotionHandler)(x, y);
162         return true;
163     case osgGA::GUIEventAdapter::CLOSE_WINDOW:
164     case osgGA::GUIEventAdapter::QUIT_APPLICATION:
165         fgOSExit(0);
166         return true;
167     default:
168         return false;
169     }
170 }
171
172 void FGManipulator::handleKey(const osgGA::GUIEventAdapter& ea, int& key,
173                               int& modifiers)
174 {
175     key = ea.getKey();
176     // XXX Probably other translations are needed too.
177     switch (key) {
178     case osgGA::GUIEventAdapter::KEY_Escape: key = 0x1b; break;
179     case osgGA::GUIEventAdapter::KEY_Return: key = '\n'; break;
180     case osgGA::GUIEventAdapter::KEY_BackSpace: key = '\b'; break;
181     case osgGA::GUIEventAdapter::KEY_Delete:   key = 0x7f; break;
182     case osgGA::GUIEventAdapter::KEY_Tab:      key = '\t'; break;
183     case osgGA::GUIEventAdapter::KEY_Left:     key = PU_KEY_LEFT;      break;
184     case osgGA::GUIEventAdapter::KEY_Up:       key = PU_KEY_UP;        break;
185     case osgGA::GUIEventAdapter::KEY_Right:    key = PU_KEY_RIGHT;     break;
186     case osgGA::GUIEventAdapter::KEY_Down:     key = PU_KEY_DOWN;      break;
187     case osgGA::GUIEventAdapter::KEY_Page_Up:   key = PU_KEY_PAGE_UP;   break;
188     case osgGA::GUIEventAdapter::KEY_Page_Down: key = PU_KEY_PAGE_DOWN; break;
189     case osgGA::GUIEventAdapter::KEY_Home:     key = PU_KEY_HOME;      break;
190     case osgGA::GUIEventAdapter::KEY_End:      key = PU_KEY_END;       break;
191     case osgGA::GUIEventAdapter::KEY_Insert:   key = PU_KEY_INSERT;    break;
192     case osgGA::GUIEventAdapter::KEY_F1:       key = PU_KEY_F1;        break;
193     case osgGA::GUIEventAdapter::KEY_F2:       key = PU_KEY_F2;        break;
194     case osgGA::GUIEventAdapter::KEY_F3:       key = PU_KEY_F3;        break;
195     case osgGA::GUIEventAdapter::KEY_F4:       key = PU_KEY_F4;        break;
196     case osgGA::GUIEventAdapter::KEY_F5:       key = PU_KEY_F5;        break;
197     case osgGA::GUIEventAdapter::KEY_F6:       key = PU_KEY_F6;        break;
198     case osgGA::GUIEventAdapter::KEY_F7:       key = PU_KEY_F7;        break;
199     case osgGA::GUIEventAdapter::KEY_F8:       key = PU_KEY_F8;        break;
200     case osgGA::GUIEventAdapter::KEY_F9:       key = PU_KEY_F9;        break;
201     case osgGA::GUIEventAdapter::KEY_F10:      key = PU_KEY_F10;       break;
202     case osgGA::GUIEventAdapter::KEY_F11:      key = PU_KEY_F11;       break;
203     case osgGA::GUIEventAdapter::KEY_F12:      key = PU_KEY_F12;       break;
204     case osgGA::GUIEventAdapter::KEY_KP_0: key = 364; break;
205     case osgGA::GUIEventAdapter::KEY_KP_1: key = 363; break;
206     case osgGA::GUIEventAdapter::KEY_KP_2: key = 359; break;
207     case osgGA::GUIEventAdapter::KEY_KP_3: key = 361; break;
208     case osgGA::GUIEventAdapter::KEY_KP_4: key = 356; break;
209     case osgGA::GUIEventAdapter::KEY_KP_5: key = 309; break;
210     case osgGA::GUIEventAdapter::KEY_KP_6: key = 358; break;
211     case osgGA::GUIEventAdapter::KEY_KP_7: key = 362; break;
212     case osgGA::GUIEventAdapter::KEY_KP_8: key = 357; break;
213     case osgGA::GUIEventAdapter::KEY_KP_9: key = 360; break;
214     case osgGA::GUIEventAdapter::KEY_KP_Enter: key = 269; break;
215     }
216     osgGA::GUIEventAdapter::EventType eventType = ea.getEventType();
217     // Track the modifiers because OSG is currently (2.0) broken
218     KeyMaskMap::iterator iter = keyMaskMap.find(key);
219     if (iter != keyMaskMap.end()) {
220         int mask = iter->second;
221         if (eventType == osgGA::GUIEventAdapter::KEYUP)
222             osgModifiers &= ~mask;
223         else
224             osgModifiers |= mask;
225     }
226     modifiers = osgToFGModifiers(osgModifiers);
227     currentModifiers = modifiers;
228     if (eventType == osgGA::GUIEventAdapter::KEYUP)
229         modifiers |= KEYMOD_RELEASED;
230 }
231