]> git.lizzy.rs Git - dragonfireclient.git/blob - src/gui/touchscreengui.h
Include irrlichttypes.h first to work around Irrlicht#433 (#10872)
[dragonfireclient.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 "irrlichttypes.h"
22 #include <IEventReceiver.h>
23 #include <IGUIButton.h>
24 #include <IGUIEnvironment.h>
25 #include <IrrlichtDevice.h>
26
27 #include <map>
28 #include <vector>
29
30 #include "client/tile.h"
31 #include "client/game.h"
32
33 using namespace irr;
34 using namespace irr::core;
35 using namespace irr::gui;
36
37 typedef enum
38 {
39         jump_id = 0,
40         crunch_id,
41         zoom_id,
42         special1_id,
43         after_last_element_id,
44         settings_starter_id,
45         rare_controls_starter_id,
46         fly_id,
47         noclip_id,
48         fast_id,
49         debug_id,
50         camera_id,
51         range_id,
52         minimap_id,
53         toggle_chat_id,
54         chat_id,
55         inventory_id,
56         drop_id,
57         forward_id,
58         backward_id,
59         left_id,
60         right_id,
61         joystick_off_id,
62         joystick_bg_id,
63         joystick_center_id
64 } touch_gui_button_id;
65
66 typedef enum
67 {
68         j_forward = 0,
69         j_backward,
70         j_left,
71         j_right,
72         j_special1
73 } touch_gui_joystick_move_id;
74
75 typedef enum
76 {
77         AHBB_Dir_Top_Bottom,
78         AHBB_Dir_Bottom_Top,
79         AHBB_Dir_Left_Right,
80         AHBB_Dir_Right_Left
81 } autohide_button_bar_dir;
82
83 #define MIN_DIG_TIME_MS 500
84 #define BUTTON_REPEAT_DELAY 0.2f
85 #define SETTINGS_BAR_Y_OFFSET 5
86 #define RARE_CONTROLS_BAR_Y_OFFSET 5
87
88 // Very slow button repeat frequency
89 #define SLOW_BUTTON_REPEAT 1.0f
90
91 extern const char **button_imagenames;
92 extern const char **joystick_imagenames;
93
94 struct button_info
95 {
96         float repeatcounter;
97         float repeatdelay;
98         irr::EKEY_CODE keycode;
99         std::vector<size_t> ids;
100         IGUIButton *guibutton = nullptr;
101         bool immediate_release;
102
103         // 0: false, 1: (true) first texture, 2: (true) second texture
104         int togglable = 0;
105         std::vector<const char *> textures;
106 };
107
108 class AutoHideButtonBar
109 {
110 public:
111         AutoHideButtonBar(IrrlichtDevice *device, IEventReceiver *receiver);
112
113         void init(ISimpleTextureSource *tsrc, const char *starter_img, int button_id,
114                         const v2s32 &UpperLeft, const v2s32 &LowerRight,
115                         autohide_button_bar_dir dir, float timeout);
116
117         ~AutoHideButtonBar();
118
119         // add button to be shown
120         void addButton(touch_gui_button_id id, const wchar_t *caption,
121                         const char *btn_image);
122
123         // add toggle button to be shown
124         void addToggleButton(touch_gui_button_id id, const wchar_t *caption,
125                         const char *btn_image_1, const char *btn_image_2);
126
127         // detect settings bar button events
128         bool isButton(const SEvent &event);
129
130         // step handler
131         void step(float dtime);
132
133         // deactivate button bar
134         void deactivate();
135
136         // hide the whole buttonbar
137         void hide();
138
139         // unhide the buttonbar
140         void show();
141
142 private:
143         ISimpleTextureSource *m_texturesource = nullptr;
144         irr::video::IVideoDriver *m_driver;
145         IGUIEnvironment *m_guienv;
146         IEventReceiver *m_receiver;
147         button_info m_starter;
148         std::vector<button_info *> m_buttons;
149
150         v2s32 m_upper_left;
151         v2s32 m_lower_right;
152
153         // show settings bar
154         bool m_active = false;
155
156         bool m_visible = true;
157
158         // settings bar timeout
159         float m_timeout = 0.0f;
160         float m_timeout_value = 3.0f;
161         bool m_initialized = false;
162         autohide_button_bar_dir m_dir = AHBB_Dir_Right_Left;
163 };
164
165 class TouchScreenGUI
166 {
167 public:
168         TouchScreenGUI(IrrlichtDevice *device, IEventReceiver *receiver);
169         ~TouchScreenGUI();
170
171         void translateEvent(const SEvent &event);
172
173         void init(ISimpleTextureSource *tsrc);
174
175         double getYawChange()
176         {
177                 double res = m_camera_yaw_change;
178                 m_camera_yaw_change = 0;
179                 return res;
180         }
181
182         double getPitch() { return m_camera_pitch; }
183
184         /*
185          * Returns a line which describes what the player is pointing at.
186          * The starting point and looking direction are significant,
187          * the line should be scaled to match its length to the actual distance
188          * the player can reach.
189          * The line starts at the camera and ends on the camera's far plane.
190          * The coordinates do not contain the camera offset.
191          */
192         line3d<f32> getShootline() { return m_shootline; }
193
194         void step(float dtime);
195         void resetHud();
196         void registerHudItem(int index, const rect<s32> &rect);
197         void Toggle(bool visible);
198
199         void hide();
200         void show();
201
202 private:
203         IrrlichtDevice *m_device;
204         IGUIEnvironment *m_guienv;
205         IEventReceiver *m_receiver;
206         ISimpleTextureSource *m_texturesource;
207         v2u32 m_screensize;
208         s32 button_size;
209         double m_touchscreen_threshold;
210         std::map<int, rect<s32>> m_hud_rects;
211         std::map<size_t, irr::EKEY_CODE> m_hud_ids;
212         bool m_visible; // is the gui visible
213
214         // value in degree
215         double m_camera_yaw_change = 0.0;
216         double m_camera_pitch = 0.0;
217
218         // forward, backward, left, right
219         touch_gui_button_id m_joystick_names[5] = {
220                         forward_id, backward_id, left_id, right_id, special1_id};
221         bool m_joystick_status[5] = {false, false, false, false, false};
222
223         /*
224          * A line starting at the camera and pointing towards the
225          * selected object.
226          * The line ends on the camera's far plane.
227          * The coordinates do not contain the camera offset.
228          */
229         line3d<f32> m_shootline;
230
231         int m_move_id = -1;
232         bool m_move_has_really_moved = false;
233         u64 m_move_downtime = 0;
234         bool m_move_sent_as_mouse_event = false;
235         v2s32 m_move_downlocation = v2s32(-10000, -10000);
236
237         int m_joystick_id = -1;
238         bool m_joystick_has_really_moved = false;
239         bool m_fixed_joystick = false;
240         bool m_joystick_triggers_special1 = false;
241         button_info *m_joystick_btn_off = nullptr;
242         button_info *m_joystick_btn_bg = nullptr;
243         button_info *m_joystick_btn_center = nullptr;
244
245         button_info m_buttons[after_last_element_id];
246
247         // gui button detection
248         touch_gui_button_id getButtonID(s32 x, s32 y);
249
250         // gui button by eventID
251         touch_gui_button_id getButtonID(size_t eventID);
252
253         // check if a button has changed
254         void handleChangedButton(const SEvent &event);
255
256         // initialize a button
257         void initButton(touch_gui_button_id id, const rect<s32> &button_rect,
258                         const std::wstring &caption, bool immediate_release,
259                         float repeat_delay = BUTTON_REPEAT_DELAY);
260
261         // initialize a joystick button
262         button_info *initJoystickButton(touch_gui_button_id id,
263                         const rect<s32> &button_rect, int texture_id,
264                         bool visible = true);
265
266         struct id_status
267         {
268                 size_t id;
269                 int X;
270                 int Y;
271         };
272
273         // vector to store known ids and their initial touch positions
274         std::vector<id_status> m_known_ids;
275
276         // handle a button event
277         void handleButtonEvent(touch_gui_button_id bID, size_t eventID, bool action);
278
279         // handle pressed hud buttons
280         bool isHUDButton(const SEvent &event);
281
282         // handle double taps
283         bool doubleTapDetection();
284
285         // handle release event
286         void handleReleaseEvent(size_t evt_id);
287
288         // apply joystick status
289         void applyJoystickStatus();
290
291         // double-click detection variables
292         struct key_event
293         {
294                 u64 down_time;
295                 s32 x;
296                 s32 y;
297         };
298
299         // array for saving last known position of a pointer
300         std::map<size_t, v2s32> m_pointerpos;
301
302         // array for double tap detection
303         key_event m_key_events[2];
304
305         // settings bar
306         AutoHideButtonBar m_settingsbar;
307
308         // rare controls bar
309         AutoHideButtonBar m_rarecontrolsbar;
310 };
311
312 extern TouchScreenGUI *g_touchscreengui;