]> git.lizzy.rs Git - minetest.git/blob - src/client/inputhandler.h
Fix GUITable selection issues with trees
[minetest.git] / src / client / inputhandler.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef INPUT_HANDLER_H
21 #define INPUT_HANDLER_H
22
23 #include "irrlichttypes_extrabloated.h"
24
25 class MyEventReceiver : public IEventReceiver
26 {
27 public:
28         // This is the one method that we have to implement
29         virtual bool OnEvent(const SEvent& event)
30         {
31                 /*
32                         React to nothing here if a menu is active
33                 */
34                 if (noMenuActive() == false) {
35 #ifdef HAVE_TOUCHSCREENGUI
36                         if (m_touchscreengui != 0) {
37                                 m_touchscreengui->Toggle(false);
38                         }
39 #endif
40                         return g_menumgr.preprocessEvent(event);
41                 }
42
43                 // Remember whether each key is down or up
44                 if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
45                         if (event.KeyInput.PressedDown) {
46                                 keyIsDown.set(event.KeyInput);
47                                 keyWasDown.set(event.KeyInput);
48                         } else {
49                                 keyIsDown.unset(event.KeyInput);
50                         }
51                 }
52
53 #ifdef HAVE_TOUCHSCREENGUI
54                 // case of touchscreengui we have to handle different events
55                 if ((m_touchscreengui != 0) &&
56                                 (event.EventType == irr::EET_TOUCH_INPUT_EVENT)) {
57                         m_touchscreengui->translateEvent(event);
58                         return true;
59                 }
60 #endif
61                 // handle mouse events
62                 if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
63                         if (noMenuActive() == false) {
64                                 left_active = false;
65                                 middle_active = false;
66                                 right_active = false;
67                         } else {
68                                 left_active = event.MouseInput.isLeftPressed();
69                                 middle_active = event.MouseInput.isMiddlePressed();
70                                 right_active = event.MouseInput.isRightPressed();
71
72                                 if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
73                                         leftclicked = true;
74                                 }
75                                 if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) {
76                                         rightclicked = true;
77                                 }
78                                 if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
79                                         leftreleased = true;
80                                 }
81                                 if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) {
82                                         rightreleased = true;
83                                 }
84                                 if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
85                                         mouse_wheel += event.MouseInput.Wheel;
86                                 }
87                         }
88                 } else if (event.EventType == irr::EET_LOG_TEXT_EVENT) {
89                         static const LogLevel irr_loglev_conv[] = {
90                                 LL_VERBOSE, // ELL_DEBUG
91                                 LL_INFO,    // ELL_INFORMATION
92                                 LL_WARNING, // ELL_WARNING
93                                 LL_ERROR,   // ELL_ERROR
94                                 LL_NONE,    // ELL_NONE
95                         };
96                         assert(event.LogEvent.Level < ARRLEN(irr_loglev_conv));
97                         g_logger.log(irr_loglev_conv[event.LogEvent.Level],
98                                 std::string("Irrlicht: ") + (const char*) event.LogEvent.Text);
99                         return true;
100                 }
101                 /* always return false in order to continue processing events */
102                 return false;
103         }
104
105         bool IsKeyDown(const KeyPress &keyCode) const
106         {
107                 return keyIsDown[keyCode];
108         }
109
110         // Checks whether a key was down and resets the state
111         bool WasKeyDown(const KeyPress &keyCode)
112         {
113                 bool b = keyWasDown[keyCode];
114                 if (b)
115                         keyWasDown.unset(keyCode);
116                 return b;
117         }
118
119         s32 getMouseWheel()
120         {
121                 s32 a = mouse_wheel;
122                 mouse_wheel = 0;
123                 return a;
124         }
125
126         void clearInput()
127         {
128                 keyIsDown.clear();
129                 keyWasDown.clear();
130
131                 leftclicked = false;
132                 rightclicked = false;
133                 leftreleased = false;
134                 rightreleased = false;
135
136                 left_active = false;
137                 middle_active = false;
138                 right_active = false;
139
140                 mouse_wheel = 0;
141         }
142
143         MyEventReceiver()
144         {
145                 clearInput();
146 #ifdef HAVE_TOUCHSCREENGUI
147                 m_touchscreengui = NULL;
148 #endif
149         }
150
151         bool leftclicked;
152         bool rightclicked;
153         bool leftreleased;
154         bool rightreleased;
155
156         bool left_active;
157         bool middle_active;
158         bool right_active;
159
160         s32 mouse_wheel;
161
162 #ifdef HAVE_TOUCHSCREENGUI
163         TouchScreenGUI* m_touchscreengui;
164 #endif
165
166 private:
167         // The current state of keys
168         KeyList keyIsDown;
169         // Whether a key has been pressed or not
170         KeyList keyWasDown;
171 };
172
173
174 /*
175         Separated input handler
176 */
177
178 class RealInputHandler : public InputHandler
179 {
180 public:
181         RealInputHandler(IrrlichtDevice *device, MyEventReceiver *receiver):
182                 m_device(device),
183                 m_receiver(receiver),
184                 m_mousepos(0,0)
185         {
186         }
187         virtual bool isKeyDown(const KeyPress &keyCode)
188         {
189                 return m_receiver->IsKeyDown(keyCode);
190         }
191         virtual bool wasKeyDown(const KeyPress &keyCode)
192         {
193                 return m_receiver->WasKeyDown(keyCode);
194         }
195         virtual v2s32 getMousePos()
196         {
197                 if (m_device->getCursorControl()) {
198                         return m_device->getCursorControl()->getPosition();
199                 }
200                 else {
201                         return m_mousepos;
202                 }
203         }
204         virtual void setMousePos(s32 x, s32 y)
205         {
206                 if (m_device->getCursorControl()) {
207                         m_device->getCursorControl()->setPosition(x, y);
208                 }
209                 else {
210                         m_mousepos = v2s32(x,y);
211                 }
212         }
213
214         virtual bool getLeftState()
215         {
216                 return m_receiver->left_active;
217         }
218         virtual bool getRightState()
219         {
220                 return m_receiver->right_active;
221         }
222
223         virtual bool getLeftClicked()
224         {
225                 return m_receiver->leftclicked;
226         }
227         virtual bool getRightClicked()
228         {
229                 return m_receiver->rightclicked;
230         }
231         virtual void resetLeftClicked()
232         {
233                 m_receiver->leftclicked = false;
234         }
235         virtual void resetRightClicked()
236         {
237                 m_receiver->rightclicked = false;
238         }
239
240         virtual bool getLeftReleased()
241         {
242                 return m_receiver->leftreleased;
243         }
244         virtual bool getRightReleased()
245         {
246                 return m_receiver->rightreleased;
247         }
248         virtual void resetLeftReleased()
249         {
250                 m_receiver->leftreleased = false;
251         }
252         virtual void resetRightReleased()
253         {
254                 m_receiver->rightreleased = false;
255         }
256
257         virtual s32 getMouseWheel()
258         {
259                 return m_receiver->getMouseWheel();
260         }
261
262         void clear()
263         {
264                 m_receiver->clearInput();
265         }
266 private:
267         IrrlichtDevice  *m_device;
268         MyEventReceiver *m_receiver;
269         v2s32           m_mousepos;
270 };
271
272 class RandomInputHandler : public InputHandler
273 {
274 public:
275         RandomInputHandler()
276         {
277                 leftdown = false;
278                 rightdown = false;
279                 leftclicked = false;
280                 rightclicked = false;
281                 leftreleased = false;
282                 rightreleased = false;
283                 keydown.clear();
284         }
285         virtual bool isKeyDown(const KeyPress &keyCode)
286         {
287                 return keydown[keyCode];
288         }
289         virtual bool wasKeyDown(const KeyPress &keyCode)
290         {
291                 return false;
292         }
293         virtual v2s32 getMousePos()
294         {
295                 return mousepos;
296         }
297         virtual void setMousePos(s32 x, s32 y)
298         {
299                 mousepos = v2s32(x, y);
300         }
301
302         virtual bool getLeftState()
303         {
304                 return leftdown;
305         }
306         virtual bool getRightState()
307         {
308                 return rightdown;
309         }
310
311         virtual bool getLeftClicked()
312         {
313                 return leftclicked;
314         }
315         virtual bool getRightClicked()
316         {
317                 return rightclicked;
318         }
319         virtual void resetLeftClicked()
320         {
321                 leftclicked = false;
322         }
323         virtual void resetRightClicked()
324         {
325                 rightclicked = false;
326         }
327
328         virtual bool getLeftReleased()
329         {
330                 return leftreleased;
331         }
332         virtual bool getRightReleased()
333         {
334                 return rightreleased;
335         }
336         virtual void resetLeftReleased()
337         {
338                 leftreleased = false;
339         }
340         virtual void resetRightReleased()
341         {
342                 rightreleased = false;
343         }
344
345         virtual s32 getMouseWheel()
346         {
347                 return 0;
348         }
349
350         virtual void step(float dtime)
351         {
352                 {
353                         static float counter1 = 0;
354                         counter1 -= dtime;
355                         if (counter1 < 0.0) {
356                                 counter1 = 0.1 * Rand(1, 40);
357                                 keydown.toggle(getKeySetting("keymap_jump"));
358                         }
359                 }
360                 {
361                         static float counter1 = 0;
362                         counter1 -= dtime;
363                         if (counter1 < 0.0) {
364                                 counter1 = 0.1 * Rand(1, 40);
365                                 keydown.toggle(getKeySetting("keymap_special1"));
366                         }
367                 }
368                 {
369                         static float counter1 = 0;
370                         counter1 -= dtime;
371                         if (counter1 < 0.0) {
372                                 counter1 = 0.1 * Rand(1, 40);
373                                 keydown.toggle(getKeySetting("keymap_forward"));
374                         }
375                 }
376                 {
377                         static float counter1 = 0;
378                         counter1 -= dtime;
379                         if (counter1 < 0.0) {
380                                 counter1 = 0.1 * Rand(1, 40);
381                                 keydown.toggle(getKeySetting("keymap_left"));
382                         }
383                 }
384                 {
385                         static float counter1 = 0;
386                         counter1 -= dtime;
387                         if (counter1 < 0.0) {
388                                 counter1 = 0.1 * Rand(1, 20);
389                                 mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20));
390                         }
391                 }
392                 {
393                         static float counter1 = 0;
394                         counter1 -= dtime;
395                         if (counter1 < 0.0) {
396                                 counter1 = 0.1 * Rand(1, 30);
397                                 leftdown = !leftdown;
398                                 if (leftdown)
399                                         leftclicked = true;
400                                 if (!leftdown)
401                                         leftreleased = true;
402                         }
403                 }
404                 {
405                         static float counter1 = 0;
406                         counter1 -= dtime;
407                         if (counter1 < 0.0) {
408                                 counter1 = 0.1 * Rand(1, 15);
409                                 rightdown = !rightdown;
410                                 if (rightdown)
411                                         rightclicked = true;
412                                 if (!rightdown)
413                                         rightreleased = true;
414                         }
415                 }
416                 mousepos += mousespeed;
417         }
418
419         s32 Rand(s32 min, s32 max)
420         {
421                 return (myrand()%(max-min+1))+min;
422         }
423 private:
424         KeyList keydown;
425         v2s32 mousepos;
426         v2s32 mousespeed;
427         bool leftdown;
428         bool rightdown;
429         bool leftclicked;
430         bool rightclicked;
431         bool leftreleased;
432         bool rightreleased;
433 };
434
435 #endif