mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
TouchScreenGUI dehardcoding refactor (#14472)
This commit is contained in:
parent
b2057a5da7
commit
f2b5c35fa2
@ -206,10 +206,6 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
if (!m_rendering_engine->run() || *kill)
|
||||
break;
|
||||
|
||||
if (g_settings->getBool("enable_touch")) {
|
||||
g_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver);
|
||||
}
|
||||
|
||||
the_game(
|
||||
kill,
|
||||
input,
|
||||
|
@ -1555,8 +1555,8 @@ bool Game::initGui()
|
||||
gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(),
|
||||
-1, chat_backend, client, &g_menumgr);
|
||||
|
||||
if (g_touchscreengui)
|
||||
g_touchscreengui->init(texture_src);
|
||||
if (g_settings->getBool("enable_touch"))
|
||||
g_touchscreengui = new TouchScreenGUI(device, texture_src);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include <IEventReceiver.h>
|
||||
#include <IGUIButton.h>
|
||||
#include <IGUIImage.h>
|
||||
#include <IGUIEnvironment.h>
|
||||
#include <IrrlichtDevice.h>
|
||||
|
||||
@ -38,6 +38,29 @@ using namespace irr;
|
||||
using namespace irr::core;
|
||||
using namespace irr::gui;
|
||||
|
||||
|
||||
// We cannot use irr_ptr for Irrlicht GUI elements we own.
|
||||
// Option 1: Pass IGUIElement* returned by IGUIEnvironment::add* into irr_ptr
|
||||
// constructor.
|
||||
// -> We steal the reference owned by IGUIEnvironment and drop it later,
|
||||
// causing the IGUIElement to be deleted while IGUIEnvironment still
|
||||
// references it.
|
||||
// Option 2: Pass IGUIElement* returned by IGUIEnvironment::add* into irr_ptr::grab.
|
||||
// -> We add another reference and drop it later, but since IGUIEnvironment
|
||||
// still references the IGUIElement, it is never deleted.
|
||||
// To make IGUIEnvironment drop its reference to the IGUIElement, we have to call
|
||||
// IGUIElement::remove, so that's what we'll do.
|
||||
template <typename T>
|
||||
std::shared_ptr<T> grab_gui_element(T *element)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IGUIElement, T>,
|
||||
"grab_gui_element only works for IGUIElement");
|
||||
return std::shared_ptr<T>(element, [](T *e) {
|
||||
e->remove();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
enum class TapState
|
||||
{
|
||||
None,
|
||||
@ -45,15 +68,16 @@ enum class TapState
|
||||
LongTap,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
enum touch_gui_button_id
|
||||
{
|
||||
jump_id = 0,
|
||||
crunch_id,
|
||||
sneak_id,
|
||||
zoom_id,
|
||||
aux1_id,
|
||||
after_last_element_id,
|
||||
settings_starter_id,
|
||||
rare_controls_starter_id,
|
||||
|
||||
// usually in the "settings bar"
|
||||
fly_id,
|
||||
noclip_id,
|
||||
fast_id,
|
||||
@ -62,24 +86,30 @@ typedef enum
|
||||
range_id,
|
||||
minimap_id,
|
||||
toggle_chat_id,
|
||||
|
||||
// usually in the "rare controls bar"
|
||||
chat_id,
|
||||
inventory_id,
|
||||
drop_id,
|
||||
exit_id,
|
||||
|
||||
// the joystick
|
||||
joystick_off_id,
|
||||
joystick_bg_id,
|
||||
joystick_center_id
|
||||
} touch_gui_button_id;
|
||||
joystick_center_id,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
enum autohide_button_bar_dir
|
||||
{
|
||||
AHBB_Dir_Top_Bottom,
|
||||
AHBB_Dir_Bottom_Top,
|
||||
AHBB_Dir_Left_Right,
|
||||
AHBB_Dir_Right_Left
|
||||
} autohide_button_bar_dir;
|
||||
};
|
||||
|
||||
#define BUTTON_REPEAT_DELAY 0.2f
|
||||
#define BUTTON_REPEAT_DELAY 0.5f
|
||||
#define BUTTON_REPEAT_INTERVAL 0.333f
|
||||
#define BUTTONBAR_HIDE_DELAY 3.0f
|
||||
#define SETTINGS_BAR_Y_OFFSET 5
|
||||
#define RARE_CONTROLS_BAR_Y_OFFSET 5
|
||||
|
||||
@ -88,96 +118,79 @@ typedef enum
|
||||
// If you tap faster than this value, the simulated clicks are of course shorter.
|
||||
#define SIMULATED_CLICK_DURATION_MS 50
|
||||
|
||||
extern const std::string button_image_names[];
|
||||
extern const std::string joystick_image_names[];
|
||||
|
||||
struct button_info
|
||||
{
|
||||
float repeat_counter;
|
||||
float repeat_delay;
|
||||
EKEY_CODE keycode;
|
||||
std::vector<size_t> ids;
|
||||
IGUIButton *gui_button = nullptr;
|
||||
bool immediate_release;
|
||||
std::vector<size_t> pointer_ids;
|
||||
std::shared_ptr<IGUIImage> gui_button = nullptr;
|
||||
|
||||
enum {
|
||||
NOT_TOGGLEABLE,
|
||||
FIRST_TEXTURE,
|
||||
SECOND_TEXTURE
|
||||
} toggleable = NOT_TOGGLEABLE;
|
||||
std::vector<std::string> textures;
|
||||
std::string toggle_textures[2];
|
||||
|
||||
void emitAction(bool action, video::IVideoDriver *driver,
|
||||
IEventReceiver *receiver, ISimpleTextureSource *tsrc);
|
||||
};
|
||||
|
||||
class AutoHideButtonBar
|
||||
{
|
||||
public:
|
||||
AutoHideButtonBar(IrrlichtDevice *device, IEventReceiver *receiver);
|
||||
AutoHideButtonBar(IrrlichtDevice *device, ISimpleTextureSource *tsrc,
|
||||
touch_gui_button_id starter_id, const std::string &starter_image,
|
||||
recti starter_rect, autohide_button_bar_dir dir);
|
||||
|
||||
void init(ISimpleTextureSource *tsrc, const std::string &starter_img, int button_id,
|
||||
const v2s32 &UpperLeft, const v2s32 &LowerRight,
|
||||
autohide_button_bar_dir dir, float timeout);
|
||||
void addButton(touch_gui_button_id id, const std::string &image);
|
||||
void addToggleButton(touch_gui_button_id id,
|
||||
const std::string &image_1, const std::string &image_2);
|
||||
|
||||
~AutoHideButtonBar();
|
||||
bool handlePress(size_t pointer_id, IGUIElement *element);
|
||||
bool handleRelease(size_t pointer_id);
|
||||
|
||||
// add button to be shown
|
||||
void addButton(touch_gui_button_id id, const wchar_t *caption,
|
||||
const std::string &btn_image);
|
||||
|
||||
// add toggle button to be shown
|
||||
void addToggleButton(touch_gui_button_id id, const wchar_t *caption,
|
||||
const std::string &btn_image_1, const std::string &btn_image_2);
|
||||
|
||||
// detect button bar button events
|
||||
bool isButton(const SEvent &event);
|
||||
|
||||
// step handler
|
||||
void step(float dtime);
|
||||
|
||||
// return whether the button bar is active
|
||||
bool active() { return m_active; }
|
||||
|
||||
// deactivate the button bar
|
||||
void activate();
|
||||
void deactivate();
|
||||
bool isActive() { return m_active; }
|
||||
|
||||
// hide the whole button bar
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
// unhide the button bar
|
||||
void show();
|
||||
bool operator==(const AutoHideButtonBar &other)
|
||||
{ return m_starter.get() == other.m_starter.get(); }
|
||||
bool operator!=(const AutoHideButtonBar &other)
|
||||
{ return m_starter.get() != other.m_starter.get(); }
|
||||
|
||||
private:
|
||||
irr::video::IVideoDriver *m_driver = nullptr;
|
||||
IGUIEnvironment *m_guienv = nullptr;
|
||||
IEventReceiver *m_receiver = nullptr;
|
||||
ISimpleTextureSource *m_texturesource = nullptr;
|
||||
irr::video::IVideoDriver *m_driver;
|
||||
IGUIEnvironment *m_guienv;
|
||||
IEventReceiver *m_receiver;
|
||||
button_info m_starter;
|
||||
std::vector<std::shared_ptr<button_info>> m_buttons;
|
||||
std::shared_ptr<IGUIImage> m_starter;
|
||||
std::vector<button_info> m_buttons;
|
||||
|
||||
v2s32 m_upper_left;
|
||||
v2s32 m_lower_right;
|
||||
|
||||
// show button bar
|
||||
bool m_active = false;
|
||||
bool m_visible = true;
|
||||
|
||||
// button bar timeout
|
||||
float m_timeout = 0.0f;
|
||||
float m_timeout_value = 3.0f;
|
||||
bool m_initialized = false;
|
||||
autohide_button_bar_dir m_dir = AHBB_Dir_Right_Left;
|
||||
|
||||
void updateVisibility();
|
||||
};
|
||||
|
||||
class TouchScreenGUI
|
||||
{
|
||||
public:
|
||||
TouchScreenGUI(IrrlichtDevice *device, IEventReceiver *receiver);
|
||||
~TouchScreenGUI();
|
||||
TouchScreenGUI(IrrlichtDevice *device, ISimpleTextureSource *tsrc);
|
||||
|
||||
void translateEvent(const SEvent &event);
|
||||
void applyContextControls(const TouchInteractionMode &mode);
|
||||
|
||||
void init(ISimpleTextureSource *tsrc);
|
||||
|
||||
double getYawChange()
|
||||
{
|
||||
double res = m_camera_yaw_change;
|
||||
@ -212,22 +225,21 @@ public:
|
||||
void show();
|
||||
|
||||
void resetHotbarRects();
|
||||
void registerHotbarRect(u16 index, const rect<s32> &rect);
|
||||
void registerHotbarRect(u16 index, const recti &rect);
|
||||
std::optional<u16> getHotbarSelection();
|
||||
|
||||
private:
|
||||
bool m_initialized = false;
|
||||
IrrlichtDevice *m_device;
|
||||
IGUIEnvironment *m_guienv;
|
||||
IEventReceiver *m_receiver;
|
||||
ISimpleTextureSource *m_texturesource;
|
||||
IrrlichtDevice *m_device = nullptr;
|
||||
IGUIEnvironment *m_guienv = nullptr;
|
||||
IEventReceiver *m_receiver = nullptr;
|
||||
ISimpleTextureSource *m_texturesource = nullptr;
|
||||
v2u32 m_screensize;
|
||||
s32 button_size;
|
||||
s32 m_button_size;
|
||||
double m_touchscreen_threshold;
|
||||
u16 m_long_tap_delay;
|
||||
bool m_visible; // is the whole touch screen gui visible
|
||||
bool m_visible = true; // is the whole touch screen gui visible
|
||||
|
||||
std::unordered_map<u16, rect<s32>> m_hotbar_rects;
|
||||
std::unordered_map<u16, recti> m_hotbar_rects;
|
||||
std::optional<u16> m_hotbar_selection = std::nullopt;
|
||||
|
||||
// value in degree
|
||||
@ -257,39 +269,25 @@ private:
|
||||
bool m_fixed_joystick = false;
|
||||
bool m_joystick_triggers_aux1 = false;
|
||||
bool m_draw_crosshair = false;
|
||||
std::shared_ptr<button_info> m_joystick_btn_off = nullptr;
|
||||
std::shared_ptr<button_info> m_joystick_btn_bg = nullptr;
|
||||
std::shared_ptr<button_info> m_joystick_btn_center = nullptr;
|
||||
std::shared_ptr<IGUIImage> m_joystick_btn_off;
|
||||
std::shared_ptr<IGUIImage> m_joystick_btn_bg;
|
||||
std::shared_ptr<IGUIImage> m_joystick_btn_center;
|
||||
|
||||
button_info m_buttons[after_last_element_id];
|
||||
|
||||
// gui button detection
|
||||
touch_gui_button_id getButtonID(s32 x, s32 y);
|
||||
|
||||
// gui button by eventID
|
||||
touch_gui_button_id getButtonID(size_t eventID);
|
||||
|
||||
// check if a button has changed
|
||||
void handleChangedButton(const SEvent &event);
|
||||
std::vector<button_info> m_buttons;
|
||||
|
||||
// initialize a button
|
||||
void initButton(touch_gui_button_id id, const rect<s32> &button_rect,
|
||||
const std::wstring &caption, bool immediate_release,
|
||||
float repeat_delay = BUTTON_REPEAT_DELAY);
|
||||
void addButton(touch_gui_button_id id, const std::string &image,
|
||||
const recti &rect);
|
||||
|
||||
// initialize a joystick button
|
||||
std::shared_ptr<button_info> initJoystickButton(touch_gui_button_id id,
|
||||
const rect<s32> &button_rect, int texture_id,
|
||||
bool visible = true);
|
||||
|
||||
// handle a button event
|
||||
void handleButtonEvent(touch_gui_button_id bID, size_t eventID, bool action);
|
||||
IGUIImage *makeJoystickButton(touch_gui_button_id id,
|
||||
const recti &rect, bool visible);
|
||||
|
||||
// handle pressing hotbar items
|
||||
bool isHotbarButton(const SEvent &event);
|
||||
|
||||
// handle release event
|
||||
void handleReleaseEvent(size_t evt_id);
|
||||
void handleReleaseEvent(size_t pointer_id);
|
||||
|
||||
// apply joystick status
|
||||
void applyJoystickStatus();
|
||||
@ -299,11 +297,7 @@ private:
|
||||
// map to store the IDs and positions of currently pressed pointers
|
||||
std::unordered_map<size_t, v2s32> m_pointer_pos;
|
||||
|
||||
// settings bar
|
||||
AutoHideButtonBar m_settings_bar;
|
||||
|
||||
// rare controls bar
|
||||
AutoHideButtonBar m_rare_controls_bar;
|
||||
std::vector<AutoHideButtonBar> m_buttonbars;
|
||||
|
||||
v2s32 getPointerPos();
|
||||
void emitMouseEvent(EMOUSE_INPUT_EVENT type);
|
||||
|
Loading…
Reference in New Issue
Block a user