Add input manager

This commit is contained in:
Ted John 2020-12-13 03:40:10 +00:00
parent b1eb975529
commit ccae533978
8 changed files with 210 additions and 0 deletions

View File

@ -26,6 +26,7 @@
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
#include <openrct2-ui/input/InputManager.h>
#include <openrct2-ui/interface/Window.h> #include <openrct2-ui/interface/Window.h>
#include <openrct2/Context.h> #include <openrct2/Context.h>
#include <openrct2/Input.h> #include <openrct2/Input.h>
@ -415,6 +416,15 @@ public:
break; break;
} }
_cursorState.touch = false; _cursorState.touch = false;
{
InputEvent ie;
ie.DeviceKind = InputDeviceKind::Mouse;
ie.Button = e.button.button;
ie.State = InputEventState::Down;
auto& inputManager = GetInputManager();
inputManager.QueueInputEvent(std::move(ie));
}
break; break;
} }
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
@ -442,6 +452,15 @@ public:
break; break;
} }
_cursorState.touch = false; _cursorState.touch = false;
{
InputEvent ie;
ie.DeviceKind = InputDeviceKind::Mouse;
ie.Button = e.button.button;
ie.State = InputEventState::Release;
auto& inputManager = GetInputManager();
inputManager.QueueInputEvent(std::move(ie));
}
break; break;
} }
// Apple sends touchscreen events for trackpads, so ignore these events on macOS // Apple sends touchscreen events for trackpads, so ignore these events on macOS

View File

@ -14,6 +14,7 @@
#include "interface/Theme.h" #include "interface/Theme.h"
#include "windows/Window.h" #include "windows/Window.h"
#include <openrct2-ui/input/InputManager.h>
#include <openrct2-ui/windows/Window.h> #include <openrct2-ui/windows/Window.h>
#include <openrct2/Input.h> #include <openrct2/Input.h>
#include <openrct2/config/Config.h> #include <openrct2/config/Config.h>
@ -517,6 +518,9 @@ public:
void HandleKeyboard(bool isTitle) override void HandleKeyboard(bool isTitle) override
{ {
InputHandleKeyboard(isTitle); InputHandleKeyboard(isTitle);
auto& inputManager = GetInputManager();
inputManager.Process();
} }
std::string GetKeyboardShortcutString(int32_t shortcut) override std::string GetKeyboardShortcutString(int32_t shortcut) override

View File

