From 34286d77c7ee65be480a372233c5ab7c4b81d9db Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Thu, 22 Feb 2024 16:44:49 +0100 Subject: [PATCH] Allow toggling touchscreen mode at runtime (#14075) Signed-off-by: David Heidelberg Co-authored-by: Gregor Parzefall --- .luacheckrc | 7 -- builtin/fstk/buttonbar.lua | 14 ++- builtin/mainmenu/content/dlg_contentstore.lua | 8 +- builtin/mainmenu/settings/dlg_settings.lua | 27 +++-- builtin/mainmenu/tab_local.lua | 2 +- builtin/settingtypes.txt | 5 + doc/compiling/README.md | 2 +- src/CMakeLists.txt | 5 +- src/client/clientlauncher.cpp | 18 +-- src/client/game.cpp | 114 ++++++------------ src/client/hud.cpp | 7 -- src/client/inputhandler.cpp | 4 - src/client/inputhandler.h | 20 +-- src/client/keycode.cpp | 8 -- src/client/keycode.h | 8 ++ src/clientdynamicinfo.h | 14 +-- src/defaultsettings.cpp | 16 ++- src/gui/CMakeLists.txt | 7 +- src/gui/guiFormSpecMenu.cpp | 21 ++-- src/gui/guiPasswordChange.cpp | 9 +- src/gui/modalMenu.cpp | 16 +-- src/gui/touchscreengui.cpp | 53 ++++++-- src/main.cpp | 3 - src/script/cpp_api/s_base.cpp | 7 -- 24 files changed, 175 insertions(+), 220 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 9dfa76d01..fcc04cab3 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -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", - }, -} diff --git a/builtin/fstk/buttonbar.lua b/builtin/fstk/buttonbar.lua index effd0eba7..c7da41280 100644 --- a/builtin/fstk/buttonbar.lua +++ b/builtin/fstk/buttonbar.lua @@ -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 diff --git a/builtin/mainmenu/content/dlg_contentstore.lua b/builtin/mainmenu/content/dlg_contentstore.lua index e567fcef7..6070bf753 100644 --- a/builtin/mainmenu/content/dlg_contentstore.lua +++ b/builtin/mainmenu/content/dlg_contentstore.lua @@ -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() diff --git a/builtin/mainmenu/settings/dlg_settings.lua b/builtin/mainmenu/settings/dlg_settings.lua index 9e5d2a46c..aa9aaa283 100644 --- a/builtin/mainmenu/settings/dlg_settings.lua +++ b/builtin/mainmenu/settings/dlg_settings.lua @@ -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) + dialogdata.components = nil + if not filtered_page_by_id[dialogdata.page_id] then - dialogdata.components = nil dialogdata.leftscroll = 0 dialogdata.rightscroll = 0 diff --git a/builtin/mainmenu/tab_local.lua b/builtin/mainmenu/tab_local.lua index c35a3f6fb..ff1a22398 100644 --- a/builtin/mainmenu/tab_local.lua +++ b/builtin/mainmenu/tab_local.lua @@ -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) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 9dfedbfe9..1daa6dc4d 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -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 diff --git a/doc/compiling/README.md b/doc/compiling/README.md index cdc39b217..7ce06c2de 100644 --- a/doc/compiling/README.md +++ b/doc/compiling/README.md @@ -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: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6879f2e86..5eb6677a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index 02bbf34bf..c23a1e3e9 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -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 - receiver->m_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver); - g_touchscreengui = receiver->m_touchscreengui; -#endif + if (g_settings->getBool("enable_touch")) { + receiver->m_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver); + g_touchscreengui = receiver->m_touchscreengui; + } 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 - delete g_touchscreengui; - g_touchscreengui = NULL; - receiver->m_touchscreengui = NULL; -#endif + if (g_touchscreengui) { + delete g_touchscreengui; + g_touchscreengui = NULL; + receiver->m_touchscreengui = NULL; + } /* Save the settings when leaving the game. * This makes sure that setting changes made in-game are persisted even diff --git a/src/client/game.cpp b/src/client/game.cpp index 46bd800be..761484c5c 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -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 - g_touchscreengui->hide(); -#endif + if (g_touchscreengui) + g_touchscreengui->hide(); 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 - g_touchscreengui->hide(); -#endif + + if (g_touchscreengui) + g_touchscreengui->hide(); + } 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 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,21 +4458,23 @@ 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" - "No menu open:\n" - "- slide finger: look around\n" - "- tap: place/punch/use (default)\n" - "- long tap: dig/use (default)\n" - "Menu/inventory open:\n" - "- double tap (outside):\n" - " --> close\n" - "- touch stack, touch slot:\n" - " --> move stack\n" - "- touch&drag, tap 2nd finger\n" - " --> place single item to slot\n" - ); -#endif + 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" + "- long tap: dig/use (default)\n" + "Menu/inventory open:\n" + "- double tap (outside):\n" + " --> close\n" + "- touch stack, touch slot:\n" + " --> move stack\n" + "- touch&drag, tap 2nd finger\n" + " --> place single item to slot\n" + ); + } 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"; diff --git a/src/client/hud.cpp b/src/client/hud.cpp index d23b96e5b..181dcb0e4 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -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) { diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index 7b54ac93d..82303c455 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -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 diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index 81bed61a8..68bd7bb03 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -24,10 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #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 - return m_receiver->m_touchscreengui->getMovementSpeed(); -#else + if (m_receiver->m_touchscreengui && m_receiver->m_touchscreengui->getMovementSpeed()) + return m_receiver->m_touchscreengui->getMovementSpeed(); 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 + return joystick.getMovementDirection(); } virtual bool cancelPressed() diff --git a/src/client/keycode.cpp b/src/client/keycode.cpp index 1fcd15e01..14360b1a1 100644 --- a/src/client/keycode.cpp +++ b/src/client/keycode.cpp @@ -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; diff --git a/src/client/keycode.h b/src/client/keycode.h index 7036705d1..6bc44bb1d 100644 --- a/src/client/keycode.h +++ b/src/client/keycode.h @@ -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 #include +class UnknownKeycode : public BaseException +{ +public: + UnknownKeycode(const char *s) : + BaseException(s) {}; +}; + /* A key press, consisting of either an Irrlicht keycode or an actual char */ diff --git a/src/clientdynamicinfo.h b/src/clientdynamicinfo.h index 547329b06..4e033dfbf 100644 --- a/src/clientdynamicinfo.h +++ b/src/clientdynamicinfo.h @@ -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 }; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index d7eee5c39..711f50f60 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -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"); diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 4434b14a0..87575f320 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -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 ) diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index a1b7519be..e4e123c16 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -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 - // smaller screensize. - double 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 + double prefer_imgsize; + if (g_settings->getBool("enable_touch")) { + // The preferred imgsize should be larger to accommodate the + // smaller screensize. + prefer_imgsize = min_screen_dim / 10 * gui_scaling; + } else { + // Desktop computers have more space, so try to fit 15 coordinates. + 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, diff --git a/src/gui/guiPasswordChange.cpp b/src/gui/guiPasswordChange.cpp index b1264ddfe..6b0c0063d 100644 --- a/src/gui/guiPasswordChange.cpp +++ b/src/gui/guiPasswordChange.cpp @@ -25,10 +25,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#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( screensize.X / 2 - 580 * s / 2, screensize.Y / 2 - 300 * s / 2, diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp index 11cb55e1c..ae2a89e96 100644 --- a/src/gui/modalMenu.cpp +++ b/src/gui/modalMenu.cpp @@ -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 - m_gui_scale *= 1.1f - 0.3f * screen_dpi_scale + 0.2f * screen_dpi_scale * screen_dpi_scale; -#else - m_gui_scale *= screen_dpi_scale; -#endif + + 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 { + m_gui_scale *= screen_dpi_scale; + } 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) diff --git a/src/gui/touchscreengui.cpp b/src/gui/touchscreengui.cpp index d8ac39c31..668130b01 100644 --- a/src/gui/touchscreengui.cpp +++ b/src/gui/touchscreengui.cpp @@ -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 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 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; } diff --git a/src/main.cpp b/src/main.cpp index 5627a362d..e7ec6dd53 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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" { diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index a2677f421..7731de7a7 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -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"); }