From 553fbe8f85877693498fa5719e02a498ff0614b9 Mon Sep 17 00:00:00 2001 From: dP Date: Tue, 6 Sep 2022 22:51:05 +0300 Subject: [PATCH] Add: Allow to configure modifier keys --- src/gfx_type.h | 7 +++++ src/lang/english.txt | 12 ++++++++ src/settings_gui.cpp | 3 ++ src/settings_table.cpp | 27 +++++++++++++++++ src/settings_type.h | 4 +++ src/table/settings/gui_settings.ini | 45 +++++++++++++++++++++++++++++ src/window.cpp | 26 ++++++++++++++--- 7 files changed, 120 insertions(+), 4 deletions(-) diff --git a/src/gfx_type.h b/src/gfx_type.h index fbedceb87c..5d28015ace 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -351,4 +351,11 @@ enum StringAlignment { }; DECLARE_ENUM_AS_BIT_SET(StringAlignment) +enum ModifierKey : byte { + None = 0, ///< No key configured + Shift = 1, ///< Shift key + Ctrl = 2, ///< Ctrl key + Alt = 3, ///< Alt key +}; + #endif /* GFX_TYPE_H */ diff --git a/src/lang/english.txt b/src/lang/english.txt index c6b6af7c2b..d04c47e989 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1766,6 +1766,18 @@ STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL :{NUM}% normal g ###setting-zero-is-special STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_ZERO :No limit (as fast as your computer allows) +STR_CONFIG_SETTING_MODIFIER_FN :Function modifier key: {STRING2} +STR_CONFIG_SETTING_MODIFIER_FN_HELPTEXT :Modifier key for accessing additional functions. +STR_CONFIG_SETTING_MODIFIER_REMOVE :Remove modifier key: {STRING2} +STR_CONFIG_SETTING_MODIFIER_REMOVE_HELPTEXT :Modifier key for removal mode on building tools. +STR_CONFIG_SETTING_MODIFIER_ESTIMATE :Estimate modifier key: {STRING2} +STR_CONFIG_SETTING_MODIFIER_ESTIMATE_HELPTEXT :Modifier key for estimating action cost. +STR_CONFIG_SETTING_MODIFIER_NONE :None +STR_CONFIG_SETTING_MODIFIER_SHIFT :Shift +STR_CONFIG_SETTING_MODIFIER_CTRL :Ctrl +STR_CONFIG_SETTING_MODIFIER_ALT :Alt +STR_CONFIG_SETTING_MODIFIER_ALREADY_IN_USE :{WHITE}This modifier key is already in use. + STR_CONFIG_SETTING_SOUND_TICKER :News ticker: {STRING2} STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT :Play sound for summarised news messages diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index bfd59e43bb..8d51e24137 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2041,6 +2041,9 @@ static SettingsContainer &GetSettingsTree() interface->Add(new SettingEntry("gui.timetable_arrival_departure")); interface->Add(new SettingEntry("gui.show_newgrf_name")); interface->Add(new SettingEntry("gui.show_cargo_in_vehicle_lists")); + viewports->Add(new SettingEntry("gui.fn_modifier")); + viewports->Add(new SettingEntry("gui.remove_modifier")); + viewports->Add(new SettingEntry("gui.estimate_modifier")); } SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS)); diff --git a/src/settings_table.cpp b/src/settings_table.cpp index 224f9a1174..360210a556 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -483,6 +483,33 @@ static bool CheckMaxHeightLevel(int32_t &new_value) return true; } +static bool CheckModifier(int32_t new_value, ModifierKey other1, ModifierKey other2) +{ + ModifierKey key = (ModifierKey)new_value; + if (key == ModifierKey::None) return true; + if (other1 == key || other2 == key) { + ShowErrorMessage(STR_CONFIG_SETTING_MODIFIER_ALREADY_IN_USE, INVALID_STRING_ID, WL_ERROR); + return false; + } + + return true; +} + +static bool CheckFnModifier(int32_t &new_value) +{ + return CheckModifier(new_value, _settings_client.gui.remove_modifier, _settings_client.gui.estimate_modifier); +} + +static bool CheckRemoveModifier(int32_t &new_value) +{ + return CheckModifier(new_value, _settings_client.gui.fn_modifier, _settings_client.gui.estimate_modifier); +} + +static bool CheckEstimateModifier(int32_t &new_value) +{ + return CheckModifier(new_value, _settings_client.gui.fn_modifier, _settings_client.gui.remove_modifier); +} + static void StationCatchmentChanged(int32_t) { Station::RecomputeCatchmentForAll(); diff --git a/src/settings_type.h b/src/settings_type.h index e9c6a60038..22a6b9efd5 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -23,6 +23,7 @@ #include "rail_gui.h" #include "signal_type.h" #include "timetable.h" +#include "gfx_type.h" /* Used to validate sizes of "max" value in settings. */ const size_t MAX_SLE_UINT8 = UINT8_MAX; @@ -220,6 +221,9 @@ struct GUISettings { uint8_t newgrf_default_palette; ///< default palette to use for NewGRFs without action 14 palette information bool scale_bevels; ///< bevels are scaled with GUI scale. + ModifierKey fn_modifier; ///< function modifier key + ModifierKey remove_modifier; ///< remove modifier key + ModifierKey estimate_modifier; ///< estimate modifier key /** * Returns true when the user has sufficient privileges to edit newgrfs on a running game diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini index 5cc1c3ecdb..5f82c64580 100644 --- a/src/table/settings/gui_settings.ini +++ b/src/table/settings/gui_settings.ini @@ -16,10 +16,14 @@ static void InvalidateCompanyLiveryWindow(int32_t new_value); static void InvalidateNewGRFChangeWindows(int32_t new_value); static void ZoomMinMaxChanged(int32_t new_value); static void SpriteZoomMinChanged(int32_t new_value); +static bool CheckFnModifier(int32_t &new_value); +static bool CheckRemoveModifier(int32_t &new_value); +static bool CheckEstimateModifier(int32_t &new_value); static constexpr std::initializer_list _osk_activation{"disabled", "double", "single", "immediately"}; static constexpr std::initializer_list _savegame_date{"long", "short", "iso"}; static constexpr std::initializer_list _right_click_close{"no", "yes", "except sticky"}; +static constexpr std::initializer_list _mod_keys{"none", "shift", "ctrl", "alt"}; static const SettingVariant _gui_settings_table[] = { [post-amble] @@ -903,3 +907,44 @@ post_cb = [](auto) { SetupWidgetDimensions(); ReInitAllWindows(true); } cat = SC_BASIC startup = true +[SDTC_OMANY] +var = gui.fn_modifier +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +full = _mod_keys +def = 2 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_MODIFIER_FN +strhelp = STR_CONFIG_SETTING_MODIFIER_FN_HELPTEXT +strval = STR_CONFIG_SETTING_MODIFIER_NONE +pre_cb = CheckFnModifier +cat = SC_ADVANCED + +[SDTC_OMANY] +var = gui.remove_modifier +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +full = _mod_keys +def = 3 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_MODIFIER_REMOVE +strhelp = STR_CONFIG_SETTING_MODIFIER_REMOVE_HELPTEXT +strval = STR_CONFIG_SETTING_MODIFIER_NONE +pre_cb = CheckRemoveModifier +cat = SC_ADVANCED + +[SDTC_OMANY] +var = gui.estimate_modifier +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +full = _mod_keys +def = 1 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_MODIFIER_ESTIMATE +strhelp = STR_CONFIG_SETTING_MODIFIER_ESTIMATE_HELPTEXT +strval = STR_CONFIG_SETTING_MODIFIER_NONE +pre_cb = CheckEstimateModifier +cat = SC_ADVANCED diff --git a/src/window.cpp b/src/window.cpp index ae8315bf2c..40f59eadb7 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2613,6 +2613,25 @@ void HandleKeypress(uint keycode, char32_t key) HandleGlobalHotkeys(key, keycode); } +/** + * Select the right state for the requested modifier key. + */ +static bool SelectModifierKey(ModifierKey key, bool shift_pressed, bool ctrl_pressed, bool alt_pressed) +{ + switch (key) { + case ModifierKey::None: + return false; + case ModifierKey::Shift: + return shift_pressed; + case ModifierKey::Ctrl: + return ctrl_pressed; + case ModifierKey::Alt: + return alt_pressed; + default: + NOT_REACHED(); + } +} + /** * Handle the modifier key state changes. */ @@ -2623,10 +2642,9 @@ void HandleModifierKeys(bool shift_pressed, bool ctrl_pressed, bool alt_pressed) _shift_pressed = shift_pressed; - /* Hardwire modifier keys. */ - _fn_pressed = ctrl_pressed; - _remove_pressed = alt_pressed; - _estimate_pressed = shift_pressed; + _fn_pressed = SelectModifierKey(_settings_client.gui.fn_modifier, shift_pressed, ctrl_pressed, alt_pressed); + _remove_pressed = SelectModifierKey(_settings_client.gui.remove_modifier, shift_pressed, ctrl_pressed, alt_pressed); + _estimate_pressed = SelectModifierKey(_settings_client.gui.estimate_modifier, shift_pressed, ctrl_pressed, alt_pressed); if (old_fn_pressed != _fn_pressed) { /* Call the event, start with the uppermost window. */