@ -0,0 +1,42 @@
/*****************************************************************************
* Copyright (c) 2014-2020 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 "InputManager.h"
#include <openrct2-ui/input/ShortcutManager.h>
using namespace OpenRCT2::Ui;
void InputManager::QueueInputEvent(InputEvent&& e)
{
_events.push(e);
}
void InputManager::Process()
{
while (!_events.empty())
{
const auto& e = _events.front();
Process(e);
_events.pop();
}
}
void InputManager::Process(const InputEvent& e)
{
auto& shortcutManager = GetShortcutManager();
shortcutManager.ProcessEvent(e);
}
static InputManager _inputManager;
InputManager& OpenRCT2::Ui::GetInputManager()
{
return _inputManager;
}

View File

@ -0,0 +1,50 @@
/*****************************************************************************
* Copyright (c) 2014-2020 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
#include <queue>
namespace OpenRCT2::Ui
{
enum class InputDeviceKind
{
Mouse,
Keyboard,
Gamepad,
};
enum class InputEventState
{
Down,
Release,
};
struct InputEvent
{
InputDeviceKind DeviceKind;
uint32_t Button;
InputEventState State;
};
class InputManager
{
private:
std::queue<InputEvent> _events;
void Process(const InputEvent& e);
public:
void QueueInputEvent(InputEvent&& e);
void Process();
};
InputManager& GetInputManager();
} // namespace OpenRCT2::Ui

View File

@ -11,6 +11,7 @@
#include <SDL.h> #include <SDL.h>
#include <openrct2/core/String.hpp> #include <openrct2/core/String.hpp>
#include <openrct2/interface/Window.h>
#include <openrct2/localisation/Language.h> #include <openrct2/localisation/Language.h>
using namespace OpenRCT2::Ui; using namespace OpenRCT2::Ui;
@ -214,6 +215,30 @@ bool ShortcutInput::AppendModifier(std::string& s, const std::string_view& text,
return false; return false;
} }
bool ShortcutInput::Matches(const InputEvent& e) const
{
if (e.DeviceKind == InputDeviceKind::Mouse)
{
if (Kind == ShortcutInputKind::Mouse && Key == e.Button)
{
return true;
}
}
return false;
}
std::optional<ShortcutInput> ShortcutInput::FromInputEvent(const InputEvent& e)
{
if (e.DeviceKind == InputDeviceKind::Mouse)
{
ShortcutInput result;
result.Kind = ShortcutInputKind::Mouse;
result.Key = e.Button;
return result;
}
return {};
}
std::string_view RegisteredShortcut::GetGroup() const std::string_view RegisteredShortcut::GetGroup() const
{ {
auto fullstopIndex = Id.find('.'); auto fullstopIndex = Id.find('.');
@ -242,6 +267,53 @@ RegisteredShortcut* ShortcutManager::GetShortcut(std::string_view id)
void ShortcutManager::SetPendingShortcutChange(std::string_view id) void ShortcutManager::SetPendingShortcutChange(std::string_view id)
{ {
_pendingShortcutChange = id;
}
bool ShortcutManager::IsSuitableInputEvent(const InputEvent& e)
{
if (e.DeviceKind == InputDeviceKind::Mouse)
{
// Do not allow LMB or RMB to be shortcut
if (e.Button == 0 || e.Button == 1)
{
return false;
}
}
return true;
}
void ShortcutManager::ProcessEvent(const InputEvent& e)
{
if (_pendingShortcutChange.empty())
{
for (const auto& shortcut : Shortcuts)
{
for (const auto& action : shortcut.Current)
{
if (action.Matches(e))
{
shortcut.Action();
break;
}
}
}
}
else if (IsSuitableInputEvent(e))
{
auto shortcut = GetShortcut(_pendingShortcutChange);
if (shortcut != nullptr)
{
auto shortcutInput = ShortcutInput::FromInputEvent(e);
if (shortcutInput)
{
shortcut->Current.clear();
shortcut->Current.push_back(std::move(*shortcutInput));
}
}
_pendingShortcutChange.clear();
window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT);
}
} }
static ShortcutManager _shortcutManager; static ShortcutManager _shortcutManager;

View File

@ -9,9 +9,12 @@
#pragma once #pragma once
#include "InputManager.h"
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <openrct2/localisation/StringIds.h> #include <openrct2/localisation/StringIds.h>
#include <optional>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <vector> #include <vector>
@ -35,6 +38,10 @@ namespace OpenRCT2::Ui
ShortcutInput(const std::string_view& value); ShortcutInput(const std::string_view& value);
std::string ToString() const; std::string ToString() const;
bool Matches(const InputEvent& e) const;
static std::optional<ShortcutInput> FromInputEvent(const InputEvent& e);
private: private:
bool AppendModifier(std::string& s, const std::string_view& text, uint32_t left, uint32_t right) const; bool AppendModifier(std::string& s, const std::string_view& text, uint32_t left, uint32_t right) const;
}; };
@ -78,6 +85,11 @@ namespace OpenRCT2::Ui
class ShortcutManager class ShortcutManager
{ {
private:
std::string _pendingShortcutChange;
static bool IsSuitableInputEvent(const InputEvent& e);
public: public:
std::vector<RegisteredShortcut> Shortcuts; std::vector<RegisteredShortcut> Shortcuts;
@ -88,6 +100,7 @@ namespace OpenRCT2::Ui
void RegisterDefaultShortcuts(); void RegisterDefaultShortcuts();
RegisteredShortcut* GetShortcut(std::string_view id); RegisteredShortcut* GetShortcut(std::string_view id);
void SetPendingShortcutChange(std::string_view id); void SetPendingShortcutChange(std::string_view id);
void ProcessEvent(const InputEvent& e);
}; };
ShortcutManager& GetShortcutManager(); ShortcutManager& GetShortcutManager();

View File

@ -41,6 +41,7 @@
<ClInclude Include="drawing\engines\opengl\TextureCache.h" /> <ClInclude Include="drawing\engines\opengl\TextureCache.h" />
<ClInclude Include="drawing\engines\opengl\TransparencyDepth.h" /> <ClInclude Include="drawing\engines\opengl\TransparencyDepth.h" />
<ClInclude Include="input\Input.h" /> <ClInclude Include="input\Input.h" />
<ClInclude Include="input\InputManager.h" />
<ClInclude Include="input\KeyboardShortcuts.h" /> <ClInclude Include="input\KeyboardShortcuts.h" />
<ClInclude Include="input\ShortcutManager.h" /> <ClInclude Include="input\ShortcutManager.h" />
<ClInclude Include="interface\Dropdown.h" /> <ClInclude Include="interface\Dropdown.h" />
@ -92,6 +93,7 @@
<ClCompile Include="drawing\engines\opengl\TransparencyDepth.cpp" /> <ClCompile Include="drawing\engines\opengl\TransparencyDepth.cpp" />
<ClCompile Include="drawing\engines\SoftwareDrawingEngine.cpp" /> <ClCompile Include="drawing\engines\SoftwareDrawingEngine.cpp" />
<ClCompile Include="input\Input.cpp" /> <ClCompile Include="input\Input.cpp" />
<ClCompile Include="input\InputManager.cpp" />
<ClCompile Include="input\KeyboardShortcut.cpp" /> <ClCompile Include="input\KeyboardShortcut.cpp" />
<ClCompile Include="input\KeyboardShortcuts.cpp" /> <ClCompile Include="input\KeyboardShortcuts.cpp" />
<ClCompile Include="input\MouseInput.cpp" /> <ClCompile Include="input\MouseInput.cpp" />

View File

@ -35,12 +35,14 @@ static rct_widget window_shortcut_change_widgets[] = {
{ WIDGETS_END } { WIDGETS_END }
}; };
static void window_shortcut_change_close(rct_window *w);
static void window_shortcut_change_mouseup(rct_window *w, rct_widgetindex widgetIndex); static void window_shortcut_change_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_shortcut_change_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_shortcut_change_paint(rct_window *w, rct_drawpixelinfo *dpi);
// 0x9A3F7C // 0x9A3F7C
static rct_window_event_list window_shortcut_change_events([](auto& events) static rct_window_event_list window_shortcut_change_events([](auto& events)
{ {
events.close = &window_shortcut_change_close;
events.mouse_up = &window_shortcut_change_mouseup; events.mouse_up = &window_shortcut_change_mouseup;
events.paint = &window_shortcut_change_paint; events.paint = &window_shortcut_change_paint;
}); });
@ -72,6 +74,12 @@ rct_window* window_shortcut_change_open(const std::string_view& shortcutId)
} }
} }
static void window_shortcut_change_close(rct_window* w)
{
auto& shortcutManager = GetShortcutManager();
shortcutManager.SetPendingShortcutChange({});
}
/** /**
* *
* rct2: 0x006E3AE0 * rct2: 0x006E3AE0