mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
Refactor some code into more files
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "InputManager.h"
|
||||
|
||||
#include "ShortcutIds.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <openrct2-ui/UiContext.h>
|
||||
#include <openrct2-ui/input/ShortcutManager.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "KeyboardShortcuts.h"
|
||||
#include "ShortcutIds.h"
|
||||
#include "ShortcutManager.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
114
src/openrct2-ui/input/ShortcutIds.h
Normal file
114
src/openrct2-ui/input/ShortcutIds.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2021 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace OpenRCT2::Ui::ShortcutId
|
||||
{
|
||||
// Interface / general
|
||||
constexpr const char* InterfaceCloseTop = "interface.general.close_top";
|
||||
constexpr const char* InterfaceCloseAll = "interface.general.close_all";
|
||||
constexpr const char* InterfaceCancelConstruction = "interface.general.cancel_construction";
|
||||
constexpr const char* InterfacePause = "interface.general.pause";
|
||||
constexpr const char* InterfaceZoomOut = "interface.general.zoom_out";
|
||||
constexpr const char* InterfaceZoomIn = "interface.general.zoom_in";
|
||||
constexpr const char* InterfaceRotateClockwise = "interface.general.rotate_clockwise";
|
||||
constexpr const char* InterfaceRotateAnticlockwise = "interface.general.rotate_anticlockwise";
|
||||
constexpr const char* InterfaceRotateConstruction = "interface.general.rotate_construction";
|
||||
constexpr const char* InterfaceDecreaseSpeed = "interface.misc.decrease_speed";
|
||||
constexpr const char* InterfaceIncreaseSpeed = "interface.misc.increase_speed";
|
||||
constexpr const char* InterfaceToggleToolbars = "interface.misc.toggle_toolbars";
|
||||
constexpr const char* InterfaceScreenshot = "interface.misc.screenshot";
|
||||
constexpr const char* InterfaceLoadGame = "interface.misc.load_game";
|
||||
constexpr const char* InterfaceSaveGame = "interface.misc.save_game";
|
||||
constexpr const char* InterfaceMute = "interface.misc.mute";
|
||||
constexpr const char* InterfaceSceneryPicker = "interface.misc.scenery_picker";
|
||||
constexpr const char* InterfaceDisableClearance = "interface.misc.disable_clearance";
|
||||
constexpr const char* MultiplayerChat = "interface.misc.multiplayer_chat";
|
||||
|
||||
// Interface / scroll
|
||||
constexpr const char* ScrollUp = "interface.scroll.up";
|
||||
constexpr const char* ScrollLeft = "interface.scroll.left";
|
||||
constexpr const char* ScrollRight = "interface.scroll.right";
|
||||
constexpr const char* ScrollDown = "interface.scroll.down";
|
||||
|
||||
// Interface / graphics
|
||||
constexpr const char* ScaleToggleWindowMode = "interface.graphics.toggle_window_mode";
|
||||
constexpr const char* InterfaceScaleIncrease = "interface.graphics.increase";
|
||||
constexpr const char* InterfaceScaleDecrease = "interface.graphics.decrease";
|
||||
|
||||
// Interface / open
|
||||
constexpr const char* InterfaceOpenLand = "interface.open.land";
|
||||
constexpr const char* InterfaceOpenWater = "interface.open.water";
|
||||
constexpr const char* InterfaceClearScenery = "interface.open.clear_scenery";
|
||||
constexpr const char* InterfaceOpenScenery = "interface.open.scenery";
|
||||
constexpr const char* InterfaceOpenFootpaths = "interface.open.footpaths";
|
||||
constexpr const char* InterfaceOpenNewRide = "interface.open.new_ride";
|
||||
constexpr const char* InterfaceOpenFinances = "interface.open.finances";
|
||||
constexpr const char* InterfaceOpenResearch = "interface.open.research";
|
||||
constexpr const char* InterfaceOpenRides = "interface.open.rides";
|
||||
constexpr const char* InterfaceOpenPark = "interface.open.park";
|
||||
constexpr const char* InterfaceOpenGuests = "interface.open.guests";
|
||||
constexpr const char* InterfaceOpenStaff = "interface.open.staff";
|
||||
constexpr const char* InterfaceOpenMessages = "interface.open.messages";
|
||||
constexpr const char* InterfaceOpenMap = "interface.open.map";
|
||||
constexpr const char* InterfaceShowOptions = "interface.open.options";
|
||||
constexpr const char* InterfaceOpenCheats = "interface.open.cheats";
|
||||
constexpr const char* InterfaceOpenTileInspector = "interface.open.tileinspector";
|
||||
constexpr const char* MultiplayerShow = "interface.open.multiplayer";
|
||||
|
||||
// View
|
||||
constexpr const char* ViewToggleUnderground = "view.show_underground";
|
||||
constexpr const char* ViewToggleBaseLand = "view.hide_base_land";
|
||||
constexpr const char* ViewToggleVerticalLand = "view.hide_vertical_land";
|
||||
constexpr const char* ViewToggleRides = "view.transparent_rides";
|
||||
constexpr const char* ViewToggleScenery = "view.transparent_scenery";
|
||||
constexpr const char* ViewToggleSupports = "view.hide_supports";
|
||||
constexpr const char* ViewTogglePeeps = "view.hide_peeps";
|
||||
constexpr const char* ViewToggleLandHeightMarkers = "view.show_land_height";
|
||||
constexpr const char* ViewToggleTrackHeightMarkers = "view.show_track_height";
|
||||
constexpr const char* ViewToggleFootpathHeightMarkers = "view.show_footpath_height";
|
||||
constexpr const char* ViewToggleFootpaths = "view.transparent_footpaths";
|
||||
constexpr const char* ViewToggleGridlines = "view.show_gridlines";
|
||||
constexpr const char* ViewToggleCutAway = "view.toggle_cut_away";
|
||||
constexpr const char* ViewToogleFootpathIssues = "view.highlight_path_issues";
|
||||
|
||||
// Window / ride construction
|
||||
constexpr const char* WindowRideConstructionTurnLeft = "window.rideconstruction.turn_left";
|
||||
constexpr const char* WindowRideConstructionTurnRight = "window.rideconstruction.turn_right";
|
||||
constexpr const char* WindowRideConstructionDefault = "window.rideconstruction.default";
|
||||
constexpr const char* WindowRideConstructionSlopeDown = "window.rideconstruction.slope_down";
|
||||
constexpr const char* WindowRideConstructionSlopeUp = "window.rideconstruction.slope_up";
|
||||
constexpr const char* WindowRideConstructionChainLift = "window.rideconstruction.chain_lift";
|
||||
constexpr const char* WindowRideConstructionBankLeft = "window.rideconstruction.bank_left";
|
||||
constexpr const char* WindowRideConstructionBankRight = "window.rideconstruction.bank_right";
|
||||
constexpr const char* WindowRideConstructionPrevious = "window.rideconstruction.previous";
|
||||
constexpr const char* WindowRideConstructionNext = "window.rideconstruction.next";
|
||||
constexpr const char* WindowRideConstructionBuild = "window.rideconstruction.build";
|
||||
constexpr const char* WindowRideConstructionDemolish = "window.rideconstruction.demolish";
|
||||
|
||||
// Window / tile inspector
|
||||
constexpr const char* WindowTileInspectorInsertCorrupt = "window.tileinspector.insert_corrupt";
|
||||
constexpr const char* WindowTileInspectorCopy = "window.tileinspector.copy";
|
||||
constexpr const char* WindowTileInspectorPaste = "window.tileinspector.paste";
|
||||
constexpr const char* WindowTileInspectorRemove = "window.tileinspector.remove";
|
||||
constexpr const char* WindowTileInspectorMoveUp = "window.tileinspector.move_up";
|
||||
constexpr const char* WindowTileInspectorMoveDown = "window.tileinspector.move_down";
|
||||
constexpr const char* WindowTileInspectorIncreaseX = "window.tileinspector.increase_x";
|
||||
constexpr const char* WindowTileInspectorDecreaseX = "window.tileinspector.decrease_x";
|
||||
constexpr const char* WindowTileInspectorIncreaseY = "window.tileinspector.increase_y";
|
||||
constexpr const char* WindowTileInspectorDecreaseY = "window.tileinspector.decrease_y";
|
||||
constexpr const char* WindowTileInspectorIncreaseHeight = "window.tileinspector.increase_height";
|
||||
constexpr const char* WindowTileInspectorDecreaseHeight = "window.tileinspector.decrease_height";
|
||||
|
||||
// Debug
|
||||
constexpr const char* DebugToggleConsole = "debug.console";
|
||||
constexpr const char* DebugTogglePaintDebugWindow = "debug.toggle_paint_debug_window";
|
||||
constexpr const char* DebugAdvanceTick = "debug.advance_tick";
|
||||
} // namespace OpenRCT2::Ui::ShortcutId
|
||||
359
src/openrct2-ui/input/ShortcutInput.cpp
Normal file
359
src/openrct2-ui/input/ShortcutInput.cpp
Normal file
@@ -0,0 +1,359 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2021 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ShortcutManager.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <openrct2/core/String.hpp>
|
||||
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
constexpr uint32_t UsefulModifiers = KMOD_SHIFT | KMOD_CTRL | KMOD_ALT | KMOD_GUI;
|
||||
|
||||
static uint32_t ParseModifier(const std::string_view& text)
|
||||
{
|
||||
if (String::Equals(text, "CTRL", true))
|
||||
{
|
||||
return KMOD_CTRL;
|
||||
}
|
||||
else if (String::Equals(text, "LCTRL", true))
|
||||
{
|
||||
return KMOD_LCTRL;
|
||||
}
|
||||
else if (String::Equals(text, "RCTRL", true))
|
||||
{
|
||||
return KMOD_RCTRL;
|
||||
}
|
||||
else if (String::Equals(text, "SHIFT", true))
|
||||
{
|
||||
return KMOD_SHIFT;
|
||||
}
|
||||
else if (String::Equals(text, "LSHIFT", true))
|
||||
{
|
||||
return KMOD_LSHIFT;
|
||||
}
|
||||
else if (String::Equals(text, "RSHIFT", true))
|
||||
{
|
||||
return KMOD_RSHIFT;
|
||||
}
|
||||
else if (String::Equals(text, "ALT", true))
|
||||
{
|
||||
return KMOD_ALT;
|
||||
}
|
||||
else if (String::Equals(text, "LALT", true))
|
||||
{
|
||||
return KMOD_LALT;
|
||||
}
|
||||
else if (String::Equals(text, "RALT", true))
|
||||
{
|
||||
return KMOD_RALT;
|
||||
}
|
||||
else if (String::Equals(text, "GUI", true))
|
||||
{
|
||||
return KMOD_GUI;
|
||||
}
|
||||
else if (String::Equals(text, "LCTRL", true))
|
||||
{
|
||||
return KMOD_LGUI;
|
||||
}
|
||||
else if (String::Equals(text, "RGUI", true))
|
||||
{
|
||||
return KMOD_RGUI;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t ParseKey(const std::string_view& text)
|
||||
{
|
||||
char buffer[128]{};
|
||||
std::strncpy(buffer, text.data(), sizeof(buffer) - 1);
|
||||
auto keyCode = SDL_GetKeyFromName(buffer);
|
||||
if (keyCode != SDLK_UNKNOWN)
|
||||
{
|
||||
return keyCode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t FindPlus(std::string_view s, size_t index)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
index = s.find('+', index);
|
||||
if (index != std::string::npos && index != 0 && s[index - 1] == ' ')
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
ShortcutInput::ShortcutInput(const std::string_view& value)
|
||||
{
|
||||
uint32_t modifiers = 0;
|
||||
size_t index = 0;
|
||||
auto sepIndex = FindPlus(value, index);
|
||||
while (sepIndex != std::string::npos)
|
||||
{
|
||||
auto text = value.substr(index, sepIndex - index);
|
||||
auto mod = ParseModifier(text);
|
||||
modifiers |= mod;
|
||||
index = sepIndex + 1;
|
||||
sepIndex = FindPlus(value, index);
|
||||
}
|
||||
|
||||
auto kind = InputDeviceKind::Keyboard;
|
||||
auto button = 0u;
|
||||
auto colonIndex = value.find(':', index);
|
||||
if (colonIndex != std::string::npos)
|
||||
{
|
||||
auto device = value.substr(index, colonIndex - index);
|
||||
if (device == "MOUSE")
|
||||
{
|
||||
auto rem = std::string(value.substr(colonIndex + 1));
|
||||
kind = InputDeviceKind::Mouse;
|
||||
button = atoi(rem.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
button = ParseKey(value.substr(index));
|
||||
}
|
||||
|
||||
Kind = kind;
|
||||
Modifiers = modifiers;
|
||||
Button = button;
|
||||
}
|
||||
|
||||
std::string ShortcutInput::ToString() const
|
||||
{
|
||||
std::string result;
|
||||
AppendModifier(result, "SHIFT", KMOD_LSHIFT, KMOD_RSHIFT);
|
||||
AppendModifier(result, "CTRL", KMOD_LCTRL, KMOD_RCTRL);
|
||||
AppendModifier(result, "ALT", KMOD_LALT, KMOD_RALT);
|
||||
AppendModifier(result, "GUI", KMOD_LGUI, KMOD_RGUI);
|
||||
|
||||
if (Kind == InputDeviceKind::Keyboard)
|
||||
{
|
||||
switch (Button)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case SDLK_BACKSPACE:
|
||||
result += "BACKSPACE";
|
||||
break;
|
||||
case SDLK_ESCAPE:
|
||||
result += "ESCAPE";
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
result += "SPACE";
|
||||
break;
|
||||
case SDLK_TAB:
|
||||
result += "TAB";
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
result += "RETURN";
|
||||
break;
|
||||
case SDLK_PAGEUP:
|
||||
result += "PAGE UP";
|
||||
break;
|
||||
case SDLK_PAGEDOWN:
|
||||
result += "PAGE DOWN";
|
||||
break;
|
||||
|
||||
case SDLK_KP_DIVIDE:
|
||||
result += "NUMPAD /";
|
||||
break;
|
||||
case SDLK_KP_MULTIPLY:
|
||||
result += "NUMPAD *";
|
||||
break;
|
||||
case SDLK_KP_MINUS:
|
||||
result += "NUMPAD -";
|
||||
break;
|
||||
case SDLK_KP_PLUS:
|
||||
result += "NUMPAD +";
|
||||
break;
|
||||
case SDLK_KP_ENTER:
|
||||
result += "NUMPAD RETURN";
|
||||
break;
|
||||
case SDLK_KP_1:
|
||||
result += "NUMPAD 1";
|
||||
break;
|
||||
case SDLK_KP_2:
|
||||
result += "NUMPAD 2";
|
||||
break;
|
||||
case SDLK_KP_3:
|
||||
result += "NUMPAD 3";
|
||||
break;
|
||||
case SDLK_KP_4:
|
||||
result += "NUMPAD 4";
|
||||
break;
|
||||
case SDLK_KP_5:
|
||||
result += "NUMPAD 5";
|
||||
break;
|
||||
case SDLK_KP_6:
|
||||
result += "NUMPAD 6";
|
||||
break;
|
||||
case SDLK_KP_7:
|
||||
result += "NUMPAD 7";
|
||||
break;
|
||||
case SDLK_KP_8:
|
||||
result += "NUMPAD 8";
|
||||
break;
|
||||
case SDLK_KP_9:
|
||||
result += "NUMPAD 9";
|
||||
break;
|
||||
case SDLK_KP_0:
|
||||
result += "NUMPAD 0";
|
||||
break;
|
||||
case SDLK_KP_PERIOD:
|
||||
result += "NUMPAD .";
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Button & SDLK_SCANCODE_MASK)
|
||||
{
|
||||
auto name = SDL_GetScancodeName(static_cast<SDL_Scancode>(Button & ~SDLK_SCANCODE_MASK));
|
||||
result += name;
|
||||
}
|
||||
else
|
||||
{
|
||||
String::AppendCodepoint(result, std::toupper(Button));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (Kind == InputDeviceKind::Mouse)
|
||||
{
|
||||
switch (Button)
|
||||
{
|
||||
case 0:
|
||||
result += "LMB";
|
||||
break;
|
||||
case 1:
|
||||
result += "RMB";
|
||||
break;
|
||||
default:
|
||||
result += "MOUSE ";
|
||||
result += std::to_string(Button + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (Kind == InputDeviceKind::JoyButton)
|
||||
{
|
||||
result += "JOY ";
|
||||
result += std::to_string(Button + 1);
|
||||
}
|
||||
else if (Kind == InputDeviceKind::JoyHat)
|
||||
{
|
||||
if (Button & SDL_HAT_LEFT)
|
||||
result += "JOY LEFT";
|
||||
else if (Button & SDL_HAT_RIGHT)
|
||||
result += "JOY RIGHT";
|
||||
else if (Button & SDL_HAT_UP)
|
||||
result += "JOY UP";
|
||||
else if (Button & SDL_HAT_DOWN)
|
||||
result += "JOY DOWN";
|
||||
else
|
||||
result += "JOY ?";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ShortcutInput::AppendModifier(std::string& s, const std::string_view& text, uint32_t left, uint32_t right) const
|
||||
{
|
||||
if ((Modifiers & (left | right)) == (left | right))
|
||||
{
|
||||
s += text;
|
||||
s += "+";
|
||||
return true;
|
||||
}
|
||||
else if (Modifiers & left)
|
||||
{
|
||||
s += "L";
|
||||
s += text;
|
||||
s += "+";
|
||||
return true;
|
||||
}
|
||||
else if (Modifiers & right)
|
||||
{
|
||||
s += "R";
|
||||
s += text;
|
||||
s += "+";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool HasModifier(uint32_t shortcut, uint32_t actual, uint32_t left, uint32_t right)
|
||||
{
|
||||
if (shortcut & (left | right))
|
||||
{
|
||||
if ((shortcut & left) && (actual & left))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((shortcut & right) && (actual & right))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (actual & (left | right))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CompareModifiers(uint32_t shortcut, uint32_t actual)
|
||||
{
|
||||
shortcut &= UsefulModifiers;
|
||||
return HasModifier(shortcut, actual, KMOD_LCTRL, KMOD_RCTRL) && HasModifier(shortcut, actual, KMOD_LSHIFT, KMOD_RSHIFT)
|
||||
&& HasModifier(shortcut, actual, KMOD_LALT, KMOD_RALT) && HasModifier(shortcut, actual, KMOD_LGUI, KMOD_RGUI);
|
||||
}
|
||||
|
||||
bool ShortcutInput::Matches(const InputEvent& e) const
|
||||
{
|
||||
if (CompareModifiers(Modifiers, e.Modifiers))
|
||||
{
|
||||
if (e.DeviceKind == Kind && Button == e.Button)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<ShortcutInput> ShortcutInput::FromInputEvent(const InputEvent& e)
|
||||
{
|
||||
// Assume any side modifier (more specific configurations can be done by manually editing config file)
|
||||
auto modifiers = e.Modifiers & UsefulModifiers;
|
||||
for (auto mod : { KMOD_CTRL, KMOD_SHIFT, KMOD_ALT, KMOD_GUI })
|
||||
{
|
||||
if (modifiers & mod)
|
||||
{
|
||||
modifiers |= mod;
|
||||
}
|
||||
}
|
||||
|
||||
ShortcutInput result;
|
||||
result.Kind = e.DeviceKind;
|
||||
result.Modifiers = modifiers;
|
||||
result.Button = e.Button;
|
||||
return result;
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "ShortcutManager.h"
|
||||
|
||||
#include "ShortcutIds.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <fstream>
|
||||
#include <openrct2/Context.h>
|
||||
@@ -22,350 +24,6 @@
|
||||
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
constexpr uint32_t UsefulModifiers = KMOD_SHIFT | KMOD_CTRL | KMOD_ALT | KMOD_GUI;
|
||||
|
||||
static uint32_t ParseModifier(const std::string_view& text)
|
||||
{
|
||||
if (String::Equals(text, "CTRL", true))
|
||||
{
|
||||
return KMOD_CTRL;
|
||||
}
|
||||
else if (String::Equals(text, "LCTRL", true))
|
||||
{
|
||||
return KMOD_LCTRL;
|
||||
}
|
||||
else if (String::Equals(text, "RCTRL", true))
|
||||
{
|
||||
return KMOD_RCTRL;
|
||||
}
|
||||
else if (String::Equals(text, "SHIFT", true))
|
||||
{
|
||||
return KMOD_SHIFT;
|
||||
}
|
||||
else if (String::Equals(text, "LSHIFT", true))
|
||||
{
|
||||
return KMOD_LSHIFT;
|
||||
}
|
||||
else if (String::Equals(text, "RSHIFT", true))
|
||||
{
|
||||
return KMOD_RSHIFT;
|
||||
}
|
||||
else if (String::Equals(text, "ALT", true))
|
||||
{
|
||||
return KMOD_ALT;
|
||||
}
|
||||
else if (String::Equals(text, "LALT", true))
|
||||
{
|
||||
return KMOD_LALT;
|
||||
}
|
||||
else if (String::Equals(text, "RALT", true))
|
||||
{
|
||||
return KMOD_RALT;
|
||||
}
|
||||
else if (String::Equals(text, "GUI", true))
|
||||
{
|
||||
return KMOD_GUI;
|
||||
}
|
||||
else if (String::Equals(text, "LCTRL", true))
|
||||
{
|
||||
return KMOD_LGUI;
|
||||
}
|
||||
else if (String::Equals(text, "RGUI", true))
|
||||
{
|
||||
return KMOD_RGUI;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t ParseKey(const std::string_view& text)
|
||||
{
|
||||
char buffer[128]{};
|
||||
std::strncpy(buffer, text.data(), sizeof(buffer) - 1);
|
||||
auto keyCode = SDL_GetKeyFromName(buffer);
|
||||
if (keyCode != SDLK_UNKNOWN)
|
||||
{
|
||||
return keyCode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t FindPlus(std::string_view s, size_t index)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
index = s.find('+', index);
|
||||
if (index != std::string::npos && index != 0 && s[index - 1] == ' ')
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
ShortcutInput::ShortcutInput(const std::string_view& value)
|
||||
{
|
||||
uint32_t modifiers = 0;
|
||||
size_t index = 0;
|
||||
auto sepIndex = FindPlus(value, index);
|
||||
while (sepIndex != std::string::npos)
|
||||
{
|
||||
auto text = value.substr(index, sepIndex - index);
|
||||
auto mod = ParseModifier(text);
|
||||
modifiers |= mod;
|
||||
index = sepIndex + 1;
|
||||
sepIndex = FindPlus(value, index);
|
||||
}
|
||||
|
||||
auto kind = InputDeviceKind::Keyboard;
|
||||
auto button = 0u;
|
||||
auto colonIndex = value.find(':', index);
|
||||
if (colonIndex != std::string::npos)
|
||||
{
|
||||
auto device = value.substr(index, colonIndex - index);
|
||||
if (device == "MOUSE")
|
||||
{
|
||||
auto rem = std::string(value.substr(colonIndex + 1));
|
||||
kind = InputDeviceKind::Mouse;
|
||||
button = atoi(rem.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
button = ParseKey(value.substr(index));
|
||||
}
|
||||
|
||||
Kind = kind;
|
||||
Modifiers = modifiers;
|
||||
Button = button;
|
||||
}
|
||||
|
||||
std::string ShortcutInput::ToString() const
|
||||
{
|
||||
std::string result;
|
||||
AppendModifier(result, "SHIFT", KMOD_LSHIFT, KMOD_RSHIFT);
|
||||
AppendModifier(result, "CTRL", KMOD_LCTRL, KMOD_RCTRL);
|
||||
AppendModifier(result, "ALT", KMOD_LALT, KMOD_RALT);
|
||||
AppendModifier(result, "GUI", KMOD_LGUI, KMOD_RGUI);
|
||||
|
||||
if (Kind == InputDeviceKind::Keyboard)
|
||||
{
|
||||
switch (Button)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case SDLK_BACKSPACE:
|
||||
result += "BACKSPACE";
|
||||
break;
|
||||
case SDLK_ESCAPE:
|
||||
result += "ESCAPE";
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
result += "SPACE";
|
||||
break;
|
||||
case SDLK_TAB:
|
||||
result += "TAB";
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
result += "RETURN";
|
||||
break;
|
||||
case SDLK_PAGEUP:
|
||||
result += "PAGE UP";
|
||||
break;
|
||||
case SDLK_PAGEDOWN:
|
||||
result += "PAGE DOWN";
|
||||
break;
|
||||
|
||||
case SDLK_KP_DIVIDE:
|
||||
result += "NUMPAD /";
|
||||
break;
|
||||
case SDLK_KP_MULTIPLY:
|
||||
result += "NUMPAD *";
|
||||
break;
|
||||
case SDLK_KP_MINUS:
|
||||
result += "NUMPAD -";
|
||||
break;
|
||||
case SDLK_KP_PLUS:
|
||||
result += "NUMPAD +";
|
||||
break;
|
||||
case SDLK_KP_ENTER:
|
||||
result += "NUMPAD RETURN";
|
||||
break;
|
||||
case SDLK_KP_1:
|
||||
result += "NUMPAD 1";
|
||||
break;
|
||||
case SDLK_KP_2:
|
||||
result += "NUMPAD 2";
|
||||
break;
|
||||
case SDLK_KP_3:
|
||||
result += "NUMPAD 3";
|
||||
break;
|
||||
case SDLK_KP_4:
|
||||
result += "NUMPAD 4";
|
||||
break;
|
||||
case SDLK_KP_5:
|
||||
result += "NUMPAD 5";
|
||||
break;
|
||||
case SDLK_KP_6:
|
||||
result += "NUMPAD 6";
|
||||
break;
|
||||
case SDLK_KP_7:
|
||||
result += "NUMPAD 7";
|
||||
break;
|
||||
case SDLK_KP_8:
|
||||
result += "NUMPAD 8";
|
||||
break;
|
||||
case SDLK_KP_9:
|
||||
result += "NUMPAD 9";
|
||||
break;
|
||||
case SDLK_KP_0:
|
||||
result += "NUMPAD 0";
|
||||
break;
|
||||
case SDLK_KP_PERIOD:
|
||||
result += "NUMPAD .";
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Button & SDLK_SCANCODE_MASK)
|
||||
{
|
||||
auto name = SDL_GetScancodeName(static_cast<SDL_Scancode>(Button & ~SDLK_SCANCODE_MASK));
|
||||
result += name;
|
||||
}
|
||||
else
|
||||
{
|
||||
String::AppendCodepoint(result, std::toupper(Button));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (Kind == InputDeviceKind::Mouse)
|
||||
{
|
||||
switch (Button)
|
||||
{
|
||||
case 0:
|
||||
result += "LMB";
|
||||
break;
|
||||
case 1:
|
||||
result += "RMB";
|
||||
break;
|
||||
default:
|
||||
result += "MOUSE ";
|
||||
result += std::to_string(Button + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (Kind == InputDeviceKind::JoyButton)
|
||||
{
|
||||
result += "JOY ";
|
||||
result += std::to_string(Button + 1);
|
||||
}
|
||||
else if (Kind == InputDeviceKind::JoyHat)
|
||||
{
|
||||
if (Button & SDL_HAT_LEFT)
|
||||
result += "JOY LEFT";
|
||||
else if (Button & SDL_HAT_RIGHT)
|
||||
result += "JOY RIGHT";
|
||||
else if (Button & SDL_HAT_UP)
|
||||
result += "JOY UP";
|
||||
else if (Button & SDL_HAT_DOWN)
|
||||
result += "JOY DOWN";
|
||||
else
|
||||
result += "JOY ?";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ShortcutInput::AppendModifier(std::string& s, const std::string_view& text, uint32_t left, uint32_t right) const
|
||||
{
|
||||
if ((Modifiers & (left | right)) == (left | right))
|
||||
{
|
||||
s += text;
|
||||
s += "+";
|
||||
return true;
|
||||
}
|
||||
else if (Modifiers & left)
|
||||
{
|
||||
s += "L";
|
||||
s += text;
|
||||
s += "+";
|
||||
return true;
|
||||
}
|
||||
else if (Modifiers & right)
|
||||
{
|
||||
s += "R";
|
||||
s += text;
|
||||
s += "+";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool HasModifier(uint32_t shortcut, uint32_t actual, uint32_t left, uint32_t right)
|
||||
{
|
||||
if (shortcut & (left | right))
|
||||
{
|
||||
if ((shortcut & left) && (actual & left))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((shortcut & right) && (actual & right))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (actual & (left | right))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CompareModifiers(uint32_t shortcut, uint32_t actual)
|
||||
{
|
||||
shortcut &= UsefulModifiers;
|
||||
return HasModifier(shortcut, actual, KMOD_LCTRL, KMOD_RCTRL) && HasModifier(shortcut, actual, KMOD_LSHIFT, KMOD_RSHIFT)
|
||||
&& HasModifier(shortcut, actual, KMOD_LALT, KMOD_RALT) && HasModifier(shortcut, actual, KMOD_LGUI, KMOD_RGUI);
|
||||
}
|
||||
|
||||
bool ShortcutInput::Matches(const InputEvent& e) const
|
||||
{
|
||||
if (CompareModifiers(Modifiers, e.Modifiers))
|
||||
{
|
||||
if (e.DeviceKind == Kind && Button == e.Button)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<ShortcutInput> ShortcutInput::FromInputEvent(const InputEvent& e)
|
||||
{
|
||||
// Assume any side modifier (more specific configurations can be done by manually editing config file)
|
||||
auto modifiers = e.Modifiers & UsefulModifiers;
|
||||
for (auto mod : { KMOD_CTRL, KMOD_SHIFT, KMOD_ALT, KMOD_GUI })
|
||||
{
|
||||
if (modifiers & mod)
|
||||
{
|
||||
modifiers |= mod;
|
||||
}
|
||||
}
|
||||
|
||||
ShortcutInput result;
|
||||
result.Kind = e.DeviceKind;
|
||||
result.Modifiers = modifiers;
|
||||
result.Button = e.Button;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string_view RegisteredShortcut::GetTopLevelGroup() const
|
||||
{
|
||||
auto fullstopIndex = Id.find('.');
|
||||
|
||||
@@ -138,109 +138,4 @@ namespace OpenRCT2::Ui
|
||||
};
|
||||
|
||||
ShortcutManager& GetShortcutManager();
|
||||
|
||||
namespace ShortcutId
|
||||
{
|
||||
// Interface / general
|
||||
constexpr const char* InterfaceCloseTop = "interface.general.close_top";
|
||||
constexpr const char* InterfaceCloseAll = "interface.general.close_all";
|
||||
constexpr const char* InterfaceCancelConstruction = "interface.general.cancel_construction";
|
||||
constexpr const char* InterfacePause = "interface.general.pause";
|
||||
constexpr const char* InterfaceZoomOut = "interface.general.zoom_out";
|
||||
constexpr const char* InterfaceZoomIn = "interface.general.zoom_in";
|
||||
constexpr const char* InterfaceRotateClockwise = "interface.general.rotate_clockwise";
|
||||
constexpr const char* InterfaceRotateAnticlockwise = "interface.general.rotate_anticlockwise";
|
||||
constexpr const char* InterfaceRotateConstruction = "interface.general.rotate_construction";
|
||||
constexpr const char* InterfaceDecreaseSpeed = "interface.misc.decrease_speed";
|
||||
constexpr const char* InterfaceIncreaseSpeed = "interface.misc.increase_speed";
|
||||
constexpr const char* InterfaceToggleToolbars = "interface.misc.toggle_toolbars";
|
||||
constexpr const char* InterfaceScreenshot = "interface.misc.screenshot";
|
||||
constexpr const char* InterfaceLoadGame = "interface.misc.load_game";
|
||||
constexpr const char* InterfaceSaveGame = "interface.misc.save_game";
|
||||
constexpr const char* InterfaceMute = "interface.misc.mute";
|
||||
constexpr const char* InterfaceSceneryPicker = "interface.misc.scenery_picker";
|
||||
constexpr const char* InterfaceDisableClearance = "interface.misc.disable_clearance";
|
||||
constexpr const char* MultiplayerChat = "interface.misc.multiplayer_chat";
|
||||
|
||||
// Interface / scroll
|
||||
constexpr const char* ScrollUp = "interface.scroll.up";
|
||||
constexpr const char* ScrollLeft = "interface.scroll.left";
|
||||
constexpr const char* ScrollRight = "interface.scroll.right";
|
||||
constexpr const char* ScrollDown = "interface.scroll.down";
|
||||
|
||||
// Interface / graphics
|
||||
constexpr const char* ScaleToggleWindowMode = "interface.graphics.toggle_window_mode";
|
||||
constexpr const char* InterfaceScaleIncrease = "interface.graphics.increase";
|
||||
constexpr const char* InterfaceScaleDecrease = "interface.graphics.decrease";
|
||||
|
||||
// Interface / open
|
||||
constexpr const char* InterfaceOpenLand = "interface.open.land";
|
||||
constexpr const char* InterfaceOpenWater = "interface.open.water";
|
||||
constexpr const char* InterfaceClearScenery = "interface.open.clear_scenery";
|
||||
constexpr const char* InterfaceOpenScenery = "interface.open.scenery";
|
||||
constexpr const char* InterfaceOpenFootpaths = "interface.open.footpaths";
|
||||
constexpr const char* InterfaceOpenNewRide = "interface.open.new_ride";
|
||||
constexpr const char* InterfaceOpenFinances = "interface.open.finances";
|
||||
constexpr const char* InterfaceOpenResearch = "interface.open.research";
|
||||
constexpr const char* InterfaceOpenRides = "interface.open.rides";
|
||||
constexpr const char* InterfaceOpenPark = "interface.open.park";
|
||||
constexpr const char* InterfaceOpenGuests = "interface.open.guests";
|
||||
constexpr const char* InterfaceOpenStaff = "interface.open.staff";
|
||||
constexpr const char* InterfaceOpenMessages = "interface.open.messages";
|
||||
constexpr const char* InterfaceOpenMap = "interface.open.map";
|
||||
constexpr const char* InterfaceShowOptions = "interface.open.options";
|
||||
constexpr const char* InterfaceOpenCheats = "interface.open.cheats";
|
||||
constexpr const char* InterfaceOpenTileInspector = "interface.open.tileinspector";
|
||||
constexpr const char* MultiplayerShow = "interface.open.multiplayer";
|
||||
|
||||
// View
|
||||
constexpr const char* ViewToggleUnderground = "view.show_underground";
|
||||
constexpr const char* ViewToggleBaseLand = "view.hide_base_land";
|
||||
constexpr const char* ViewToggleVerticalLand = "view.hide_vertical_land";
|
||||
constexpr const char* ViewToggleRides = "view.transparent_rides";
|
||||
constexpr const char* ViewToggleScenery = "view.transparent_scenery";
|
||||
constexpr const char* ViewToggleSupports = "view.hide_supports";
|
||||
constexpr const char* ViewTogglePeeps = "view.hide_peeps";
|
||||
constexpr const char* ViewToggleLandHeightMarkers = "view.show_land_height";
|
||||
constexpr const char* ViewToggleTrackHeightMarkers = "view.show_track_height";
|
||||
constexpr const char* ViewToggleFootpathHeightMarkers = "view.show_footpath_height";
|
||||
constexpr const char* ViewToggleFootpaths = "view.transparent_footpaths";
|
||||
constexpr const char* ViewToggleGridlines = "view.show_gridlines";
|
||||
constexpr const char* ViewToggleCutAway = "view.toggle_cut_away";
|
||||
constexpr const char* ViewToogleFootpathIssues = "view.highlight_path_issues";
|
||||
|
||||
// Window / ride construction
|
||||
constexpr const char* WindowRideConstructionTurnLeft = "window.rideconstruction.turn_left";
|
||||
constexpr const char* WindowRideConstructionTurnRight = "window.rideconstruction.turn_right";
|
||||
constexpr const char* WindowRideConstructionDefault = "window.rideconstruction.default";
|
||||
constexpr const char* WindowRideConstructionSlopeDown = "window.rideconstruction.slope_down";
|
||||
constexpr const char* WindowRideConstructionSlopeUp = "window.rideconstruction.slope_up";
|
||||
constexpr const char* WindowRideConstructionChainLift = "window.rideconstruction.chain_lift";
|
||||
constexpr const char* WindowRideConstructionBankLeft = "window.rideconstruction.bank_left";
|
||||
constexpr const char* WindowRideConstructionBankRight = "window.rideconstruction.bank_right";
|
||||
constexpr const char* WindowRideConstructionPrevious = "window.rideconstruction.previous";
|
||||
constexpr const char* WindowRideConstructionNext = "window.rideconstruction.next";
|
||||
constexpr const char* WindowRideConstructionBuild = "window.rideconstruction.build";
|
||||
constexpr const char* WindowRideConstructionDemolish = "window.rideconstruction.demolish";
|
||||
|
||||
// Window / tile inspector
|
||||
constexpr const char* WindowTileInspectorInsertCorrupt = "window.tileinspector.insert_corrupt";
|
||||
constexpr const char* WindowTileInspectorCopy = "window.tileinspector.copy";
|
||||
constexpr const char* WindowTileInspectorPaste = "window.tileinspector.paste";
|
||||
constexpr const char* WindowTileInspectorRemove = "window.tileinspector.remove";
|
||||
constexpr const char* WindowTileInspectorMoveUp = "window.tileinspector.move_up";
|
||||
constexpr const char* WindowTileInspectorMoveDown = "window.tileinspector.move_down";
|
||||
constexpr const char* WindowTileInspectorIncreaseX = "window.tileinspector.increase_x";
|
||||
constexpr const char* WindowTileInspectorDecreaseX = "window.tileinspector.decrease_x";
|
||||
constexpr const char* WindowTileInspectorIncreaseY = "window.tileinspector.increase_y";
|
||||
constexpr const char* WindowTileInspectorDecreaseY = "window.tileinspector.decrease_y";
|
||||
constexpr const char* WindowTileInspectorIncreaseHeight = "window.tileinspector.increase_height";
|
||||
constexpr const char* WindowTileInspectorDecreaseHeight = "window.tileinspector.decrease_height";
|
||||
|
||||
// Debug
|
||||
constexpr const char* DebugToggleConsole = "debug.console";
|
||||
constexpr const char* DebugTogglePaintDebugWindow = "debug.toggle_paint_debug_window";
|
||||
constexpr const char* DebugAdvanceTick = "debug.advance_tick";
|
||||
} // namespace ShortcutId
|
||||
|
||||
} // namespace OpenRCT2::Ui
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<ClInclude Include="drawing\engines\opengl\TransparencyDepth.h" />
|
||||
<ClInclude Include="input\InputManager.h" />
|
||||
<ClInclude Include="input\KeyboardShortcuts.h" />
|
||||
<ClInclude Include="input\ShortcutIds.h" />
|
||||
<ClInclude Include="input\ShortcutManager.h" />
|
||||
<ClInclude Include="interface\Dropdown.h" />
|
||||
<ClInclude Include="interface\Graph.h" />
|
||||
@@ -95,6 +96,7 @@
|
||||
<ClCompile Include="input\KeyboardShortcut.cpp" />
|
||||
<ClCompile Include="input\KeyboardShortcuts.cpp" />
|
||||
<ClCompile Include="input\MouseInput.cpp" />
|
||||
<ClCompile Include="input\ShortcutInput.cpp" />
|
||||
<ClCompile Include="input\ShortcutManager.cpp" />
|
||||
<ClCompile Include="interface\Graph.cpp" />
|
||||
<ClCompile Include="interface\InGameConsole.cpp" />
|
||||
|
||||
Reference in New Issue
Block a user