From 23bfb2db72638f4de5681e0b69d41fd8b0a8bda7 Mon Sep 17 00:00:00 2001 From: y5nw <37980625+y5nw@users.noreply.github.com> Date: Sun, 20 Apr 2025 20:20:49 +0200 Subject: [PATCH] Move keybinding settings to (Lua-based) setting menu (#15791) --- .luacheckrc | 12 + builtin/common/menu.lua | 11 + builtin/common/settings/components.lua | 54 +++ builtin/common/settings/dlg_settings.lua | 33 +- builtin/common/settings/settingtypes.lua | 6 +- builtin/mainmenu/init.lua | 9 +- builtin/pause_menu/init.lua | 1 + builtin/settingtypes.txt | 467 ++++++++++++----------- doc/menu_lua_api.md | 1 - src/client/game_formspec.cpp | 12 - src/client/inputhandler.cpp | 2 + src/client/inputhandler.h | 14 + src/gui/CMakeLists.txt | 2 +- src/gui/guiButtonKey.cpp | 141 +++++++ src/gui/guiButtonKey.h | 75 ++++ src/gui/guiFormSpecMenu.cpp | 14 +- src/gui/guiKeyChangeMenu.cpp | 401 ------------------- src/gui/guiKeyChangeMenu.h | 63 --- src/gui/mainmenumanager.h | 14 - src/script/lua_api/l_mainmenu.cpp | 18 - src/script/lua_api/l_mainmenu.h | 2 - src/script/lua_api/l_menu_common.cpp | 10 + src/script/lua_api/l_menu_common.h | 1 + src/script/lua_api/l_pause_menu.cpp | 9 +- src/script/lua_api/l_pause_menu.h | 1 - 25 files changed, 591 insertions(+), 782 deletions(-) create mode 100644 builtin/common/menu.lua create mode 100644 src/gui/guiButtonKey.cpp create mode 100644 src/gui/guiButtonKey.h delete mode 100644 src/gui/guiKeyChangeMenu.cpp delete mode 100644 src/gui/guiKeyChangeMenu.h diff --git a/.luacheckrc b/.luacheckrc index de45f0413..670c84325 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -33,6 +33,13 @@ globals = { "_", } +stds.menu_common = { + globals = { + "mt_color_grey", "mt_color_blue", "mt_color_lightblue", "mt_color_green", + "mt_color_dark_green", "mt_color_orange", "mt_color_red", + }, +} + files["builtin/client/register.lua"] = { globals = { debug = {fields={"getinfo"}}, @@ -73,11 +80,16 @@ files["builtin/common/filterlist.lua"] = { } files["builtin/mainmenu"] = { + std = "+menu_common", globals = { "gamedata", }, } +files["builtin/common/settings"] = { + std = "+menu_common", +} + files["builtin/common/tests"] = { read_globals = { "describe", diff --git a/builtin/common/menu.lua b/builtin/common/menu.lua new file mode 100644 index 000000000..165286470 --- /dev/null +++ b/builtin/common/menu.lua @@ -0,0 +1,11 @@ +-- Luanti +-- SPDX-License-Identifier: LGPL-2.1-or-later + +-- These colors are used by the main menu and the settings menu +mt_color_grey = "#AAAAAA" +mt_color_blue = "#6389FF" +mt_color_lightblue = "#99CCFF" +mt_color_green = "#72FF63" +mt_color_dark_green = "#25C191" +mt_color_orange = "#FF8800" +mt_color_red = "#FF3300" diff --git a/builtin/common/settings/components.lua b/builtin/common/settings/components.lua index de7a63fee..b3035fd51 100644 --- a/builtin/common/settings/components.lua +++ b/builtin/common/settings/components.lua @@ -37,6 +37,7 @@ local make = {} -- * `fs` is a string for the formspec. -- Components should be relative to `0,0`, and not exceed `avail_w` or the returned `used_height`. -- * `used_height` is the space used by components in `fs`. +-- * `spacing`: (Optional) the vertical margin to be added before the component (default 0.25) -- * `on_submit = function(self, fields, parent)`: -- * `fields`: submitted formspec fields -- * `parent`: the fstk element for the settings UI, use to show dialogs @@ -442,6 +443,59 @@ local function make_noise_params(setting) } end +function make.key(setting) + local btn_bind = "bind_" .. setting.name + local btn_clear = "unbind_" .. setting.name + local function add_conflict_warnings(fs, height) + local value = core.settings:get(setting.name) + if value == "" then + return height + end + for _, o in ipairs(core.full_settingtypes) do + if o.type == "key" and o.name ~= setting.name and core.are_keycodes_equal(core.settings:get(o.name), value) then + table.insert(fs, ("label[0,%f;%s]"):format(height + 0.3, + core.colorize(mt_color_orange, fgettext([[Conflicts with "$1"]], fgettext(o.readable_name))))) + height = height + 0.6 + end + end + return height + end + return { + info_text = setting.comment, + setting = setting, + spacing = 0.1, + + get_formspec = function(self, avail_w) + self.resettable = core.settings:has(setting.name) + local btn_bind_width = math.max(2.5, avail_w/2) + local value = core.settings:get(setting.name) + local fs = { + ("label[0,0.4;%s]"):format(get_label(setting)), + ("button_key[%f,0;%f,0.8;%s;%s]"):format( + btn_bind_width, btn_bind_width-0.8, + btn_bind, core.formspec_escape(value)), + ("image_button[%f,0;0.8,0.8;%s;%s;]"):format(avail_w - 0.8, + core.formspec_escape(defaulttexturedir .. "clear.png"), + btn_clear), + ("tooltip[%s;%s]"):format(btn_clear, fgettext("Remove keybinding")), + } + local height = 0.8 + height = add_conflict_warnings(fs, height) + return table.concat(fs), height + end, + + on_submit = function(self, fields) + if fields[btn_bind] then + core.settings:set(setting.name, fields[btn_bind]) + return true + elseif fields[btn_clear] then + core.settings:set(setting.name, "") + return true + end + end, + } +end + if INIT == "pause_menu" then -- Making the noise parameter dialog work in the pause menu settings would -- require porting "FSTK" (at least the dialog API) from the mainmenu formspec diff --git a/builtin/common/settings/dlg_settings.lua b/builtin/common/settings/dlg_settings.lua index b43d9ebdc..8d4a8b6de 100644 --- a/builtin/common/settings/dlg_settings.lua +++ b/builtin/common/settings/dlg_settings.lua @@ -22,7 +22,6 @@ local component_funcs = dofile(path .. "components.lua") local shadows_component = dofile(path .. "shadows_component.lua") local loaded = false -local full_settings local info_icon_path = core.formspec_escape(defaulttexturedir .. "settings_info.png") local reset_icon_path = core.formspec_escape(defaulttexturedir .. "settings_reset.png") local all_pages = {} @@ -32,7 +31,7 @@ local filtered_page_by_id = page_by_id local function get_setting_info(name) - for _, entry in ipairs(full_settings) do + for _, entry in ipairs(core.full_settingtypes) do if entry.type ~= "category" and entry.name == name then return entry end @@ -70,7 +69,7 @@ local function load_settingtypes() end end - for _, entry in ipairs(full_settings) do + for _, entry in ipairs(core.full_settingtypes) do if entry.type == "category" then if entry.level == 0 then section = entry.name @@ -104,24 +103,7 @@ local function load() end loaded = true - full_settings = settingtypes.parse_config_file(false, true) - - local change_keys = { - query_text = "Controls", - requires = { - keyboard_mouse = true, - }, - context = "client", - get_formspec = function(self, avail_w) - local btn_w = math.min(avail_w, 3) - return ("button[0,0;%f,0.8;btn_change_keys;%s]"):format(btn_w, fgettext("Controls")), 0.8 - end, - on_submit = function(self, fields) - if fields.btn_change_keys then - core.show_keys_menu() - end - end, - } + core.full_settingtypes = settingtypes.parse_config_file(false, true) local touchscreen_layout = { query_text = "Touchscreen layout", @@ -166,7 +148,6 @@ local function load() load_settingtypes() - table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys) -- insert after "touch_controls" table.insert(page_by_id.controls_touchscreen.content, 2, touchscreen_layout) do @@ -665,7 +646,13 @@ local function get_formspec(dialogdata) fs[#fs + 1] = "container_end[]" if used_h > 0 then - y = y + used_h + 0.25 + local spacing = 0.25 + local next_comp = dialogdata.components[i + 1] + if next_comp and next_comp.spacing then + spacing = next_comp.spacing + end + + y = y + used_h + spacing end end diff --git a/builtin/common/settings/settingtypes.lua b/builtin/common/settings/settingtypes.lua index 39a50e1f4..90ff8975c 100644 --- a/builtin/common/settings/settingtypes.lua +++ b/builtin/common/settings/settingtypes.lua @@ -249,9 +249,9 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se if not default then return "Invalid string setting" end - if setting_type == "key" and not read_all then - -- ignore key type if read_all is false - return + + if setting_type == "key" then + requires.keyboard_mouse = true end table.insert(settings, { diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua index ec33f33b3..acf1f738d 100644 --- a/builtin/mainmenu/init.lua +++ b/builtin/mainmenu/init.lua @@ -15,14 +15,6 @@ --with this program; if not, write to the Free Software Foundation, Inc., --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -mt_color_grey = "#AAAAAA" -mt_color_blue = "#6389FF" -mt_color_lightblue = "#99CCFF" -mt_color_green = "#72FF63" -mt_color_dark_green = "#25C191" -mt_color_orange = "#FF8800" -mt_color_red = "#FF3300" - MAIN_TAB_W = 15.5 MAIN_TAB_H = 7.1 TABHEADER_H = 0.85 @@ -35,6 +27,7 @@ local basepath = core.get_builtin_path() defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" .. DIR_DELIM .. "pack" .. DIR_DELIM +dofile(basepath .. "common" .. DIR_DELIM .. "menu.lua") dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua") dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.lua") dofile(basepath .. "fstk" .. DIR_DELIM .. "dialog.lua") diff --git a/builtin/pause_menu/init.lua b/builtin/pause_menu/init.lua index 035d2ba99..01c5dc856 100644 --- a/builtin/pause_menu/init.lua +++ b/builtin/pause_menu/init.lua @@ -8,5 +8,6 @@ defaulttexturedir = "" local builtin_shared = {} assert(loadfile(commonpath .. "register.lua"))(builtin_shared) +assert(loadfile(commonpath .. "menu.lua"))(builtin_shared) assert(loadfile(pausepath .. "register.lua"))(builtin_shared) dofile(commonpath .. "settings" .. DIR_DELIM .. "init.lua") diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 825a85b97..83d0b48e0 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -31,7 +31,7 @@ # - enum # - path # - filepath -# - key (will be ignored in GUI, since a special key change dialog exists) +# - key # - flags # - noise_params_2d # - noise_params_3d @@ -91,6 +91,8 @@ # * touchscreen / keyboard_mouse # * opengl / gles # * You can negate any requirement by prepending with ! +# * The "keyboard_mouse" requirement is automatically added to settings with the +# "key" type. # # Sections are marked by a single line in the format: [Section Name] # Sub-section are marked by adding * in front of the section name: [*Sub-section] @@ -178,6 +180,228 @@ enable_hotbar_mouse_wheel (Hotbar: Enable mouse wheel for selection) bool true # Requires: keyboard_mouse invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false +[**Keybindings] + +# Key for moving the player forward. +keymap_forward (Move forward) key KEY_KEY_W + +# Key for moving the player backward. +# Will also disable autoforward, when active. +keymap_backward (Move backward) key KEY_KEY_S + +# Key for moving the player left. +keymap_left (Move left) key KEY_KEY_A + +# Key for moving the player right. +keymap_right (Move right) key KEY_KEY_D + +# Key for jumping. +keymap_jump (Jump) key KEY_SPACE + +# Key for sneaking. +# Also used for climbing down and descending in water if aux1_descends is disabled. +keymap_sneak (Sneak) key KEY_LSHIFT + +# Key for digging, punching or using something. +# (Note: The actual meaning might vary on a per-game basis.) +keymap_dig (Dig/punch/use) key KEY_LBUTTON + +# Key for placing an item/block or for using something. +# (Note: The actual meaning might vary on a per-game basis.) +keymap_place (Place/use) key KEY_RBUTTON + +# Key for opening the inventory. +keymap_inventory (Open inventory) key KEY_KEY_I + +# Key for moving fast in fast mode. +keymap_aux1 (Aux1) key KEY_KEY_E + +# Key for opening the chat window. +keymap_chat (Open chat) key KEY_KEY_T + +# Key for opening the chat window to type commands. +keymap_cmd (Command) key / + +# Key for opening the chat window to type local commands. +keymap_cmd_local (Local command) key . + +# Key for toggling unlimited view range. +keymap_rangeselect (Range select) key + +# Key for toggling flying. +keymap_freemove (Toggle fly) key KEY_KEY_K + +# Key for toggling pitch move mode. +keymap_pitchmove (Toggle pitchmove) key + +# Key for toggling fast mode. +keymap_fastmove (Toggle fast) key KEY_KEY_J + +# Key for toggling noclip mode. +keymap_noclip (Toggle noclip) key KEY_KEY_H + +# Key for selecting the next item in the hotbar. +keymap_hotbar_next (Hotbar: select next item) key KEY_KEY_N + +# Key for selecting the previous item in the hotbar. +keymap_hotbar_previous (Hotbar: select previous item) key KEY_KEY_B + +# Key for muting the game. +keymap_mute (Mute) key KEY_KEY_M + +# Key for increasing the volume. +keymap_increase_volume (Increase volume) key + +# Key for decreasing the volume. +keymap_decrease_volume (Decrease volume) key + +# Key for toggling autoforward. +keymap_autoforward (Toggle automatic forward) key + +# Key for toggling cinematic mode. +keymap_cinematic (Toggle cinematic mode) key + +# Key for toggling display of minimap. +keymap_minimap (Toggle minimap) key KEY_KEY_V + +# Key for taking screenshots. +keymap_screenshot (Screenshot) key KEY_F12 + +# Key for toggling fullscreen mode. +keymap_fullscreen (Toggle fullscreen) key KEY_F11 + +# Key for dropping the currently selected item. +keymap_drop (Drop item) key KEY_KEY_Q + +# Key to use view zoom when possible. +keymap_zoom (Zoom) key KEY_KEY_Z + +# Key for toggling the display of the HUD. +keymap_toggle_hud (Toggle HUD) key KEY_F1 + +# Key for toggling the display of chat. +keymap_toggle_chat (Toggle chat log) key KEY_F2 + +# Key for toggling the display of the large chat console. +keymap_console (Large chat console) key KEY_F10 + +# Key for toggling the display of fog. +keymap_toggle_fog (Toggle fog) key KEY_F3 + +# Key for toggling the display of debug info. +keymap_toggle_debug (Toggle debug info) key KEY_F5 + +# Key for toggling the display of the profiler. Used for development. +keymap_toggle_profiler (Toggle profiler) key KEY_F6 + +# Key for toggling the display of mapblock boundaries. +keymap_toggle_block_bounds (Toggle block bounds) key + +# Key for switching between first- and third-person camera. +keymap_camera_mode (Toggle camera mode) key KEY_KEY_C + +# Key for increasing the viewing range. +keymap_increase_viewing_range_min (Increase view range) key + + +# Key for decreasing the viewing range. +keymap_decrease_viewing_range_min (Decrease view range) key - + +# Key for selecting the first hotbar slot. +keymap_slot1 (Hotbar slot 1) key KEY_KEY_1 + +# Key for selecting the second hotbar slot. +keymap_slot2 (Hotbar slot 2) key KEY_KEY_2 + +# Key for selecting the third hotbar slot. +keymap_slot3 (Hotbar slot 3) key KEY_KEY_3 + +# Key for selecting the fourth hotbar slot. +keymap_slot4 (Hotbar slot 4) key KEY_KEY_4 + +# Key for selecting the fifth hotbar slot. +keymap_slot5 (Hotbar slot 5) key KEY_KEY_5 + +# Key for selecting the sixth hotbar slot. +keymap_slot6 (Hotbar slot 6) key KEY_KEY_6 + +# Key for selecting the seventh hotbar slot. +keymap_slot7 (Hotbar slot 7) key KEY_KEY_7 + +# Key for selecting the eighth hotbar slot. +keymap_slot8 (Hotbar slot 8) key KEY_KEY_8 + +# Key for selecting the ninth hotbar slot. +keymap_slot9 (Hotbar slot 9) key KEY_KEY_9 + +# Key for selecting the tenth hotbar slot. +keymap_slot10 (Hotbar slot 10) key KEY_KEY_0 + +# Key for selecting the 11th hotbar slot. +keymap_slot11 (Hotbar slot 11) key + +# Key for selecting the 12th hotbar slot. +keymap_slot12 (Hotbar slot 12) key + +# Key for selecting the 13th hotbar slot. +keymap_slot13 (Hotbar slot 13) key + +# Key for selecting the 14th hotbar slot. +keymap_slot14 (Hotbar slot 14) key + +# Key for selecting the 15th hotbar slot. +keymap_slot15 (Hotbar slot 15) key + +# Key for selecting the 16th hotbar slot. +keymap_slot16 (Hotbar slot 16) key + +# Key for selecting the 17th hotbar slot. +keymap_slot17 (Hotbar slot 17) key + +# Key for selecting the 18th hotbar slot. +keymap_slot18 (Hotbar slot 18) key + +# Key for selecting the 19th hotbar slot. +keymap_slot19 (Hotbar slot 19) key + +# Key for selecting the 20th hotbar slot. +keymap_slot20 (Hotbar slot 20) key + +# Key for selecting the 21st hotbar slot. +keymap_slot21 (Hotbar slot 21) key + +# Key for selecting the 22nd hotbar slot. +keymap_slot22 (Hotbar slot 22) key + +# Key for selecting the 23rd hotbar slot. +keymap_slot23 (Hotbar slot 23) key + +# Key for selecting the 24th hotbar slot. +keymap_slot24 (Hotbar slot 24) key + +# Key for selecting the 25th hotbar slot. +keymap_slot25 (Hotbar slot 25) key + +# Key for selecting the 26th hotbar slot. +keymap_slot26 (Hotbar slot 26) key + +# Key for selecting the 27th hotbar slot. +keymap_slot27 (Hotbar slot 27) key + +# Key for selecting the 28th hotbar slot. +keymap_slot28 (Hotbar slot 28) key + +# Key for selecting the 29th hotbar slot. +keymap_slot29 (Hotbar slot 29) key + +# Key for selecting the 30th hotbar slot. +keymap_slot30 (Hotbar slot 30) key + +# Key for selecting the 31st hotbar slot. +keymap_slot31 (Hotbar slot 31) key + +# Key for selecting the 32nd hotbar slot. +keymap_slot32 (Hotbar slot 32) key + [*Touchscreen] # Enables the touchscreen controls, allowing you to play the game with a touchscreen. @@ -1825,7 +2049,6 @@ instrument.profiler (Profiler) bool false # 0 = disable. Useful for developers. profiler_print_interval (Engine profiling data print interval) int 0 0 - [*Advanced] [**Graphics] [client] @@ -2219,6 +2442,23 @@ curl_parallel_limit (cURL parallel limit) int 8 1 2147483647 # Maximum time a file download (e.g. a mod download) may take, stated in milliseconds. curl_file_download_timeout (cURL file download timeout) int 300000 5000 2147483647 +[**Client Debugging] [client] + +# Key for toggling the camera update. Only usable with 'debug' privilege. +keymap_toggle_update_camera (Toggle camera update) key + +# Key for switching to the previous entry in Quicktune. +keymap_quicktune_prev (Quicktune: select previous entry) key + +# Key for switching to the next entry in Quicktune. +keymap_quicktune_next (Quicktune: select next entry) key + +# Key for decrementing the selected value in Quicktune. +keymap_quicktune_dec (Quicktune: decrement value) key + +# Key for incrementing the selected value in Quicktune. +keymap_quicktune_inc (Quicktune: increment value) key + [**Miscellaneous] # Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output. @@ -2345,226 +2585,3 @@ show_technical_names (Show technical names) bool false # Controlled by a checkbox in the settings menu. show_advanced (Show advanced settings) bool false - -# Key for moving the player forward. -keymap_forward (Forward key) key KEY_KEY_W - -# Key for moving the player backward. -# Will also disable autoforward, when active. -keymap_backward (Backward key) key KEY_KEY_S - -# Key for moving the player left. -keymap_left (Left key) key KEY_KEY_A - -# Key for moving the player right. -keymap_right (Right key) key KEY_KEY_D - -# Key for jumping. -keymap_jump (Jump key) key KEY_SPACE - -# Key for sneaking. -# Also used for climbing down and descending in water if aux1_descends is disabled. -keymap_sneak (Sneak key) key KEY_LSHIFT - -# Key for digging, punching or using something. -# (Note: The actual meaning might vary on a per-game basis.) -keymap_dig (Dig/punch/use key) key KEY_LBUTTON - -# Key for placing an item/block or for using something. -# (Note: The actual meaning might vary on a per-game basis.) -keymap_place (Place/use key) key KEY_RBUTTON - -# Key for opening the inventory. -keymap_inventory (Inventory key) key KEY_KEY_I - -# Key for moving fast in fast mode. -keymap_aux1 (Aux1 key) key KEY_KEY_E - -# Key for opening the chat window. -keymap_chat (Chat key) key KEY_KEY_T - -# Key for opening the chat window to type commands. -keymap_cmd (Command key) key / - -# Key for opening the chat window to type local commands. -keymap_cmd_local (Command key) key . - -# Key for toggling unlimited view range. -keymap_rangeselect (Range select key) key - -# Key for toggling flying. -keymap_freemove (Fly key) key KEY_KEY_K - -# Key for toggling pitch move mode. -keymap_pitchmove (Pitch move key) key - -# Key for toggling fast mode. -keymap_fastmove (Fast key) key KEY_KEY_J - -# Key for toggling noclip mode. -keymap_noclip (Noclip key) key KEY_KEY_H - -# Key for selecting the next item in the hotbar. -keymap_hotbar_next (Hotbar next key) key KEY_KEY_N - -# Key for selecting the previous item in the hotbar. -keymap_hotbar_previous (Hotbar previous key) key KEY_KEY_B - -# Key for muting the game. -keymap_mute (Mute key) key KEY_KEY_M - -# Key for increasing the volume. -keymap_increase_volume (Inc. volume key) key - -# Key for decreasing the volume. -keymap_decrease_volume (Dec. volume key) key - -# Key for toggling autoforward. -keymap_autoforward (Automatic forward key) key - -# Key for toggling cinematic mode. -keymap_cinematic (Cinematic mode key) key - -# Key for toggling display of minimap. -keymap_minimap (Minimap key) key KEY_KEY_V - -# Key for taking screenshots. -keymap_screenshot (Screenshot) key KEY_F12 - -# Key for toggling fullscreen mode. -keymap_fullscreen (Fullscreen key) key KEY_F11 - -# Key for dropping the currently selected item. -keymap_drop (Drop item key) key KEY_KEY_Q - -# Key to use view zoom when possible. -keymap_zoom (View zoom key) key KEY_KEY_Z - -# Key for selecting the first hotbar slot. -keymap_slot1 (Hotbar slot 1 key) key KEY_KEY_1 - -# Key for selecting the second hotbar slot. -keymap_slot2 (Hotbar slot 2 key) key KEY_KEY_2 - -# Key for selecting the third hotbar slot. -keymap_slot3 (Hotbar slot 3 key) key KEY_KEY_3 - -# Key for selecting the fourth hotbar slot. -keymap_slot4 (Hotbar slot 4 key) key KEY_KEY_4 - -# Key for selecting the fifth hotbar slot. -keymap_slot5 (Hotbar slot 5 key) key KEY_KEY_5 - -# Key for selecting the sixth hotbar slot. -keymap_slot6 (Hotbar slot 6 key) key KEY_KEY_6 - -# Key for selecting the seventh hotbar slot. -keymap_slot7 (Hotbar slot 7 key) key KEY_KEY_7 - -# Key for selecting the eighth hotbar slot. -keymap_slot8 (Hotbar slot 8 key) key KEY_KEY_8 - -# Key for selecting the ninth hotbar slot. -keymap_slot9 (Hotbar slot 9 key) key KEY_KEY_9 - -# Key for selecting the tenth hotbar slot. -keymap_slot10 (Hotbar slot 10 key) key KEY_KEY_0 - -# Key for selecting the 11th hotbar slot. -keymap_slot11 (Hotbar slot 11 key) key - -# Key for selecting the 12th hotbar slot. -keymap_slot12 (Hotbar slot 12 key) key - -# Key for selecting the 13th hotbar slot. -keymap_slot13 (Hotbar slot 13 key) key - -# Key for selecting the 14th hotbar slot. -keymap_slot14 (Hotbar slot 14 key) key - -# Key for selecting the 15th hotbar slot. -keymap_slot15 (Hotbar slot 15 key) key - -# Key for selecting the 16th hotbar slot. -keymap_slot16 (Hotbar slot 16 key) key - -# Key for selecting the 17th hotbar slot. -keymap_slot17 (Hotbar slot 17 key) key - -# Key for selecting the 18th hotbar slot. -keymap_slot18 (Hotbar slot 18 key) key - -# Key for selecting the 19th hotbar slot. -keymap_slot19 (Hotbar slot 19 key) key - -# Key for selecting the 20th hotbar slot. -keymap_slot20 (Hotbar slot 20 key) key - -# Key for selecting the 21st hotbar slot. -keymap_slot21 (Hotbar slot 21 key) key - -# Key for selecting the 22nd hotbar slot. -keymap_slot22 (Hotbar slot 22 key) key - -# Key for selecting the 23rd hotbar slot. -keymap_slot23 (Hotbar slot 23 key) key - -# Key for selecting the 24th hotbar slot. -keymap_slot24 (Hotbar slot 24 key) key - -# Key for selecting the 25th hotbar slot. -keymap_slot25 (Hotbar slot 25 key) key - -# Key for selecting the 26th hotbar slot. -keymap_slot26 (Hotbar slot 26 key) key - -# Key for selecting the 27th hotbar slot. -keymap_slot27 (Hotbar slot 27 key) key - -# Key for selecting the 28th hotbar slot. -keymap_slot28 (Hotbar slot 28 key) key - -# Key for selecting the 29th hotbar slot. -keymap_slot29 (Hotbar slot 29 key) key - -# Key for selecting the 30th hotbar slot. -keymap_slot30 (Hotbar slot 30 key) key - -# Key for selecting the 31st hotbar slot. -keymap_slot31 (Hotbar slot 31 key) key - -# Key for selecting the 32nd hotbar slot. -keymap_slot32 (Hotbar slot 32 key) key - -# Key for toggling the display of the HUD. -keymap_toggle_hud (HUD toggle key) key KEY_F1 - -# Key for toggling the display of chat. -keymap_toggle_chat (Chat toggle key) key KEY_F2 - -# Key for toggling the display of the large chat console. -keymap_console (Large chat console key) key KEY_F10 - -# Key for toggling the display of fog. -keymap_toggle_fog (Fog toggle key) key KEY_F3 - -# Key for toggling the camera update. Only usable with 'debug' privilege. -keymap_toggle_update_camera (Camera update toggle key) key - -# Key for toggling the display of debug info. -keymap_toggle_debug (Debug info toggle key) key KEY_F5 - -# Key for toggling the display of the profiler. Used for development. -keymap_toggle_profiler (Profiler toggle key) key KEY_F6 - -# Key for toggling the display of mapblock boundaries. -keymap_toggle_block_bounds (Block bounds toggle key) key - -# Key for switching between first- and third-person camera. -keymap_camera_mode (Toggle camera mode key) key KEY_KEY_C - -# Key for increasing the viewing range. -keymap_increase_viewing_range_min (View range increase key) key + - -# Key for decreasing the viewing range. -keymap_decrease_viewing_range_min (View range decrease key) key - diff --git a/doc/menu_lua_api.md b/doc/menu_lua_api.md index 0fccf37a3..38940a7ed 100644 --- a/doc/menu_lua_api.md +++ b/doc/menu_lua_api.md @@ -217,7 +217,6 @@ GUI doing tiling (background only) * `core.set_clouds()` * `core.set_topleft_text(text)` -* `core.show_keys_menu()` * `core.show_touchscreen_layout()` * `core.show_path_select_dialog(formname, caption, is_file_select)` * shows a path select dialog diff --git a/src/client/game_formspec.cpp b/src/client/game_formspec.cpp index dc4be3699..3b86ae7e3 100644 --- a/src/client/game_formspec.cpp +++ b/src/client/game_formspec.cpp @@ -16,7 +16,6 @@ #include "gui/touchcontrols.h" #include "gui/touchscreeneditor.h" #include "gui/guiPasswordChange.h" -#include "gui/guiKeyChangeMenu.h" #include "gui/guiPasswordChange.h" #include "gui/guiOpenURL.h" #include "gui/guiVolumeChange.h" @@ -538,12 +537,6 @@ bool GameFormSpec::handleCallbacks() g_gamecallback->changevolume_requested = false; } - if (g_gamecallback->keyconfig_requested) { - (void)make_irr(guienv, guiroot, -1, - &g_menumgr, texture_src); - g_gamecallback->keyconfig_requested = false; - } - if (g_gamecallback->touchscreenlayout_requested) { (new GUITouchscreenLayout(guienv, guiroot, -1, &g_menumgr, texture_src))->drop(); @@ -556,11 +549,6 @@ bool GameFormSpec::handleCallbacks() g_gamecallback->show_open_url_dialog.clear(); } - if (g_gamecallback->keyconfig_changed) { - m_input->reloadKeybindings(); // update the cache with new settings - g_gamecallback->keyconfig_changed = false; - } - return true; } diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index e7bdd4f30..64c9cc968 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -14,6 +14,8 @@ void MyEventReceiver::reloadKeybindings() { + clearKeyCache(); + keybindings[KeyType::FORWARD] = getKeySetting("keymap_forward"); keybindings[KeyType::BACKWARD] = getKeySetting("keymap_backward"); keybindings[KeyType::LEFT] = getKeySetting("keymap_left"); diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index fec52a74d..85da30ff8 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -12,6 +12,8 @@ #include #include #include "keycode.h" +#include "settings.h" +#include "util/string.h" class InputHandler; @@ -132,6 +134,13 @@ private: class InputHandler { public: + InputHandler() + { + for (const auto &name: Settings::getLayer(SL_DEFAULTS)->getNames()) + if (str_starts_with(name, "keymap_")) + g_settings->registerChangedCallback(name, &settingChangedCallback, this); + } + virtual ~InputHandler() = default; virtual bool isRandom() const @@ -163,6 +172,11 @@ public: virtual void clear() {} virtual void releaseAllKeys() {} + static void settingChangedCallback(const std::string &name, void *data) + { + static_cast(data)->reloadKeybindings(); + } + JoystickController joystick; }; diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 26fd5bfcf..0c1db2ae0 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -5,6 +5,7 @@ set(gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/guiButton.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiButtonImage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiButtonKey.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiEditBox.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp @@ -12,7 +13,6 @@ set(gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/guiFormSpecMenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiInventoryList.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiItemImage.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/guiKeyChangeMenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiOpenURL.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiPasswordChange.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiPathSelectMenu.cpp diff --git a/src/gui/guiButtonKey.cpp b/src/gui/guiButtonKey.cpp new file mode 100644 index 000000000..85e3719b1 --- /dev/null +++ b/src/gui/guiButtonKey.cpp @@ -0,0 +1,141 @@ +// Luanti +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "guiButtonKey.h" +using namespace irr::gui; + +GUIButtonKey *GUIButtonKey::addButton(IGUIEnvironment *environment, + const core::rect &rectangle, ISimpleTextureSource *tsrc, + IGUIElement *parent, s32 id, const wchar_t *text, + const wchar_t *tooltiptext) +{ + auto button = make_irr(environment, + parent ? parent : environment->getRootGUIElement(), id, rectangle, tsrc); + + if (text) + button->setText(text); + + if (tooltiptext) + button->setToolTipText(tooltiptext); + + return button.get(); +} + +void GUIButtonKey::setKey(KeyPress kp) +{ + key_value = kp; + keysym = utf8_to_wide(kp.sym()); + super::setText(wstrgettext(kp.name()).c_str()); +} + +void GUIButtonKey::sendKey() +{ + if (Parent) { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = nullptr; + e.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(e); + } +} + +bool GUIButtonKey::OnEvent(const SEvent & event) +{ + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (!event.KeyInput.PressedDown) { + bool wasPressed = isPressed(); + setPressed(false); + if (capturing) { + cancelCapture(); + if (event.KeyInput.Key != KEY_ESCAPE) + sendKey(); + return true; + } else if (wasPressed && (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)) { + startCapture(); + return true; + } + break; + } else if (capturing) { + if (event.KeyInput.Key != KEY_ESCAPE) { + setPressed(true); + setKey(KeyPress(event.KeyInput)); + } + return true; + } else if (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE) { + setPressed(true); + return true; + } + break; + case EET_MOUSE_INPUT_EVENT: { + auto in_rect = AbsoluteClippingRect.isPointInside( + core::position2d(event.MouseInput.X, event.MouseInput.Y)); + switch (event.MouseInput.Event) + { + case EMIE_LMOUSE_LEFT_UP: + if (!capturing && in_rect) { + setPressed(false); + startCapture(); + return true; + } + [[fallthrough]]; + case EMIE_MMOUSE_LEFT_UP: [[fallthrough]]; + case EMIE_RMOUSE_LEFT_UP: + setPressed(false); + if (capturing) { + cancelCapture(); + sendKey(); + return true; + } + break; + case EMIE_LMOUSE_PRESSED_DOWN: + if (capturing) { + if (event.MouseInput.Simulated) { + cancelCapture(true); + if (in_rect) + return true; + } else { + setPressed(true); + setKey(LMBKey); + return true; + } + } else if (in_rect) { + Environment->setFocus(this); + setPressed(true); + return true; + } + break; + case EMIE_MMOUSE_PRESSED_DOWN: + if (capturing) { + setPressed(true); + setKey(MMBKey); + return true; + } + break; + case EMIE_RMOUSE_PRESSED_DOWN: + if (capturing) { + setPressed(true); + setKey(RMBKey); + return true; + } + break; + default: + break; + } + break; + } + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) { + if (capturing) + return true; + else + nostart = false; // lift nostart restriction if "mouse" (finger) is released outside the button + } + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} diff --git a/src/gui/guiButtonKey.h b/src/gui/guiButtonKey.h new file mode 100644 index 000000000..75d0d56ee --- /dev/null +++ b/src/gui/guiButtonKey.h @@ -0,0 +1,75 @@ +// Luanti +// SPDX-License-Identifier: LGPL-2.1-or-later + +#pragma once + +#include "guiButton.h" +#include "client/keycode.h" +#include "util/string.h" +#include "gettext.h" + +using namespace irr; + +class GUIButtonKey : public GUIButton +{ + using super = GUIButton; + +public: + //! Constructor + GUIButtonKey(gui::IGUIEnvironment *environment, gui::IGUIElement *parent, + s32 id, core::rect rectangle, ISimpleTextureSource *tsrc, + bool noclip = false) + : GUIButton(environment, parent, id, rectangle, tsrc, noclip) {} + + //! Sets the text for the key field + virtual void setText(const wchar_t *text) override + { + setKey(wide_to_utf8(text)); + } + + //! Gets the value for the key field + virtual const wchar_t *getText() const override + { + return keysym.c_str(); + } + + //! Do not drop returned handle + static GUIButtonKey *addButton(gui::IGUIEnvironment *environment, + const core::rect &rectangle, ISimpleTextureSource *tsrc, + IGUIElement *parent, s32 id, const wchar_t *text = L"", + const wchar_t *tooltiptext = L""); + + //! Called if an event happened + virtual bool OnEvent(const SEvent &event) override; + +private: + void sendKey(); + + //! Start key capture + void startCapture() + { + if (nostart) { + nostart = false; + return; + } + capturing = true; + super::setText(wstrgettext("Press Button").c_str()); + } + + //! Cancel key capture + // inhibit_restart: whether the next call to startCapture should be inhibited + void cancelCapture(bool inhibit_restart = false) + { + capturing = false; + nostart |= inhibit_restart; + super::setText(wstrgettext(key_value.name()).c_str()); + } + + //! Sets the captured key and stop capturing + void setKey(KeyPress key); + + bool capturing = false; + bool nostart = false; + KeyPress key_value = {}; + std::wstring keysym; +}; diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 39d8797b4..3c5a9ffde 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -47,6 +47,7 @@ #include "guiButton.h" #include "guiButtonImage.h" #include "guiButtonItemImage.h" +#include "guiButtonKey.h" #include "guiEditBoxWithScrollbar.h" #include "guiInventoryList.h" #include "guiItemImage.h" @@ -1025,8 +1026,16 @@ void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element) if (data->type == "button_url" || data->type == "button_url_exit") spec.url = url; - GUIButton *e = GUIButton::addButton(Environment, rect, m_tsrc, - data->current_parent, spec.fid, spec.flabel.c_str()); + GUIButton *e; + + if (data->type == "button_key") { + spec.ftype = f_Unknown; + e = GUIButtonKey::addButton(Environment, rect, m_tsrc, + data->current_parent, spec.fid, spec.flabel.c_str()); + } else { + e = GUIButton::addButton(Environment, rect, m_tsrc, + data->current_parent, spec.fid, spec.flabel.c_str()); + } auto style = getStyleForElement(data->type, name, (data->type != "button") ? "button" : ""); @@ -2873,6 +2882,7 @@ const std::unordered_map -// Copyright (C) 2013 Ciaran Gultnieks -// Copyright (C) 2013 teddydestodes - -#include "guiKeyChangeMenu.h" -#include "debug.h" -#include "guiButton.h" -#include -#include -#include -#include -#include -#include -#include -#include "settings.h" -#include "gettext.h" - -#include "mainmenumanager.h" // for g_gamecallback - -#define KMaxButtonPerColumns 12 - -extern MainGameCallback *g_gamecallback; - -enum -{ - GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR, - // buttons - GUI_ID_KEY_FORWARD_BUTTON, - GUI_ID_KEY_BACKWARD_BUTTON, - GUI_ID_KEY_LEFT_BUTTON, - GUI_ID_KEY_RIGHT_BUTTON, - GUI_ID_KEY_AUX1_BUTTON, - GUI_ID_KEY_FLY_BUTTON, - GUI_ID_KEY_FAST_BUTTON, - GUI_ID_KEY_JUMP_BUTTON, - GUI_ID_KEY_NOCLIP_BUTTON, - GUI_ID_KEY_PITCH_MOVE, - GUI_ID_KEY_CHAT_BUTTON, - GUI_ID_KEY_CMD_BUTTON, - GUI_ID_KEY_CMD_LOCAL_BUTTON, - GUI_ID_KEY_CONSOLE_BUTTON, - GUI_ID_KEY_SNEAK_BUTTON, - GUI_ID_KEY_DROP_BUTTON, - GUI_ID_KEY_INVENTORY_BUTTON, - GUI_ID_KEY_HOTBAR_PREV_BUTTON, - GUI_ID_KEY_HOTBAR_NEXT_BUTTON, - GUI_ID_KEY_MUTE_BUTTON, - GUI_ID_KEY_DEC_VOLUME_BUTTON, - GUI_ID_KEY_INC_VOLUME_BUTTON, - GUI_ID_KEY_RANGE_BUTTON, - GUI_ID_KEY_ZOOM_BUTTON, - GUI_ID_KEY_CAMERA_BUTTON, - GUI_ID_KEY_MINIMAP_BUTTON, - GUI_ID_KEY_SCREENSHOT_BUTTON, - GUI_ID_KEY_CHATLOG_BUTTON, - GUI_ID_KEY_BLOCK_BOUNDS_BUTTON, - GUI_ID_KEY_HUD_BUTTON, - GUI_ID_KEY_FOG_BUTTON, - GUI_ID_KEY_DEC_RANGE_BUTTON, - GUI_ID_KEY_INC_RANGE_BUTTON, - GUI_ID_KEY_AUTOFWD_BUTTON, - // other - GUI_ID_CB_AUX1_DESCENDS, - GUI_ID_CB_DOUBLETAP_JUMP, - GUI_ID_CB_AUTOJUMP, -}; - -GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, - ISimpleTextureSource *tsrc) : - GUIModalMenu(env, parent, id, menumgr), - m_tsrc(tsrc) -{ - init_keys(); -} - -GUIKeyChangeMenu::~GUIKeyChangeMenu() -{ - removeAllChildren(); - key_used_text = nullptr; - - for (key_setting *ks : key_settings) { - delete ks; - } - key_settings.clear(); -} - -void GUIKeyChangeMenu::regenerateGui(v2u32 screensize) -{ - removeAllChildren(); - key_used_text = nullptr; - - ScalingInfo info = getScalingInfo(screensize, v2u32(835, 430)); - const float s = info.scale; - DesiredRect = info.rect; - recalculateAbsolutePosition(false); - - v2s32 size = DesiredRect.getSize(); - v2s32 topleft(0, 0); - - { - core::rect rect(0, 0, 600 * s, 40 * s); - rect += topleft + v2s32(25 * s, 3 * s); - //gui::IGUIStaticText *t = - gui::StaticText::add(Environment, wstrgettext("Keybindings."), rect, - false, true, this, -1); - //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); - } - - // Build buttons - - v2s32 offset(25 * s, 60 * s); - - for(size_t i = 0; i < key_settings.size(); i++) - { - key_setting *k = key_settings.at(i); - { - core::rect rect(0, 0, 150 * s, 20 * s); - rect += topleft + v2s32(offset.X, offset.Y); - gui::StaticText::add(Environment, k->button_name, rect, - false, true, this, -1); - } - - { - core::rect rect(0, 0, 100 * s, 30 * s); - rect += topleft + v2s32(offset.X + 150 * s, offset.Y - 5 * s); - k->button = GUIButton::addButton(Environment, rect, m_tsrc, this, k->id, - wstrgettext(k->key.name()).c_str()); - } - if ((i + 1) % KMaxButtonPerColumns == 0) { - offset.X += 260 * s; - offset.Y = 60 * s; - } else { - offset += v2s32(0, 25 * s); - } - } - - { - s32 option_x = offset.X; - s32 option_y = offset.Y + 5 * s; - u32 option_w = 180 * s; - { - core::rect rect(0, 0, option_w, 30 * s); - rect += topleft + v2s32(option_x, option_y); - Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this, - GUI_ID_CB_AUX1_DESCENDS, wstrgettext("\"Aux1\" = climb down").c_str()); - } - offset += v2s32(0, 25 * s); - } - - { - s32 option_x = offset.X; - s32 option_y = offset.Y + 5 * s; - u32 option_w = 280 * s; - { - core::rect rect(0, 0, option_w, 30 * s); - rect += topleft + v2s32(option_x, option_y); - Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this, - GUI_ID_CB_DOUBLETAP_JUMP, wstrgettext("Double tap \"jump\" to toggle fly").c_str()); - } - offset += v2s32(0, 25 * s); - } - - { - s32 option_x = offset.X; - s32 option_y = offset.Y + 5 * s; - u32 option_w = 280; - { - core::rect rect(0, 0, option_w, 30 * s); - rect += topleft + v2s32(option_x, option_y); - Environment->addCheckBox(g_settings->getBool("autojump"), rect, this, - GUI_ID_CB_AUTOJUMP, wstrgettext("Automatic jumping").c_str()); - } - offset += v2s32(0, 25); - } - - { - core::rect rect(0, 0, 100 * s, 30 * s); - rect += topleft + v2s32(size.X / 2 - 105 * s, size.Y - 40 * s); - GUIButton::addButton(Environment, rect, m_tsrc, this, GUI_ID_BACK_BUTTON, - wstrgettext("Save").c_str()); - } - { - core::rect rect(0, 0, 100 * s, 30 * s); - rect += topleft + v2s32(size.X / 2 + 5 * s, size.Y - 40 * s); - GUIButton::addButton(Environment, rect, m_tsrc, this, GUI_ID_ABORT_BUTTON, - wstrgettext("Cancel").c_str()); - } -} - -void GUIKeyChangeMenu::drawMenu() -{ - gui::IGUISkin* skin = Environment->getSkin(); - if (!skin) - return; - video::IVideoDriver* driver = Environment->getVideoDriver(); - - video::SColor bgcolor(140, 0, 0, 0); - driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); - - gui::IGUIElement::draw(); -} - -bool GUIKeyChangeMenu::acceptInput() -{ - clearKeyCache(); - - for (key_setting *k : key_settings) { - std::string default_key; - Settings::getLayer(SL_DEFAULTS)->getNoEx(k->setting_name, default_key); - - if (k->key.sym() != default_key) - g_settings->set(k->setting_name, k->key.sym()); - else - g_settings->remove(k->setting_name); - } - - { - gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS); - if(e && e->getType() == gui::EGUIET_CHECK_BOX) - g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked()); - } - { - gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAP_JUMP); - if(e && e->getType() == gui::EGUIET_CHECK_BOX) - g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked()); - } - { - gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUTOJUMP); - if(e && e->getType() == gui::EGUIET_CHECK_BOX) - g_settings->setBool("autojump", ((gui::IGUICheckBox*)e)->isChecked()); - } - - g_gamecallback->signalKeyConfigChange(); - - return true; -} - -bool GUIKeyChangeMenu::resetMenu() -{ - if (active_key) { - active_key->button->setText(wstrgettext(active_key->key.name()).c_str()); - active_key = nullptr; - return false; - } - return true; -} -bool GUIKeyChangeMenu::OnEvent(const SEvent& event) -{ - if (event.EventType == EET_KEY_INPUT_EVENT && active_key - && event.KeyInput.PressedDown) { - - KeyPress kp(event.KeyInput); - - if (event.KeyInput.Key == irr::KEY_DELETE) - kp = KeyPress(""); // To erase key settings - else if (event.KeyInput.Key == irr::KEY_ESCAPE) - kp = active_key->key; // Cancel - - bool shift_went_down = false; - if(!shift_down && - (event.KeyInput.Key == irr::KEY_SHIFT || - event.KeyInput.Key == irr::KEY_LSHIFT || - event.KeyInput.Key == irr::KEY_RSHIFT)) - shift_went_down = true; - - // Display Key already in use message - bool key_in_use = false; - if (kp) { - for (key_setting *ks : key_settings) { - if (ks != active_key && ks->key == kp) { - key_in_use = true; - break; - } - } - } - - if (key_in_use && !this->key_used_text) { - core::rect rect(0, 0, 600, 40); - rect += v2s32(0, 0) + v2s32(25, 30); - this->key_used_text = gui::StaticText::add(Environment, - wstrgettext("Key already in use"), - rect, false, true, this, -1); - } else if (!key_in_use && this->key_used_text) { - this->key_used_text->remove(); - this->key_used_text = nullptr; - } - - // But go on - { - active_key->key = kp; - active_key->button->setText(wstrgettext(kp.name()).c_str()); - - // Allow characters made with shift - if (shift_went_down){ - shift_down = true; - return false; - } - - active_key = nullptr; - return true; - } - } else if (event.EventType == EET_KEY_INPUT_EVENT && !active_key - && event.KeyInput.PressedDown - && event.KeyInput.Key == irr::KEY_ESCAPE) { - quitMenu(); - return true; - } else if (event.EventType == EET_GUI_EVENT) { - if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST - && isVisible()) - { - if (!canTakeFocus(event.GUIEvent.Element)) - { - infostream << "GUIKeyChangeMenu: Not allowing focus change." - << std::endl; - // Returning true disables focus change - return true; - } - } - if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) - { - switch (event.GUIEvent.Caller->getID()) - { - case GUI_ID_BACK_BUTTON: //back - acceptInput(); - quitMenu(); - return true; - case GUI_ID_ABORT_BUTTON: //abort - quitMenu(); - return true; - default: - resetMenu(); - for (key_setting *ks : key_settings) { - if (ks->id == event.GUIEvent.Caller->getID()) { - active_key = ks; - break; - } - } - FATAL_ERROR_IF(!active_key, "Key setting not found"); - - shift_down = false; - active_key->button->setText(wstrgettext("press key").c_str()); - break; - } - Environment->setFocus(this); - } - } - return Parent ? Parent->OnEvent(event) : false; -} - -void GUIKeyChangeMenu::add_key(int id, std::wstring button_name, const std::string &setting_name) -{ - key_setting *k = new key_setting; - k->id = id; - - k->button_name = std::move(button_name); - k->setting_name = setting_name; - k->key = getKeySetting(k->setting_name.c_str()); - key_settings.push_back(k); -} - -// compare with button_titles in touchcontrols.cpp -void GUIKeyChangeMenu::init_keys() -{ - this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wstrgettext("Forward"), "keymap_forward"); - this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, wstrgettext("Backward"), "keymap_backward"); - this->add_key(GUI_ID_KEY_LEFT_BUTTON, wstrgettext("Left"), "keymap_left"); - this->add_key(GUI_ID_KEY_RIGHT_BUTTON, wstrgettext("Right"), "keymap_right"); - this->add_key(GUI_ID_KEY_AUX1_BUTTON, wstrgettext("Aux1"), "keymap_aux1"); - this->add_key(GUI_ID_KEY_JUMP_BUTTON, wstrgettext("Jump"), "keymap_jump"); - this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wstrgettext("Sneak"), "keymap_sneak"); - this->add_key(GUI_ID_KEY_DROP_BUTTON, wstrgettext("Drop"), "keymap_drop"); - this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wstrgettext("Inventory"), "keymap_inventory"); - this->add_key(GUI_ID_KEY_HOTBAR_PREV_BUTTON, wstrgettext("Prev. item"), "keymap_hotbar_previous"); - this->add_key(GUI_ID_KEY_HOTBAR_NEXT_BUTTON, wstrgettext("Next item"), "keymap_hotbar_next"); - this->add_key(GUI_ID_KEY_ZOOM_BUTTON, wstrgettext("Zoom"), "keymap_zoom"); - this->add_key(GUI_ID_KEY_CAMERA_BUTTON, wstrgettext("Change camera"), "keymap_camera_mode"); - this->add_key(GUI_ID_KEY_MINIMAP_BUTTON, wstrgettext("Toggle minimap"), "keymap_minimap"); - this->add_key(GUI_ID_KEY_FLY_BUTTON, wstrgettext("Toggle fly"), "keymap_freemove"); - this->add_key(GUI_ID_KEY_PITCH_MOVE, wstrgettext("Toggle pitchmove"), "keymap_pitchmove"); - this->add_key(GUI_ID_KEY_FAST_BUTTON, wstrgettext("Toggle fast"), "keymap_fastmove"); - this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, wstrgettext("Toggle noclip"), "keymap_noclip"); - this->add_key(GUI_ID_KEY_MUTE_BUTTON, wstrgettext("Mute"), "keymap_mute"); - this->add_key(GUI_ID_KEY_DEC_VOLUME_BUTTON, wstrgettext("Dec. volume"), "keymap_decrease_volume"); - this->add_key(GUI_ID_KEY_INC_VOLUME_BUTTON, wstrgettext("Inc. volume"), "keymap_increase_volume"); - this->add_key(GUI_ID_KEY_AUTOFWD_BUTTON, wstrgettext("Autoforward"), "keymap_autoforward"); - this->add_key(GUI_ID_KEY_CHAT_BUTTON, wstrgettext("Chat"), "keymap_chat"); - this->add_key(GUI_ID_KEY_SCREENSHOT_BUTTON, wstrgettext("Screenshot"), "keymap_screenshot"); - this->add_key(GUI_ID_KEY_RANGE_BUTTON, wstrgettext("Range select"), "keymap_rangeselect"); - this->add_key(GUI_ID_KEY_DEC_RANGE_BUTTON, wstrgettext("Dec. range"), "keymap_decrease_viewing_range_min"); - this->add_key(GUI_ID_KEY_INC_RANGE_BUTTON, wstrgettext("Inc. range"), "keymap_increase_viewing_range_min"); - this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, wstrgettext("Console"), "keymap_console"); - this->add_key(GUI_ID_KEY_CMD_BUTTON, wstrgettext("Command"), "keymap_cmd"); - this->add_key(GUI_ID_KEY_CMD_LOCAL_BUTTON, wstrgettext("Local command"), "keymap_cmd_local"); - this->add_key(GUI_ID_KEY_BLOCK_BOUNDS_BUTTON, wstrgettext("Block bounds"), "keymap_toggle_block_bounds"); - this->add_key(GUI_ID_KEY_HUD_BUTTON, wstrgettext("Toggle HUD"), "keymap_toggle_hud"); - this->add_key(GUI_ID_KEY_CHATLOG_BUTTON, wstrgettext("Toggle chat log"), "keymap_toggle_chat"); - this->add_key(GUI_ID_KEY_FOG_BUTTON, wstrgettext("Toggle fog"), "keymap_toggle_fog"); -} diff --git a/src/gui/guiKeyChangeMenu.h b/src/gui/guiKeyChangeMenu.h deleted file mode 100644 index c858b2c93..000000000 --- a/src/gui/guiKeyChangeMenu.h +++ /dev/null @@ -1,63 +0,0 @@ -// Luanti -// SPDX-License-Identifier: LGPL-2.1-or-later -// Copyright (C) 2010-2013 celeron55, Perttu Ahola -// Copyright (C) 2013 Ciaran Gultnieks -// Copyright (C) 2013 teddydestodes - -#pragma once - -#include "modalMenu.h" -#include "client/keycode.h" -#include -#include -#include - -class ISimpleTextureSource; - -struct key_setting -{ - int id; - std::wstring button_name; - KeyPress key; - std::string setting_name; - gui::IGUIButton *button; -}; - -class GUIKeyChangeMenu : public GUIModalMenu -{ -public: - GUIKeyChangeMenu(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, - IMenuManager *menumgr, ISimpleTextureSource *tsrc); - ~GUIKeyChangeMenu(); - - /* - Remove and re-add (or reposition) stuff - */ - void regenerateGui(v2u32 screensize); - - void drawMenu(); - - bool acceptInput(); - - bool OnEvent(const SEvent &event); - - bool pausesGame() { return true; } - -protected: - std::wstring getLabelByID(s32 id) { return L""; } - std::string getNameByID(s32 id) { return ""; } - -private: - void init_keys(); - - bool resetMenu(); - - void add_key(int id, std::wstring button_name, const std::string &setting_name); - - bool shift_down = false; - - key_setting *active_key = nullptr; - gui::IGUIStaticText *key_used_text = nullptr; - std::vector key_settings; - ISimpleTextureSource *m_tsrc; -}; diff --git a/src/gui/mainmenumanager.h b/src/gui/mainmenumanager.h index 2ac00fee7..9b5bea5f7 100644 --- a/src/gui/mainmenumanager.h +++ b/src/gui/mainmenumanager.h @@ -22,12 +22,10 @@ class IGameCallback public: virtual void exitToOS() = 0; virtual void openSettings() = 0; - virtual void keyConfig() = 0; virtual void disconnect() = 0; virtual void changePassword() = 0; virtual void changeVolume() = 0; virtual void showOpenURLDialog(const std::string &url) = 0; - virtual void signalKeyConfigChange() = 0; virtual void touchscreenLayout() = 0; }; @@ -136,16 +134,6 @@ public: changevolume_requested = true; } - void keyConfig() override - { - keyconfig_requested = true; - } - - void signalKeyConfigChange() override - { - keyconfig_changed = true; - } - void touchscreenLayout() override { touchscreenlayout_requested = true; @@ -160,10 +148,8 @@ public: bool settings_requested = false; bool changepassword_requested = false; bool changevolume_requested = false; - bool keyconfig_requested = false; bool touchscreenlayout_requested = false; bool shutdown_requested = false; - bool keyconfig_changed = false; std::string show_open_url_dialog = ""; }; diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 240927a4a..3d096e018 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -9,7 +9,6 @@ #include "scripting_mainmenu.h" #include "gui/guiEngine.h" #include "gui/guiMainMenu.h" -#include "gui/guiKeyChangeMenu.h" #include "gui/guiPathSelectMenu.h" #include "gui/touchscreeneditor.h" #include "version.h" @@ -538,22 +537,6 @@ int ModApiMainMenu::l_get_content_translation(lua_State *L) return 1; } -/******************************************************************************/ -int ModApiMainMenu::l_show_keys_menu(lua_State *L) -{ - GUIEngine *engine = getGuiEngine(L); - sanity_check(engine != NULL); - - GUIKeyChangeMenu *kmenu = new GUIKeyChangeMenu( - engine->m_rendering_engine->get_gui_env(), - engine->m_parent, - -1, - engine->m_menumanager, - engine->m_texture_source.get()); - kmenu->drop(); - return 0; -} - /******************************************************************************/ int ModApiMainMenu::l_show_touchscreen_layout(lua_State *L) { @@ -1070,7 +1053,6 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_content_translation); API_FCT(start); API_FCT(close); - API_FCT(show_keys_menu); API_FCT(show_touchscreen_layout); API_FCT(create_world); API_FCT(delete_world); diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 63f45d74b..fc2d90af8 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -65,8 +65,6 @@ private: //gui - static int l_show_keys_menu(lua_State *L); - static int l_show_touchscreen_layout(lua_State *L); static int l_show_path_select_dialog(lua_State *L); diff --git a/src/script/lua_api/l_menu_common.cpp b/src/script/lua_api/l_menu_common.cpp index 19c97c042..8b3ffda4e 100644 --- a/src/script/lua_api/l_menu_common.cpp +++ b/src/script/lua_api/l_menu_common.cpp @@ -35,11 +35,21 @@ int ModApiMenuCommon::l_irrlicht_device_supports_touch(lua_State *L) } +int ModApiMenuCommon::l_are_keycodes_equal(lua_State *L) +{ + auto k1 = luaL_checkstring(L, 1); + auto k2 = luaL_checkstring(L, 2); + lua_pushboolean(L, KeyPress(k1) == KeyPress(k2)); + return 1; +} + + void ModApiMenuCommon::Initialize(lua_State *L, int top) { API_FCT(gettext); API_FCT(get_active_driver); API_FCT(irrlicht_device_supports_touch); + API_FCT(are_keycodes_equal); } diff --git a/src/script/lua_api/l_menu_common.h b/src/script/lua_api/l_menu_common.h index e94e562e1..8cbd58f11 100644 --- a/src/script/lua_api/l_menu_common.h +++ b/src/script/lua_api/l_menu_common.h @@ -13,6 +13,7 @@ private: static int l_gettext(lua_State *L); static int l_get_active_driver(lua_State *L); static int l_irrlicht_device_supports_touch(lua_State *L); + static int l_are_keycodes_equal(lua_State *L); public: static void Initialize(lua_State *L, int top); diff --git a/src/script/lua_api/l_pause_menu.cpp b/src/script/lua_api/l_pause_menu.cpp index c2a9a81e5..b1aaae185 100644 --- a/src/script/lua_api/l_pause_menu.cpp +++ b/src/script/lua_api/l_pause_menu.cpp @@ -3,18 +3,12 @@ // Copyright (C) 2025 grorp #include "l_pause_menu.h" +#include "client/keycode.h" #include "gui/mainmenumanager.h" #include "lua_api/l_internal.h" #include "client/client.h" -int ModApiPauseMenu::l_show_keys_menu(lua_State *L) -{ - g_gamecallback->keyConfig(); - return 0; -} - - int ModApiPauseMenu::l_show_touchscreen_layout(lua_State *L) { g_gamecallback->touchscreenLayout(); @@ -31,7 +25,6 @@ int ModApiPauseMenu::l_is_internal_server(lua_State *L) void ModApiPauseMenu::Initialize(lua_State *L, int top) { - API_FCT(show_keys_menu); API_FCT(show_touchscreen_layout); API_FCT(is_internal_server); } diff --git a/src/script/lua_api/l_pause_menu.h b/src/script/lua_api/l_pause_menu.h index 2d7eb62d7..8bb6fe8c3 100644 --- a/src/script/lua_api/l_pause_menu.h +++ b/src/script/lua_api/l_pause_menu.h @@ -9,7 +9,6 @@ class ModApiPauseMenu: public ModApiBase { private: - static int l_show_keys_menu(lua_State *L); static int l_show_touchscreen_layout(lua_State *L); static int l_is_internal_server(lua_State *L);