Allow toggling touchscreen mode at runtime (#14075)

Signed-off-by: David Heidelberg <david@ixit.cz>
Co-authored-by: Gregor Parzefall <gregor.parzefall@posteo.de>
This commit is contained in:
David Heidelberg 2024-02-22 16:44:49 +01:00 committed by GitHub
parent e3cc26cb7c
commit 34286d77c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 175 additions and 220 deletions

@ -71,7 +71,6 @@ files["builtin/mainmenu"] = {
read_globals = {
"PLATFORM",
"TOUCHSCREEN_GUI",
},
}
@ -82,9 +81,3 @@ files["builtin/common/tests"] = {
"assert",
},
}
files["builtin/fstk"] = {
read_globals = {
"TOUCHSCREEN_GUI",
},
}

@ -18,7 +18,9 @@
local BASE_SPACING = 0.1
local SCROLL_BTN_WIDTH = TOUCHSCREEN_GUI and 0.8 or 0.5
local function get_scroll_btn_width()
return core.settings:get_bool("enable_touch") and 0.8 or 0.5
end
local function buttonbar_formspec(self)
if self.hidden then
@ -39,7 +41,7 @@ local function buttonbar_formspec(self)
-- The number of buttons per page is always calculated as if the scroll
-- buttons were visible.
local avail_space = self.size.x - 2*BASE_SPACING - 2*SCROLL_BTN_WIDTH
local avail_space = self.size.x - 2*BASE_SPACING - 2*get_scroll_btn_width()
local btns_per_page = math.floor((avail_space - BASE_SPACING) / (btn_size + BASE_SPACING))
self.num_pages = math.ceil(#self.buttons / btns_per_page)
@ -55,7 +57,7 @@ local function buttonbar_formspec(self)
local btn_start_x = self.pos.x + btn_spacing
if show_scroll_btns then
btn_start_x = btn_start_x + BASE_SPACING + SCROLL_BTN_WIDTH
btn_start_x = btn_start_x + BASE_SPACING + get_scroll_btn_width()
end
for i = first_btn, first_btn + btns_per_page - 1 do
@ -80,7 +82,7 @@ local function buttonbar_formspec(self)
y = self.pos.y + BASE_SPACING,
}
local btn_next_pos = {
x = self.pos.x + self.size.x - BASE_SPACING - SCROLL_BTN_WIDTH,
x = self.pos.x + self.size.x - BASE_SPACING - get_scroll_btn_width(),
y = self.pos.y + BASE_SPACING,
}
@ -88,11 +90,11 @@ local function buttonbar_formspec(self)
self.btn_prev_name, self.btn_next_name))
table.insert(formspec, string.format("button[%f,%f;%f,%f;%s;<]",
btn_prev_pos.x, btn_prev_pos.y, SCROLL_BTN_WIDTH, btn_size,
btn_prev_pos.x, btn_prev_pos.y, get_scroll_btn_width(), btn_size,
self.btn_prev_name))
table.insert(formspec, string.format("button[%f,%f;%f,%f;%s;>]",
btn_next_pos.x, btn_next_pos.y, SCROLL_BTN_WIDTH, btn_size,
btn_next_pos.x, btn_next_pos.y, get_scroll_btn_width(), btn_size,
self.btn_next_name))
end

