mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-27 17:28:41 +00:00
Implement an editor to customize the touchscreen controls (#14933)
- The editor is accessible via the pause menu and the settings menu. - Buttons can be moved via drag & drop. - Buttons can be added/removed. The grid menu added by #14918 is used to show all buttons not included in the layout. - Custom layouts are responsive and adapt to changed screen size / DPI / hud_scaling. - The layout is saved as JSON in the "touch_layout" setting.
This commit is contained in:
parent
4faa16fe0d
commit
6a1d22b2c5
18 changed files with 1122 additions and 195 deletions
|
@ -5,11 +5,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "IGUIStaticText.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include <IEventReceiver.h>
|
||||
#include <IGUIImage.h>
|
||||
#include <IGUIEnvironment.h>
|
||||
#include "IEventReceiver.h"
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
@ -17,41 +14,29 @@
|
|||
#include <vector>
|
||||
|
||||
#include "itemdef.h"
|
||||
#include "client/game.h"
|
||||
#include "touchscreenlayout.h"
|
||||
#include "util/basic_macros.h"
|
||||
#include "client/texturesource.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
class IrrlichtDevice;
|
||||
namespace gui
|
||||
{
|
||||
class IGUIEnvironment;
|
||||
class IGUIImage;
|
||||
class IGUIStaticText;
|
||||
}
|
||||
namespace video
|
||||
{
|
||||
class IVideoDriver;
|
||||
}
|
||||
}
|
||||
class ISimpleTextureSource;
|
||||
|
||||
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,
|
||||
|
@ -59,36 +44,6 @@ enum class TapState
|
|||
LongTap,
|
||||
};
|
||||
|
||||
enum touch_gui_button_id
|
||||
{
|
||||
jump_id = 0,
|
||||
sneak_id,
|
||||
zoom_id,
|
||||
aux1_id,
|
||||
overflow_id,
|
||||
|
||||
// usually in the "settings bar"
|
||||
fly_id,
|
||||
noclip_id,
|
||||
fast_id,
|
||||
debug_id,
|
||||
camera_id,
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
#define BUTTON_REPEAT_DELAY 0.5f
|
||||
#define BUTTON_REPEAT_INTERVAL 0.333f
|
||||
|
@ -168,6 +123,9 @@ public:
|
|||
bool isStatusTextOverriden() { return m_overflow_open; }
|
||||
IGUIStaticText *getStatusText() { return m_status_text.get(); }
|
||||
|
||||
ButtonLayout getLayout() { return m_layout; }
|
||||
void applyLayout(const ButtonLayout &layout);
|
||||
|
||||
private:
|
||||
IrrlichtDevice *m_device = nullptr;
|
||||
IGUIEnvironment *m_guienv = nullptr;
|
||||
|
@ -233,13 +191,14 @@ private:
|
|||
void releaseAll();
|
||||
|
||||
// initialize a button
|
||||
bool mayAddButton(touch_gui_button_id id);
|
||||
void addButton(std::vector<button_info> &buttons,
|
||||
touch_gui_button_id id, const std::string &image,
|
||||
const recti &rect, bool visible=true);
|
||||
const recti &rect, bool visible);
|
||||
void addToggleButton(std::vector<button_info> &buttons,
|
||||
touch_gui_button_id id,
|
||||
const std::string &image_1, const std::string &image_2,
|
||||
const recti &rect, bool visible=true);
|
||||
const recti &rect, bool visible);
|
||||
|
||||
IGUIImage *makeButtonDirect(touch_gui_button_id id,
|
||||
const recti &rect, bool visible);
|
||||
|
@ -268,6 +227,8 @@ private:
|
|||
|
||||
bool m_place_pressed = false;
|
||||
u64 m_place_pressed_until = 0;
|
||||
|
||||
ButtonLayout m_layout;
|
||||
};
|
||||
|
||||
extern TouchControls *g_touchcontrols;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue