]> git.lizzy.rs Git - minetest.git/blob - src/gui/touchscreengui.h
21c52f756e4e4dc656438481679371f0af5ea1cf
[minetest.git] / src / gui / touchscreengui.h
1 /*
2 Copyright (C) 2014 sapier
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20
21 #include <IEventReceiver.h>
22 #include <IGUIButton.h>
23 #include <IGUIEnvironment.h>
24 #include <IrrlichtDevice.h>
25
26 #include <map>
27 #include <vector>
28
29 #include "client/tile.h"
30 #include "game.h"
31
32 using namespace irr;
33 using namespace irr::core;
34 using namespace irr::gui;
35
36 typedef enum {
37         jump_id = 0,
38         crunch_id,
39         after_last_element_id,
40         settings_starter_id,
41         rare_controls_starter_id,
42         fly_id,
43         noclip_id,
44         fast_id,
45         debug_id,
46         camera_id,
47         range_id,
48         chat_id,
49         inventory_id,
50         drop_id,
51         forward_id,
52         backward_id,
53         left_id,
54         right_id,
55         joystick_off_id,
56         joystick_bg_id,
57         joystick_center_id
58 } touch_gui_button_id;
59
60 typedef enum { j_forward = 0, j_backward, j_left, j_right } touch_gui_joystick_move_id;
61
62 typedef enum {
63         AHBB_Dir_Top_Bottom,
64         AHBB_Dir_Bottom_Top,
65         AHBB_Dir_Left_Right,
66         AHBB_Dir_Right_Left
67 } autohide_button_bar_dir;
68
69 #define MIN_DIG_TIME_MS 500
70 #define MAX_TOUCH_COUNT 64
71 #define BUTTON_REPEAT_DELAY 0.2f
72
73 #define SETTINGS_BAR_Y_OFFSET 6.5
74 #define RARE_CONTROLS_BAR_Y_OFFSET 4
75
76 extern const char **touchgui_button_imagenames;
77 extern const char **touchgui_joystick_imagenames;
78
79 struct button_info
80 {
81         float repeatcounter;
82         float repeatdelay;
83         irr::EKEY_CODE keycode;
84         std::vector<int> ids;
85         IGUIButton *guibutton = nullptr;
86         bool immediate_release;
87 };
88
89 class AutoHideButtonBar
90 {
91 public:
92         AutoHideButtonBar(IrrlichtDevice *device, IEventReceiver *receiver);
93
94         void init(ISimpleTextureSource *tsrc, const char *starter_img, int button_id,
95                         v2s32 UpperLeft, v2s32 LowerRight, autohide_button_bar_dir dir,
96                         float timeout);
97
98         ~AutoHideButtonBar();
99
100         // add button to be shown
101         void addButton(touch_gui_button_id id, const wchar_t *caption,
102                         const char *btn_image);
103
104         // detect settings bar button events
105         bool isButton(const SEvent &event);
106
107         // handle released hud buttons
108         bool isReleaseButton(int eventID);
109
110         // step handler
111         void step(float dtime);
112
113         // deactivate button bar
114         void deactivate();
115
116         // hide the whole buttonbar
117         void hide();
118
119         // unhide the buttonbar
120         void show();
121
122 private:
123         ISimpleTextureSource *m_texturesource = nullptr;
124         irr::video::IVideoDriver *m_driver;
125         IGUIEnvironment *m_guienv;
126         IEventReceiver *m_receiver;
127         button_info m_starter;
128         std::vector<button_info *> m_buttons;
129
130         v2s32 m_upper_left;
131         v2s32 m_lower_right;
132
133         // show settings bar
134         bool m_active = false;
135
136         bool m_visible = true;
137
138         // settings bar timeout
139         float m_timeout = 0.0f;
140         float m_timeout_value = 3.0f;
141         bool m_initialized = false;
142         autohide_button_bar_dir m_dir = AHBB_Dir_Right_Left;
143 };
144
145 class TouchScreenGUI
146 {
147 public:
148         TouchScreenGUI(IrrlichtDevice *device, IEventReceiver *receiver);
149         ~TouchScreenGUI();
150
151         void translateEvent(const SEvent &event);
152
153         void init(ISimpleTextureSource *tsrc);
154
155         double getYawChange()
156         {
157                 double res = m_camera_yaw_change;
158                 m_camera_yaw_change = 0;
159                 return res;
160         }
161
162         double getPitch() { return m_camera_pitch; }
163
164         /*!
165          * Returns a line which describes what the player is pointing at.
166          * The starting point and looking direction are significant,
167          * the line should be scaled to match its length to the actual distance
168          * the player can reach.
169          * The line starts at the camera and ends on the camera's far plane.
170          * The coordinates do not contain the camera offset.
171          */
172         line3d<f32> getShootline() { return m_shootline; }
173
174         void step(float dtime);
175         void resetHud();
176         void registerHudItem(int index, const rect<s32> &rect);
177         void Toggle(bool visible);
178
179         void hide();
180         void show();
181
182 private:
183         IrrlichtDevice *m_device;
184         IGUIEnvironment *m_guienv;
185         IEventReceiver *m_receiver;
186         ISimpleTextureSource *m_texturesource;
187         v2u32 m_screensize;
188         double m_touchscreen_threshold;
189         std::map<int, rect<s32>> m_hud_rects;
190         std::map<int, irr::EKEY_CODE> m_hud_ids;
191         bool m_visible; // is the gui visible
192
193         // value in degree
194         double m_camera_yaw_change = 0.0;
195         double m_camera_pitch = 0.0;
196
197         // forward, backward, left, right
198         touch_gui_button_id m_joystick_names[4] = {
199                         forward_id, backward_id, left_id, right_id};
200         bool m_joystick_status[4] = {false, false, false, false};
201
202         /*!
203          * A line starting at the camera and pointing towards the
204          * selected object.
205          * The line ends on the camera's far plane.
206          * The coordinates do not contain the camera offset.
207          */
208         line3d<f32> m_shootline;
209
210         int m_move_id = -1;
211         bool m_move_has_really_moved = false;
212         s64 m_move_downtime = 0;
213         bool m_move_sent_as_mouse_event = false;
214         v2s32 m_move_downlocation = v2s32(-10000, -10000);
215
216         int m_joystick_id = -1;
217         bool m_joystick_has_really_moved = false;
218         bool m_fixed_joystick = false;
219         button_info *m_joystick_btn_off = nullptr;
220         button_info *m_joystick_btn_bg = nullptr;
221         button_info *m_joystick_btn_center = nullptr;
222
223         button_info m_buttons[after_last_element_id];
224
225         // gui button detection
226         touch_gui_button_id getButtonID(s32 x, s32 y);
227
228         // gui button by eventID
229         touch_gui_button_id getButtonID(int eventID);
230
231         // check if a button has changed
232         void handleChangedButton(const SEvent &event);
233
234         // initialize a button
235         void initButton(touch_gui_button_id id, rect<s32> button_rect,
236                         std::wstring caption, bool immediate_release,
237                         float repeat_delay = BUTTON_REPEAT_DELAY);
238
239         // initialize a joystick button
240         button_info *initJoystickButton(touch_gui_button_id id, rect<s32> button_rect,
241                         int texture_id, bool visible = true);
242
243         struct id_status
244         {
245                 int id;
246                 int X;
247                 int Y;
248         };
249
250         // vector to store known ids and their initial touch positions
251         std::vector<id_status> m_known_ids;
252
253         // handle a button event
254         void handleButtonEvent(touch_gui_button_id bID, int eventID, bool action);
255
256         // handle pressed hud buttons
257         bool isHUDButton(const SEvent &event);
258
259         // handle released hud buttons
260         bool isReleaseHUDButton(int eventID);
261
262         // handle double taps
263         bool doubleTapDetection();
264
265         // handle release event
266         void handleReleaseEvent(int evt_id);
267
268         // apply joystick status
269         void applyJoystickStatus();
270
271         // get size of regular gui control button
272         int getGuiButtonSize();
273
274         // doubleclick detection variables
275         struct key_event
276         {
277                 unsigned int down_time;
278                 s32 x;
279                 s32 y;
280         };
281
282         // array for saving last known position of a pointer
283         v2s32 m_pointerpos[MAX_TOUCH_COUNT];
284
285         // array for doubletap detection
286         key_event m_key_events[2];
287
288         // settings bar
289         AutoHideButtonBar m_settingsbar;
290
291         // rare controls bar
292         AutoHideButtonBar m_rarecontrolsbar;
293 };
294 extern TouchScreenGUI *g_touchscreengui;