@ -898,7 +898,7 @@ local function get_info_formspec(text)
return table.concat({
"formspec_version[6]",
"size[15.75,9.5]",
TOUCHSCREEN_GUI and "padding[0.01,0.01]" or "position[0.5,0.55]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "position[0.5,0.55]",
"label[4,4.35;", text, "]",
"container[0,", H - 0.8 - 0.375, "]",
@ -928,7 +928,7 @@ function store.get_formspec(dlgdata)
local formspec = {
"formspec_version[6]",
"size[15.75,9.5]",
TOUCHSCREEN_GUI and "padding[0.01,0.01]" or "position[0.5,0.55]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "position[0.5,0.55]",
"style[status,downloading,queued;border=false]",
@ -1175,8 +1175,8 @@ end
function store.handle_events(event)
if event == "DialogShow" then
-- On mobile, don't show the "MINETEST" header behind the dialog.
mm_game_theme.set_engine(TOUCHSCREEN_GUI)
-- On touchscreen, don't show the "MINETEST" header behind the dialog.
mm_game_theme.set_engine(core.settings:get_bool("enable_touch"))
-- If the store is already loaded, auto-install packages here.
do_auto_install()

@ -316,8 +316,8 @@ local function check_requirements(name, requires)
local special = {
android = PLATFORM == "Android",
desktop = PLATFORM ~= "Android",
touchscreen_gui = TOUCHSCREEN_GUI,
keyboard_mouse = not TOUCHSCREEN_GUI,
touchscreen_gui = core.settings:get_bool("enable_touch"),
keyboard_mouse = not core.settings:get_bool("enable_touch"),
shaders_support = shaders_support,
shaders = core.settings:get_bool("enable_shaders") and shaders_support,
opengl = video_driver == "opengl",
@ -449,13 +449,13 @@ local function get_formspec(dialogdata)
local extra_h = 1 -- not included in tabsize.height
local tabsize = {
width = TOUCHSCREEN_GUI and 16.5 or 15.5,
height = TOUCHSCREEN_GUI and (10 - extra_h) or 12,
width = core.settings:get_bool("enable_touch") and 16.5 or 15.5,
height = core.settings:get_bool("enable_touch") and (10 - extra_h) or 12,
}
local scrollbar_w = TOUCHSCREEN_GUI and 0.6 or 0.4
local scrollbar_w = core.settings:get_bool("enable_touch") and 0.6 or 0.4
local left_pane_width = TOUCHSCREEN_GUI and 4.5 or 4.25
local left_pane_width = core.settings:get_bool("enable_touch") and 4.5 or 4.25
local search_width = left_pane_width + scrollbar_w - (0.75 * 2)
local back_w = 3
@ -468,7 +468,7 @@ local function get_formspec(dialogdata)
local fs = {
"formspec_version[6]",
"size[", tostring(tabsize.width), ",", tostring(tabsize.height + extra_h), "]",
TOUCHSCREEN_GUI and "padding[0.01,0.01]" or "",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "",
"bgcolor[#0000]",
-- HACK: this is needed to allow resubmitting the same formspec
@ -641,11 +641,22 @@ local function buttonhandler(this, fields)
local value = core.is_yes(fields.show_advanced)
core.settings:set_bool("show_advanced", value)
write_settings_early()
end
-- enable_touch is a checkbox in a setting component. We handle this
-- setting differently so we can hide/show pages using the next if-statement
if fields.enable_touch ~= nil then
local value = core.is_yes(fields.enable_touch)
core.settings:set_bool("enable_touch", value)
write_settings_early()
end
if fields.show_advanced ~= nil or fields.enable_touch ~= nil then
local suggested_page_id = update_filtered_pages(dialogdata.query)
if not filtered_page_by_id[dialogdata.page_id] then
dialogdata.components = nil
if not filtered_page_by_id[dialogdata.page_id] then
dialogdata.leftscroll = 0
dialogdata.rightscroll = 0

@ -94,7 +94,7 @@ function singleplayer_refresh_gamebar()
local btnbar = buttonbar_create(
"game_button_bar",
TOUCHSCREEN_GUI and {x = 0, y = 7.25} or {x = 0, y = 7.475},
core.settings:get_bool("enable_touch") and {x = 0, y = 7.25} or {x = 0, y = 7.475},
{x = 15.5, y = 1.25},
"#000000",
game_buttonbar_button_handler)

@ -148,6 +148,11 @@ invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false
[*Touchscreen]
# Enables touchscreen mode, allowing you to play the game with a touchscreen.
#
# Requires: !android
enable_touch (Enable touchscreen) bool true
# The length in pixels it takes for touchscreen interaction to start.
#
# Requires: touchscreen_gui

@ -38,7 +38,7 @@ General options and their default values:
INSTALL_DEVTEST=FALSE - Whether the Development Test game should be installed alongside Minetest
USE_GPROF=FALSE - Enable profiling using GProf
VERSION_EXTRA= - Text to append to version (e.g. VERSION_EXTRA=foobar -> Minetest 0.4.9-foobar)
ENABLE_TOUCH=FALSE - Enable Touchscreen support (requires support by IrrlichtMt)
ENABLE_TOUCH=FALSE - Enable touchscreen support by default (requires support by IrrlichtMt)
Library specific options:

@ -109,9 +109,10 @@ if(BUILD_CLIENT AND ENABLE_SOUND)
endif()
endif()
option(ENABLE_TOUCH "Enable Touchscreen support" FALSE)
option(ENABLE_TOUCH "Enable touchscreen by default" FALSE)
if(ENABLE_TOUCH)
add_definitions(-DHAVE_TOUCHSCREENGUI)
message(STATUS "Touchscreen support enabled by default.")
add_definitions(-DENABLE_TOUCH)
endif()
if(BUILD_CLIENT)

@ -249,10 +249,10 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
m_rendering_engine->get_video_driver()->setTextureCreationFlag(
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
#ifdef HAVE_TOUCHSCREENGUI
if (g_settings->getBool("enable_touch")) {
receiver->m_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver);
g_touchscreengui = receiver->m_touchscreengui;
#endif
}
the_game(
kill,
@ -283,11 +283,11 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
m_rendering_engine->get_scene_manager()->clear();
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
delete g_touchscreengui;
g_touchscreengui = NULL;
receiver->m_touchscreengui = NULL;
#endif
}
/* Save the settings when leaving the game.
* This makes sure that setting changes made in-game are persisted even

@ -664,11 +664,7 @@ public:
}
};
#ifdef HAVE_TOUCHSCREENGUI
#define SIZE_TAG "size[11,5.5]"
#else
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
#endif
#define SIZE_TAG "size[11,5.5,true]" // Fixed size (ignored in touchscreen mode)
/****************************************************************************
****************************************************************************/
@ -1021,13 +1017,11 @@ private:
// this happens in pause menu in singleplayer
bool m_is_paused = false;
#ifdef HAVE_TOUCHSCREENGUI
bool m_cache_hold_aux1;
bool m_touch_simulate_aux1 = false;
bool m_touch_use_crosshair;
inline bool isNoCrosshairAllowed() {
inline bool isTouchCrosshairDisabled() {
return !m_touch_use_crosshair && camera->getCameraMode() == CAMERA_MODE_FIRST;
}
#endif
#ifdef __ANDROID__
bool m_android_chat_open;
#endif
@ -1075,11 +1069,6 @@ Game::Game() :
&settingChangedCallback, this);
readSettings();
#ifdef HAVE_TOUCHSCREENGUI
m_cache_hold_aux1 = false; // This is initialised properly later
#endif
}
@ -1182,9 +1171,7 @@ bool Game::startup(bool *kill,
m_first_loop_after_window_activation = true;
#ifdef HAVE_TOUCHSCREENGUI
m_touch_use_crosshair = g_settings->getBool("touch_use_crosshair");
#endif
g_client_translations->clear();
@ -1219,10 +1206,8 @@ void Game::run()
set_light_table(g_settings->getFloat("display_gamma"));
#ifdef HAVE_TOUCHSCREENGUI
m_cache_hold_aux1 = g_settings->getBool("fast_move")
m_touch_simulate_aux1 = g_settings->getBool("fast_move")
&& client->checkPrivilege("fast");
#endif
const irr::core::dimension2du initial_screen_size(
g_settings->getU16("screen_w"),
@ -1308,9 +1293,8 @@ void Game::shutdown()
// Clear text when exiting.
m_game_ui->clearText();
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->hide();
#endif
showOverlayMessage(N_("Shutting down..."), 0, 0, false);
@ -1520,11 +1504,10 @@ bool Game::createClient(const GameStartData &start_data)
if (client->modsLoaded())
client->getScript()->on_camera_ready(camera);
client->setCamera(camera);
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
g_touchscreengui->setUseCrosshair(!isNoCrosshairAllowed());
g_touchscreengui->setUseCrosshair(!isTouchCrosshairDisabled());
}
#endif
/* Clouds
*/
@ -1594,10 +1577,8 @@ bool Game::initGui()
gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(),
-1, chat_backend, client, &g_menumgr);
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->init(texture_src);
#endif
return true;
}
@ -2026,18 +2007,17 @@ void Game::processUserInput(f32 dtime)
} else {
input->clear();
}
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->hide();
#endif
} else {
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
/* on touchscreengui step may generate own input events which ain't
* what we want in case we just did clear them */
g_touchscreengui->show();
g_touchscreengui->step(dtime);
}
#endif
m_game_focused = true;
}
@ -2229,13 +2209,11 @@ void Game::processItemSelection(u16 *new_playeritem)
}
}
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
std::optional<u16> selection = g_touchscreengui->getHotbarSelection();
if (selection)
*new_playeritem = *selection;
}
#endif
// Clamp selection again in case it wasn't changed but max_item was
*new_playeritem = MYMIN(*new_playeritem, max_item);
@ -2386,9 +2364,7 @@ void Game::toggleFast()
m_game_ui->showTranslatedStatusText("Fast mode disabled");
}
#ifdef HAVE_TOUCHSCREENGUI
m_cache_hold_aux1 = fast_move && has_fast_privs;
#endif
m_touch_simulate_aux1 = fast_move && has_fast_privs;
}
@ -2633,10 +2609,8 @@ void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
Since Minetest has its own code to synthesize mouse events from touch events,
this results in duplicated input. To avoid that, we don't enable relative
mouse mode if we're in touchscreen mode. */
#ifndef HAVE_TOUCHSCREENGUI
if (cur_control)
cur_control->setRelativeMode(!isMenuActive());
#endif
cur_control->setRelativeMode(!g_touchscreengui && !isMenuActive());
if ((device->isWindowActive() && device->isWindowFocused()
&& !isMenuActive()) || input->isRandom()) {
@ -2679,12 +2653,10 @@ f32 Game::getSensitivityScaleFactor() const
void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
{
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
cam->camera_yaw += g_touchscreengui->getYawChange();
cam->camera_pitch += g_touchscreengui->getPitchChange();
} else {
#endif
v2s32 center(driver->getScreenSize().Width / 2, driver->getScreenSize().Height / 2);
v2s32 dist = input->getMousePos() - center;
@ -2698,9 +2670,7 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
if (dist.X != 0 || dist.Y != 0)
input->setMousePos(center.X, center.Y);
#ifdef HAVE_TOUCHSCREENGUI
}
#endif
if (m_cache_enable_joysticks) {
f32 sens_scale = getSensitivityScaleFactor();
@ -2745,16 +2715,14 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
control.movement_direction = atan2(dx, 1.0f);
}
#ifdef HAVE_TOUCHSCREENGUI
/* For touch, simulate holding down AUX1 (fast move) if the user has
* the fast_move setting toggled on. If there is an aux1 key defined for
* touch then its meaning is inverted (i.e. holding aux1 means walk and
* not fast)
*/
if (m_cache_hold_aux1) {
if (g_touchscreengui && m_touch_simulate_aux1) {
control.aux1 = control.aux1 ^ true;
}
#endif
client->setPlayerControl(control);
@ -3235,10 +3203,8 @@ void Game::updateCamera(f32 dtime)
camera->toggleCameraMode();
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->setUseCrosshair(!isNoCrosshairAllowed());
#endif
g_touchscreengui->setUseCrosshair(!isTouchCrosshairDisabled());
// Make the player visible depending on camera mode.
playercao->updateMeshCulling();
@ -3339,8 +3305,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
}
shootline.end = shootline.start + camera_direction * BS * d;
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui && isNoCrosshairAllowed()) {
if (g_touchscreengui && isTouchCrosshairDisabled()) {
shootline = g_touchscreengui->getShootline();
// Scale shootline to the acual distance the player can reach
shootline.end = shootline.start +
@ -3348,7 +3313,6 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
shootline.start += intToFloat(camera_offset, BS);
shootline.end += intToFloat(camera_offset, BS);
}
#endif
PointedThing pointed = updatePointedThing(shootline,
selected_def.liquids_pointable,
@ -3359,10 +3323,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
if (pointed != runData.pointed_old)
infostream << "Pointing at " << pointed.dump() << std::endl;
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->applyContextControls(selected_def.touch_interaction.getMode(pointed));
#endif
// Note that updating the selection mesh every frame is not particularly efficient,
// but the halo rendering code is already inefficient so there's no point in optimizing it here
@ -4345,10 +4307,10 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats)
bool draw_crosshair = (
(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
(this->camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
#ifdef HAVE_TOUCHSCREENGUI
if (this->isNoCrosshairAllowed())
if (g_touchscreengui && isTouchCrosshairDisabled())
draw_crosshair = false;
#endif
this->m_rendering_engine->draw_scene(sky_color, this->m_game_ui->m_flags.show_hud,
draw_wield_tool, draw_crosshair);
@ -4496,8 +4458,10 @@ void Game::showDeathFormspec()
#define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name())
void Game::showPauseMenu()
{
#ifdef HAVE_TOUCHSCREENGUI
static const std::string control_text = strgettext("Controls:\n"
std::string control_text;
if (g_touchscreengui) {
control_text = strgettext("Controls:\n"
"No menu open:\n"
"- slide finger: look around\n"
"- tap: place/punch/use (default)\n"
@ -4510,7 +4474,7 @@ void Game::showPauseMenu()
"- touch&drag, tap 2nd finger\n"
" --> place single item to slot\n"
);
#endif
}
float ypos = simple_singleplayer_mode ? 0.7f : 0.1f;
std::ostringstream os;
@ -4540,9 +4504,9 @@ void Game::showPauseMenu()
<< strgettext("Exit to Menu") << "]";
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_os;"
<< strgettext("Exit to OS") << "]";
#ifdef HAVE_TOUCHSCREENGUI
if (!control_text.empty()) {
os << "textarea[7.5,0.25;3.9,6.25;;" << control_text << ";]";
#endif
}
os << "textarea[0.4,0.25;3.9,6.25;;" << PROJECT_NAME_C " " VERSION_STRING "\n"
<< "\n"
<< strgettext("Game info:") << "\n";

@ -39,10 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "wieldmesh.h"
#include "client/renderingengine.h"
#include "client/minimap.h"
#ifdef HAVE_TOUCHSCREENGUI
#include "gui/touchscreengui.h"
#endif
#define OBJECT_CROSSHAIR_LINE_SIZE 8
#define CROSSHAIR_LINE_SIZE 10
@ -292,10 +289,8 @@ void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
drawItem(mainlist->getItem(i), item_rect, (i + 1) == selectitem);
#ifdef HAVE_TOUCHSCREENGUI
if (is_hotbar && g_touchscreengui)
g_touchscreengui->registerHotbarRect(i, item_rect);
#endif
}
}
@ -749,10 +744,8 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
void Hud::drawHotbar(u16 playeritem)
{
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->resetHotbarRects();
#endif
InventoryList *mainlist = inventory->getList("main");
if (mainlist == NULL) {

@ -102,11 +102,9 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
React to nothing here if a menu is active
*/
if (isMenuActive()) {
#ifdef HAVE_TOUCHSCREENGUI
if (m_touchscreengui) {
m_touchscreengui->setVisible(false);
}
#endif
return g_menumgr.preprocessEvent(event);
}
@ -130,12 +128,10 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
return true;
}
#ifdef HAVE_TOUCHSCREENGUI
} else if (m_touchscreengui && event.EventType == irr::EET_TOUCH_INPUT_EVENT) {
// In case of touchscreengui, we have to handle different events
m_touchscreengui->translateEvent(event);
return true;
#endif
} else if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) {
// joystick may be nullptr if game is launched with '--random-input' parameter

@ -24,10 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <list>
#include "keycode.h"
#include "renderingengine.h"
#ifdef HAVE_TOUCHSCREENGUI
#include "gui/touchscreengui.h"
#endif
class InputHandler;
@ -203,16 +200,12 @@ public:
MyEventReceiver()
{
#ifdef HAVE_TOUCHSCREENGUI
m_touchscreengui = NULL;
#endif
}
JoystickController *joystick = nullptr;
#ifdef HAVE_TOUCHSCREENGUI
TouchScreenGUI *m_touchscreengui;
#endif
private:
s32 mouse_wheel = 0;
@ -332,11 +325,9 @@ public:
return 0.0f;
return 1.0f; // If there is a keyboard event, assume maximum speed
}
#ifdef HAVE_TOUCHSCREENGUI
if (m_receiver->m_touchscreengui && m_receiver->m_touchscreengui->getMovementSpeed())
return m_receiver->m_touchscreengui->getMovementSpeed();
#else
return joystick.getMovementSpeed();
#endif
}
virtual float getMovementDirection()
@ -355,12 +346,9 @@ public:
if (x != 0 || z != 0) /* If there is a keyboard event, it takes priority */
return atan2(x, z);
else
#ifdef HAVE_TOUCHSCREENGUI
else if (m_receiver->m_touchscreengui && m_receiver->m_touchscreengui->getMovementDirection())
return m_receiver->m_touchscreengui->getMovementDirection();
#else
return joystick.getMovementDirection();
#endif
}
virtual bool cancelPressed()

@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "keycode.h"
#include "exceptions.h"
#include "settings.h"
#include "log.h"
#include "debug.h"
@ -26,13 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/string.h"
#include "util/basic_macros.h"
class UnknownKeycode : public BaseException
{
public:
UnknownKeycode(const char *s) :
BaseException(s) {};
};
struct table_key {
const char *Name;
irr::EKEY_CODE Key;

@ -19,11 +19,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include "exceptions.h"
#include "irrlichttypes.h"
#include "Keycodes.h"
#include <IEventReceiver.h>
#include <string>
class UnknownKeycode : public BaseException
{
public:
UnknownKeycode(const char *s) :
BaseException(s) {};
};
/* A key press, consisting of either an Irrlicht keycode
or an actual char */

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef SERVER
#include "settings.h"
#include "client/renderingengine.h"
#include "gui/touchscreengui.h"
#endif
@ -50,11 +51,7 @@ public:
f32 hud_scaling = g_settings->getFloat("hud_scaling", 0.5f, 20.0f);
f32 real_gui_scaling = gui_scaling * density;
f32 real_hud_scaling = hud_scaling * density;
#ifdef HAVE_TOUCHSCREENGUI
bool touch_controls = true;
#else
bool touch_controls = false;
#endif
bool touch_controls = g_touchscreengui;
return {
screen_size, real_gui_scaling, real_hud_scaling,
@ -67,12 +64,7 @@ public:
private:
#ifndef SERVER
static v2f32 calculateMaxFSSize(v2u32 render_target_size, f32 gui_scaling) {
f32 factor =
#ifdef HAVE_TOUCHSCREENGUI
10 / gui_scaling;
#else
15 / gui_scaling;
#endif
f32 factor = (g_settings->getBool("enable_touch") ? 10 : 15) / gui_scaling;
f32 ratio = (f32)render_target_size.X / (f32)render_target_size.Y;
if (ratio < 1)
return { factor, factor / ratio };

@ -39,6 +39,11 @@ void set_default_settings()
// Client
settings->setDefault("address", "");
settings->setDefault("enable_sound", "true");
#if ENABLE_TOUCH
settings->setDefault("enable_touch", "true");
#else
settings->setDefault("enable_touch", "false");
#endif
settings->setDefault("sound_volume", "0.8");
settings->setDefault("sound_volume_unfocused", "0.3");
settings->setDefault("mute_sound", "false");
@ -90,7 +95,7 @@ void set_default_settings()
settings->setDefault("keymap_cmd_local", ".");
settings->setDefault("keymap_minimap", "KEY_KEY_V");
settings->setDefault("keymap_console", "KEY_F10");
#if HAVE_TOUCHSCREENGUI
#if ENABLE_TOUCH
// See https://github.com/minetest/minetest/issues/12792
settings->setDefault("keymap_rangeselect", "KEY_KEY_R");
#else
@ -192,7 +197,11 @@ void set_default_settings()
settings->setDefault("screen_h", "600");
settings->setDefault("window_maximized", "false");
settings->setDefault("autosave_screensize", "true");
#ifdef ENABLE_TOUCH
settings->setDefault("fullscreen", "true");
#else
settings->setDefault("fullscreen", "false");
#endif
settings->setDefault("vsync", "false");
settings->setDefault("fov", "72");
settings->setDefault("leaves_style", "fancy");
@ -298,7 +307,7 @@ void set_default_settings()
settings->setDefault("aux1_descends", "false");
settings->setDefault("doubletap_jump", "false");
settings->setDefault("always_fly_fast", "true");
#ifdef HAVE_TOUCHSCREENGUI
#ifdef ENABLE_TOUCH
settings->setDefault("autojump", "true");
#else
settings->setDefault("autojump", "false");
@ -477,12 +486,12 @@ void set_default_settings()
settings->setDefault("keymap_sneak", "KEY_SHIFT");
#endif
#ifdef HAVE_TOUCHSCREENGUI
settings->setDefault("touchscreen_threshold", "20");
settings->setDefault("touchscreen_sensitivity", "0.2");
settings->setDefault("touch_use_crosshair", "false");
settings->setDefault("fixed_virtual_joystick", "false");
settings->setDefault("virtual_joystick_triggers_aux1", "false");
#ifdef ENABLE_TOUCH
settings->setDefault("clickable_chat_weblinks", "false");
#else
settings->setDefault("clickable_chat_weblinks", "true");
@ -491,7 +500,6 @@ void set_default_settings()
#ifdef __ANDROID__
settings->setDefault("screen_w", "0");
settings->setDefault("screen_h", "0");
settings->setDefault("fullscreen", "true");
settings->setDefault("performance_tradeoffs", "true");
settings->setDefault("max_simultaneous_block_sends_per_client", "10");
settings->setDefault("emergequeue_limit_diskonly", "16");

@ -1,8 +1,3 @@
set(extra_gui_SRCS "")
if(ENABLE_TOUCH)
set(extra_gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/touchscreengui.cpp)
endif()
set(gui_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/guiAnimatedImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiBackgroundImage.cpp
@ -29,6 +24,6 @@ set(gui_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp
${CMAKE_CURRENT_SOURCE_DIR}/modalMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/profilergraph.cpp
${extra_gui_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/touchscreengui.cpp
PARENT_SCOPE
)

@ -316,13 +316,11 @@ void GUIFormSpecMenu::parseSize(parserData* data, const std::string &element)
data->invsize.Y = MYMAX(0, stof(parts[1]));
lockSize(false);
#ifndef HAVE_TOUCHSCREENGUI
if (parts.size() == 3) {
if (!g_settings->getBool("enable_touch") && parts.size() == 3) {
if (parts[2] == "true") {
lockSize(true,v2u32(800,600));
}
}
#endif
data->explicit_size = true;
return;
}
@ -3284,14 +3282,15 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
s32 min_screen_dim = std::min(padded_screensize.X, padded_screensize.Y);
#ifdef HAVE_TOUCHSCREENGUI
// In Android, the preferred imgsize should be larger to accommodate the
double prefer_imgsize;
if (g_settings->getBool("enable_touch")) {
// The preferred imgsize should be larger to accommodate the
// smaller screensize.
double prefer_imgsize = min_screen_dim / 10 * gui_scaling;
#else
prefer_imgsize = min_screen_dim / 10 * gui_scaling;
} else {
// Desktop computers have more space, so try to fit 15 coordinates.
double prefer_imgsize = min_screen_dim / 15 * gui_scaling;
#endif
prefer_imgsize = min_screen_dim / 15 * gui_scaling;
}
// Try to use the preferred imgsize, but if that's bigger than the maximum
// size, use the maximum size.
use_imgsize = std::min(prefer_imgsize,

@ -25,10 +25,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#ifdef HAVE_TOUCHSCREENGUI
#include "client/renderingengine.h"
#endif
#include "porting.h"
#include "gettext.h"
@ -66,11 +62,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
/*
Calculate new sizes and positions
*/
#ifdef HAVE_TOUCHSCREENGUI
const float s = m_gui_scale * RenderingEngine::getDisplayDensity() / 2;
#else
const float s = m_gui_scale;
#endif
DesiredRect = core::rect<s32>(
screensize.X / 2 - 580 * s / 2,
screensize.Y / 2 - 300 * s / 2,

@ -27,10 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gettext.h"
#include "porting.h"
#include "settings.h"
#ifdef HAVE_TOUCHSCREENGUI
#include "touchscreengui.h"
#endif
GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent,
s32 id, IMenuManager *menumgr, bool remap_dbl_click) :
@ -44,11 +41,12 @@ GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent,
{
m_gui_scale = std::max(g_settings->getFloat("gui_scaling"), 0.5f);
const float screen_dpi_scale = RenderingEngine::getDisplayDensity();
#ifdef HAVE_TOUCHSCREENGUI
if (g_settings->getBool("enable_touch")) {
m_gui_scale *= 1.1f - 0.3f * screen_dpi_scale + 0.2f * screen_dpi_scale * screen_dpi_scale;
#else
} else {
m_gui_scale *= screen_dpi_scale;
#endif
}
setVisible(true);
m_menumgr->createdMenu(this);
@ -102,10 +100,8 @@ void GUIModalMenu::quitMenu()
Environment->removeFocus(this);
m_menumgr->deletingMenu(this);
this->remove();
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->show();
#endif
}
static bool isChild(gui::IGUIElement *tocheck, gui::IGUIElement *parent)

@ -55,6 +55,7 @@ const std::string joystick_image_names[] = {
static EKEY_CODE id_to_keycode(touch_gui_button_id id)
{
EKEY_CODE code;
// ESC isn't part of the keymap.
if (id == exit_id)
return KEY_ESCAPE;
@ -110,7 +111,15 @@ static EKEY_CODE id_to_keycode(touch_gui_button_id id)
break;
}
assert(!key.empty());
return keyname_to_keycode(g_settings->get("keymap_" + key).c_str());
std::string resolved = g_settings->get("keymap_" + key);
try {
code = keyname_to_keycode(resolved.c_str());
} catch (UnknownKeycode &e) {
code = KEY_UNKNOWN;
warningstream << "TouchScreenGUI: Unknown key '" << resolved
<< "' for '" << key << "', hiding button." << std::endl;
}
return code;
}
static void load_button_texture(const button_info *btn, const std::string &path,
@ -523,13 +532,23 @@ void TouchScreenGUI::init(ISimpleTextureSource *tsrc)
+ 0.5f * button_size),
AHBB_Dir_Right_Left, 3.0f);
m_settings_bar.addButton(fly_id, L"fly", "fly_btn.png");
m_settings_bar.addButton(noclip_id, L"noclip", "noclip_btn.png");
m_settings_bar.addButton(fast_id, L"fast", "fast_btn.png");
m_settings_bar.addButton(debug_id, L"debug", "debug_btn.png");
m_settings_bar.addButton(camera_id, L"camera", "camera_btn.png");
m_settings_bar.addButton(range_id, L"rangeview", "rangeview_btn.png");
m_settings_bar.addButton(minimap_id, L"minimap", "minimap_btn.png");
const static std::map<touch_gui_button_id, std::string> settings_bar_buttons {
{fly_id, "fly"},
{noclip_id, "noclip"},
{fast_id, "fast"},
{debug_id, "debug"},
{camera_id, "camera"},
{range_id, "rangeview"},
{minimap_id, "minimap"},
};
for (const auto &pair : settings_bar_buttons) {
if (id_to_keycode(pair.first) == KEY_UNKNOWN)
continue;
std::wstring wide = utf8_to_wide(pair.second);
m_settings_bar.addButton(pair.first, wide.c_str(),
pair.second + "_btn.png");
}
// Chat is shown by default, so chat_hide_btn.png is shown first.
m_settings_bar.addToggleButton(toggle_chat_id, L"togglechat",
@ -545,10 +564,20 @@ void TouchScreenGUI::init(ISimpleTextureSource *tsrc)
+ 0.5f * button_size),
AHBB_Dir_Left_Right, 2.0f);
m_rare_controls_bar.addButton(chat_id, L"chat", "chat_btn.png");
m_rare_controls_bar.addButton(inventory_id, L"inv", "inventory_btn.png");
m_rare_controls_bar.addButton(drop_id, L"drop", "drop_btn.png");
m_rare_controls_bar.addButton(exit_id, L"exit", "exit_btn.png");
const static std::map<touch_gui_button_id, std::string> rare_controls_bar_buttons {
{chat_id, "chat"},
{inventory_id, "inventory"},
{drop_id, "drop"},
{exit_id, "exit"},
};
for (const auto &pair : rare_controls_bar_buttons) {
if (id_to_keycode(pair.first) == KEY_UNKNOWN)
continue;
std::wstring wide = utf8_to_wide(pair.second);
m_rare_controls_bar.addButton(pair.first, wide.c_str(),
pair.second + "_btn.png");
}
m_initialized = true;
}

@ -50,9 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gui/guiEngine.h"
#include "gui/mainmenumanager.h"
#endif
#ifdef HAVE_TOUCHSCREENGUI
#include "gui/touchscreengui.h"
#endif
// for version information only
extern "C" {

@ -153,13 +153,6 @@ ScriptApiBase::ScriptApiBase(ScriptingType type):
lua_pushstring(m_luastack, porting::getPlatformName());
lua_setglobal(m_luastack, "PLATFORM");
#ifdef HAVE_TOUCHSCREENGUI
lua_pushboolean(m_luastack, true);
#else
lua_pushboolean(m_luastack, false);
#endif
lua_setglobal(m_luastack, "TOUCHSCREEN_GUI");
// Make sure Lua uses the right locale
setlocale(LC_NUMERIC, "C");
}