From 2b197d0fb2037f2e8fcfcc0a1527fdb5831a181d Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 17 Jan 2021 16:11:52 +0000 Subject: [PATCH] Fix parsing of shortcuts --- src/openrct2-ui/input/InputManager.cpp | 13 ++-- src/openrct2-ui/input/ShortcutInput.cpp | 75 ++++++++++++++++++----- src/openrct2-ui/input/ShortcutManager.cpp | 7 ++- src/openrct2-ui/input/ShortcutManager.h | 1 + src/openrct2-ui/input/Shortcuts.cpp | 28 ++++----- src/openrct2-ui/windows/ShortcutKeys.cpp | 10 ++- src/openrct2/core/String.cpp | 31 ++-------- src/openrct2/core/String.hpp | 16 ++++- 8 files changed, 118 insertions(+), 63 deletions(-) diff --git a/src/openrct2-ui/input/InputManager.cpp b/src/openrct2-ui/input/InputManager.cpp index 173bd6f872..e3d9174dd5 100644 --- a/src/openrct2-ui/input/InputManager.cpp +++ b/src/openrct2-ui/input/InputManager.cpp @@ -287,10 +287,15 @@ void InputManager::ProcessHoldEvents() // Check view scroll shortcuts _viewScroll.x = 0; _viewScroll.y = 0; - ProcessViewScrollEvent(ShortcutId::ScrollUp, { 0, -1 }); - ProcessViewScrollEvent(ShortcutId::ScrollDown, { 0, 1 }); - ProcessViewScrollEvent(ShortcutId::ScrollLeft, { -1, 0 }); - ProcessViewScrollEvent(ShortcutId::ScrollRight, { 1, 0 }); + + auto& shortcutManager = GetShortcutManager(); + if (!shortcutManager.IsPendingShortcutChange()) + { + ProcessViewScrollEvent(ShortcutId::ScrollUp, { 0, -1 }); + ProcessViewScrollEvent(ShortcutId::ScrollDown, { 0, 1 }); + ProcessViewScrollEvent(ShortcutId::ScrollLeft, { -1, 0 }); + ProcessViewScrollEvent(ShortcutId::ScrollRight, { 1, 0 }); + } } void InputManager::ProcessViewScrollEvent(std::string_view shortcutId, const ScreenCoordsXY& delta) diff --git a/src/openrct2-ui/input/ShortcutInput.cpp b/src/openrct2-ui/input/ShortcutInput.cpp index 46bca04961..a392628046 100644 --- a/src/openrct2-ui/input/ShortcutInput.cpp +++ b/src/openrct2-ui/input/ShortcutInput.cpp @@ -116,28 +116,75 @@ ShortcutInput::ShortcutInput(const std::string_view& value) index = sepIndex + 1; sepIndex = FindPlus(value, index); } + auto rem = value.substr(index); - auto kind = InputDeviceKind::Keyboard; - auto button = 0u; - auto colonIndex = value.find(':', index); - if (colonIndex != std::string::npos) + if (String::StartsWith(rem, "JOY ", true)) { - auto device = value.substr(index, colonIndex - index); - if (device == "MOUSE") + rem = rem.substr(4); + if (String::Equals(rem, "LEFT")) { - auto rem = std::string(value.substr(colonIndex + 1)); - kind = InputDeviceKind::Mouse; - button = atoi(rem.c_str()); + Kind = InputDeviceKind::JoyHat; + Modifiers = modifiers; + Button = SDL_HAT_LEFT; } + else if (String::Equals(rem, "RIGHT")) + { + Kind = InputDeviceKind::JoyHat; + Modifiers = modifiers; + Button = SDL_HAT_RIGHT; + } + else if (String::Equals(rem, "UP")) + { + Kind = InputDeviceKind::JoyHat; + Modifiers = modifiers; + Button = SDL_HAT_UP; + } + else if (String::Equals(rem, "DOWN")) + { + Kind = InputDeviceKind::JoyHat; + Modifiers = modifiers; + Button = SDL_HAT_DOWN; + } + else + { + auto number = String::Parse(rem); + if (number) + { + Kind = InputDeviceKind::JoyButton; + Modifiers = modifiers; + Button = *number - 1; + } + } + } + else if (String::StartsWith(rem, "MOUSE ", true)) + { + rem = rem.substr(6); + auto number = String::Parse(rem); + if (number) + { + Kind = InputDeviceKind::Mouse; + Modifiers = modifiers; + Button = *number - 1; + } + } + else if (String::Equals(rem, "LMB", true)) + { + Kind = InputDeviceKind::Mouse; + Modifiers = modifiers; + Button = 0; + } + else if (String::Equals(rem, "RMB", true)) + { + Kind = InputDeviceKind::Mouse; + Modifiers = modifiers; + Button = 1; } else { - button = ParseKey(value.substr(index)); + Kind = InputDeviceKind::Keyboard; + Modifiers = modifiers; + Button = ParseKey(rem); } - - Kind = kind; - Modifiers = modifiers; - Button = button; } std::string ShortcutInput::ToString() const diff --git a/src/openrct2-ui/input/ShortcutManager.cpp b/src/openrct2-ui/input/ShortcutManager.cpp index cc12f9c222..46cfa2f602 100644 --- a/src/openrct2-ui/input/ShortcutManager.cpp +++ b/src/openrct2-ui/input/ShortcutManager.cpp @@ -134,6 +134,11 @@ void ShortcutManager::RemoveShortcut(std::string_view id) Shortcuts.begin(), Shortcuts.end(), [id](const RegisteredShortcut& shortcut) { return shortcut.Id == id; })); } +bool ShortcutManager::IsPendingShortcutChange() const +{ + return !_pendingShortcutChange.empty(); +} + void ShortcutManager::SetPendingShortcutChange(std::string_view id) { _pendingShortcutChange = id; @@ -141,7 +146,7 @@ void ShortcutManager::SetPendingShortcutChange(std::string_view id) void ShortcutManager::ProcessEvent(const InputEvent& e) { - if (_pendingShortcutChange.empty()) + if (!IsPendingShortcutChange()) { for (const auto& shortcut : Shortcuts) { diff --git a/src/openrct2-ui/input/ShortcutManager.h b/src/openrct2-ui/input/ShortcutManager.h index d058d3e88e..78c9e4acf2 100644 --- a/src/openrct2-ui/input/ShortcutManager.h +++ b/src/openrct2-ui/input/ShortcutManager.h @@ -131,6 +131,7 @@ namespace OpenRCT2::Ui void RegisterDefaultShortcuts(); RegisteredShortcut* GetShortcut(std::string_view id); void RemoveShortcut(std::string_view id); + bool IsPendingShortcutChange() const; void SetPendingShortcutChange(std::string_view id); void ProcessEvent(const InputEvent& e); bool ProcessEventForSpecificShortcut(const InputEvent& e, std::string_view id); diff --git a/src/openrct2-ui/input/Shortcuts.cpp b/src/openrct2-ui/input/Shortcuts.cpp index 333e3512a8..5971bd5668 100644 --- a/src/openrct2-ui/input/Shortcuts.cpp +++ b/src/openrct2-ui/input/Shortcuts.cpp @@ -674,8 +674,8 @@ void ShortcutManager::RegisterDefaultShortcuts() // Interface 3 RegisterShortcut(ShortcutId::InterfaceZoomOut, STR_SHORTCUT_ZOOM_VIEW_OUT, "PAGEUP", []() { main_window_zoom(false, false); }); RegisterShortcut(ShortcutId::InterfaceZoomIn, STR_SHORTCUT_ZOOM_VIEW_IN, "PAGEDOWN", []() { main_window_zoom(true, false); }); - RegisterShortcut(ShortcutId::InterfaceRotateClockwise, STR_SHORTCUT_ROTATE_VIEW_CLOCKWISE, "RETURN", "MOUSE:5", []() { RotateCamera(1); }); - RegisterShortcut(ShortcutId::InterfaceRotateAnticlockwise, STR_SHORTCUT_ROTATE_VIEW_ANTICLOCKWISE, "SHIFT+RETURN", "MOUSE:4", []() { RotateCamera(-1); }); + RegisterShortcut(ShortcutId::InterfaceRotateClockwise, STR_SHORTCUT_ROTATE_VIEW_CLOCKWISE, "RETURN", "MOUSE 6", []() { RotateCamera(1); }); + RegisterShortcut(ShortcutId::InterfaceRotateAnticlockwise, STR_SHORTCUT_ROTATE_VIEW_ANTICLOCKWISE, "SHIFT+RETURN", "MOUSE 5", []() { RotateCamera(-1); }); RegisterShortcut(ShortcutId::InterfaceOpenMap, STR_SHORTCUT_TOGGLE_CLEARANCE_CHECKS, "TAB", []() { ShortcutShowMap(); }); // Interface 4 @@ -746,18 +746,18 @@ void ShortcutManager::RegisterDefaultShortcuts() RegisterShortcut(ShortcutId::InterfaceScaleDecrease, STR_SHORTCUT_SCALE_DOWN, []() { ShortcutScaleDown(); }); // Ride construction - RegisterShortcut(ShortcutId::WindowRideConstructionTurnLeft, STR_SHORTCUT_RIDE_CONSTRUCTION_TURN_LEFT, "KEYPAD 4", []() { window_ride_construction_keyboard_shortcut_turn_left(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionTurnRight, STR_SHORTCUT_RIDE_CONSTRUCTION_TURN_RIGHT, "KEYPAD 6", []() { window_ride_construction_keyboard_shortcut_turn_right(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionDefault, STR_SHORTCUT_RIDE_CONSTRUCTION_USE_TRACK_DEFAULT, "KEYPAD 5", []() { window_ride_construction_keyboard_shortcut_use_track_default(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionSlopeDown, STR_SHORTCUT_RIDE_CONSTRUCTION_SLOPE_DOWN, "KEYPAD 2", []() { window_ride_construction_keyboard_shortcut_slope_down(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionSlopeUp, STR_SHORTCUT_RIDE_CONSTRUCTION_SLOPE_UP, "KEYPAD 8", []() { window_ride_construction_keyboard_shortcut_slope_up(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionChainLift, STR_SHORTCUT_RIDE_CONSTRUCTION_CHAIN_LIFT_TOGGLE, "KEYPAD +", []() { window_ride_construction_keyboard_shortcut_chain_lift_toggle(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionBankLeft, STR_SHORTCUT_RIDE_CONSTRUCTION_BANK_LEFT, "KEYPAD 1", []() { window_ride_construction_keyboard_shortcut_bank_left(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionBankRight, STR_SHORTCUT_RIDE_CONSTRUCTION_BANK_RIGHT, "KEYPAD 3", []() { window_ride_construction_keyboard_shortcut_bank_right(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionPrevious, STR_SHORTCUT_RIDE_CONSTRUCTION_PREVIOUS_TRACK, "KEYPAD 7", []() { window_ride_construction_keyboard_shortcut_previous_track(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionNext, STR_SHORTCUT_RIDE_CONSTRUCTION_NEXT_TRACK, "KEYPAD 9", []() { window_ride_construction_keyboard_shortcut_next_track(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionBuild, STR_SHORTCUT_RIDE_CONSTRUCTION_BUILD_CURRENT, "KEYPAD 0", []() { window_ride_construction_keyboard_shortcut_build_current(); }); - RegisterShortcut(ShortcutId::WindowRideConstructionDemolish, STR_SHORTCUT_RIDE_CONSTRUCTION_DEMOLISH_CURRENT, "KEYPAD -", []() { window_ride_construction_keyboard_shortcut_demolish_current(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionTurnLeft, STR_SHORTCUT_RIDE_CONSTRUCTION_TURN_LEFT, "NUMPAD 4", []() { window_ride_construction_keyboard_shortcut_turn_left(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionTurnRight, STR_SHORTCUT_RIDE_CONSTRUCTION_TURN_RIGHT, "NUMPAD 6", []() { window_ride_construction_keyboard_shortcut_turn_right(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionDefault, STR_SHORTCUT_RIDE_CONSTRUCTION_USE_TRACK_DEFAULT, "NUMPAD 5", []() { window_ride_construction_keyboard_shortcut_use_track_default(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionSlopeDown, STR_SHORTCUT_RIDE_CONSTRUCTION_SLOPE_DOWN, "NUMPAD 2", []() { window_ride_construction_keyboard_shortcut_slope_down(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionSlopeUp, STR_SHORTCUT_RIDE_CONSTRUCTION_SLOPE_UP, "NUMPAD 8", []() { window_ride_construction_keyboard_shortcut_slope_up(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionChainLift, STR_SHORTCUT_RIDE_CONSTRUCTION_CHAIN_LIFT_TOGGLE, "NUMPAD +", []() { window_ride_construction_keyboard_shortcut_chain_lift_toggle(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionBankLeft, STR_SHORTCUT_RIDE_CONSTRUCTION_BANK_LEFT, "NUMPAD 1", []() { window_ride_construction_keyboard_shortcut_bank_left(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionBankRight, STR_SHORTCUT_RIDE_CONSTRUCTION_BANK_RIGHT, "NUMPAD 3", []() { window_ride_construction_keyboard_shortcut_bank_right(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionPrevious, STR_SHORTCUT_RIDE_CONSTRUCTION_PREVIOUS_TRACK, "NUMPAD 7", []() { window_ride_construction_keyboard_shortcut_previous_track(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionNext, STR_SHORTCUT_RIDE_CONSTRUCTION_NEXT_TRACK, "NUMPAD 9", []() { window_ride_construction_keyboard_shortcut_next_track(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionBuild, STR_SHORTCUT_RIDE_CONSTRUCTION_BUILD_CURRENT, "NUMPAD 0", []() { window_ride_construction_keyboard_shortcut_build_current(); }); + RegisterShortcut(ShortcutId::WindowRideConstructionDemolish, STR_SHORTCUT_RIDE_CONSTRUCTION_DEMOLISH_CURRENT, "NUMPAD -", []() { window_ride_construction_keyboard_shortcut_demolish_current(); }); // Tile inspector RegisterShortcut(ShortcutId::InterfaceOpenTileInspector, STR_SHORTCUT_OPEN_TILE_INSPECTOR, []() { diff --git a/src/openrct2-ui/windows/ShortcutKeys.cpp b/src/openrct2-ui/windows/ShortcutKeys.cpp index 0394a4a9b9..1cd7935248 100644 --- a/src/openrct2-ui/windows/ShortcutKeys.cpp +++ b/src/openrct2-ui/windows/ShortcutKeys.cpp @@ -231,7 +231,14 @@ public: ScreenSize OnScrollGetSize(int32_t scrollIndex) override { - return { 0, static_cast(_list.size() * SCROLLABLE_ROW_HEIGHT) }; + auto h = static_cast(_list.size() * SCROLLABLE_ROW_HEIGHT); + auto bottom = std::max(0, h - widgets[WIDX_SCROLL].bottom + widgets[WIDX_SCROLL].top + 21); + if (bottom < scrolls[0].v_top) + { + scrolls[0].v_top = bottom; + Invalidate(); + } + return { 0, h }; } void OnScrollMouseOver(int32_t scrollIndex, const ScreenCoordsXY& screenCoords) override @@ -363,7 +370,6 @@ private: index++; } - WindowInitScrollWidgets(this); Invalidate(); } diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index 96d26cf746..9f394be4f1 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -254,35 +254,14 @@ namespace String } } - bool StartsWith(const utf8* str, const utf8* match, bool ignoreCase) + bool StartsWith(std::string_view str, std::string_view match, bool ignoreCase) { - if (ignoreCase) + if (str.size() >= match.size()) { - while (*match != '\0') - { - if (*str == '\0' || tolower(*str++) != tolower(*match++)) - { - return false; - } - } - return true; + auto view = str.substr(0, match.size()); + return Equals(view, match, ignoreCase); } - else - { - while (*match != '\0') - { - if (*str == '\0' || *str++ != *match++) - { - return false; - } - } - return true; - } - } - - bool StartsWith(const std::string& str, const std::string& match, bool ignoreCase) - { - return StartsWith(str.c_str(), match.c_str(), ignoreCase); + return false; } bool EndsWith(std::string_view str, std::string_view match, bool ignoreCase) diff --git a/src/openrct2/core/String.hpp b/src/openrct2/core/String.hpp index e6388d527b..8d2ab02462 100644 --- a/src/openrct2/core/String.hpp +++ b/src/openrct2/core/String.hpp @@ -11,8 +11,10 @@ #include "../common.h" +#include #include #include +#include #include #include @@ -51,8 +53,7 @@ namespace String bool Equals(std::string_view a, std::string_view b, bool ignoreCase = false); bool Equals(const std::string& a, const std::string& b, bool ignoreCase = false); bool Equals(const utf8* a, const utf8* b, bool ignoreCase = false); - bool StartsWith(const utf8* str, const utf8* match, bool ignoreCase = false); - bool StartsWith(const std::string& str, const std::string& match, bool ignoreCase = false); + bool StartsWith(std::string_view str, std::string_view match, bool ignoreCase = false); bool EndsWith(std::string_view str, std::string_view match, bool ignoreCase = false); size_t IndexOf(const utf8* str, utf8 match, size_t startIndex = 0); ptrdiff_t LastIndexOf(const utf8* str, utf8 match); @@ -118,6 +119,17 @@ namespace String * Returns an uppercased version of a UTF-8 string. */ std::string ToUpper(std::string_view src); + + template std::optional Parse(std::string_view input) + { + T out; + const std::from_chars_result result = std::from_chars(input.data(), input.data() + input.size(), out); + if (result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range) + { + return std::nullopt; + } + return out; + } } // namespace String class CodepointView