mirror of https://github.com/OpenRCT2/OpenRCT2.git
Add input manager
This commit is contained in:
parent
b1eb975529
commit
ccae533978
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue