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 <cstdlib>
|
||||
#include <memory>
|
||||
#include <openrct2-ui/input/InputManager.h>
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/Input.h>
|
||||
|
@ -415,6 +416,15 @@ public:
|
|||
break;
|
||||
}
|
||||
_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;
|
||||
}
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
|
@ -442,6 +452,15 @@ public:
|
|||
break;
|
||||
}
|
||||
_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;
|
||||
}
|
||||
// Apple sends touchscreen events for trackpads, so ignore these events on macOS
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "interface/Theme.h"
|
||||
#include "windows/Window.h"
|
||||
|
||||
#include <openrct2-ui/input/InputManager.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
|
@ -517,6 +518,9 @@ public:
|
|||
void HandleKeyboard(bool isTitle) override
|
||||
{
|
||||
InputHandleKeyboard(isTitle);
|
||||
|
||||
auto& inputManager = GetInputManager();
|
||||
inputManager.Process();
|
||||
}
|
||||
|
||||
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 <openrct2/core/String.hpp>
|
||||
#include <openrct2/interface/Window.h>
|
||||
#include <openrct2/localisation/Language.h>
|
||||
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
@ -214,6 +215,30 @@ bool ShortcutInput::AppendModifier(std::string& s, const std::string_view& text,
|
|||
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
|
||||
{
|
||||
auto fullstopIndex = Id.find('.');
|
||||
|
@ -242,6 +267,53 @@ RegisteredShortcut* ShortcutManager::GetShortcut(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;
|
||||
|
|
|
@ -9,9 +9,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "InputManager.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <openrct2/localisation/StringIds.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
@ -35,6 +38,10 @@ namespace OpenRCT2::Ui
|
|||
ShortcutInput(const std::string_view& value);
|
||||
std::string ToString() const;
|
||||
|
||||
bool Matches(const InputEvent& e) const;
|
||||
|
||||
static std::optional<ShortcutInput> FromInputEvent(const InputEvent& e);
|
||||
|
||||
private:
|
||||
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
|
||||
{
|
||||
private:
|
||||
std::string _pendingShortcutChange;
|
||||
|
||||
static bool IsSuitableInputEvent(const InputEvent& e);
|
||||
|
||||
public:
|
||||
std::vector<RegisteredShortcut> Shortcuts;
|
||||
|
||||
|
@ -88,6 +100,7 @@ namespace OpenRCT2::Ui
|
|||
void RegisterDefaultShortcuts();
|
||||
RegisteredShortcut* GetShortcut(std::string_view id);
|
||||
void SetPendingShortcutChange(std::string_view id);
|
||||
void ProcessEvent(const InputEvent& e);
|
||||
};
|
||||
|
||||
ShortcutManager& GetShortcutManager();
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
<ClInclude Include="drawing\engines\opengl\TextureCache.h" />
|
||||
<ClInclude Include="drawing\engines\opengl\TransparencyDepth.h" />
|
||||
<ClInclude Include="input\Input.h" />
|
||||
<ClInclude Include="input\InputManager.h" />
|
||||
<ClInclude Include="input\KeyboardShortcuts.h" />
|
||||
<ClInclude Include="input\ShortcutManager.h" />
|
||||
<ClInclude Include="interface\Dropdown.h" />
|
||||
|
@ -92,6 +93,7 @@
|
|||
<ClCompile Include="drawing\engines\opengl\TransparencyDepth.cpp" />
|
||||
<ClCompile Include="drawing\engines\SoftwareDrawingEngine.cpp" />
|
||||
<ClCompile Include="input\Input.cpp" />
|
||||
<ClCompile Include="input\InputManager.cpp" />
|
||||
<ClCompile Include="input\KeyboardShortcut.cpp" />
|
||||
<ClCompile Include="input\KeyboardShortcuts.cpp" />
|
||||
<ClCompile Include="input\MouseInput.cpp" />
|
||||
|
|
|
@ -35,12 +35,14 @@ static rct_widget window_shortcut_change_widgets[] = {
|
|||
{ 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_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
||||
|
||||
// 0x9A3F7C
|
||||
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.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
|
||||
|
|
Loading…
Reference in New Issue