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