Qt: Allow binding keyboard keys via fullscreen UI

This commit is contained in:
Connor McLaughlin 2021-03-08 01:39:46 +10:00
parent 39498cda10
commit a0e97059f5
9 changed files with 44 additions and 34 deletions

View file

@ -306,27 +306,25 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event)
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
{ {
// Binding mode
if (m_fullscreen_ui_enabled && m_controller_interface && m_controller_interface->HasHook() &&
event->key.repeat == 0)
{
String keyName;
if (!SDLKeyNames::KeyEventToString(event, keyName))
{
break;
}
const bool pressed = (event->type == SDL_KEYDOWN); const bool pressed = (event->type == SDL_KEYDOWN);
if (FullscreenUI::HandleKeyboardBinding(keyName, pressed))
// Binding mode
if (m_fullscreen_ui_enabled && FullscreenUI::IsBindingInput())
{ {
break; if (event->key.repeat > 0)
return;
TinyString key_string;
if (SDLKeyNames::KeyEventToString(event, key_string))
{
if (FullscreenUI::HandleKeyboardBinding(key_string, pressed))
return;
} }
} }
if (!ImGui::GetIO().WantCaptureKeyboard && event->key.repeat == 0) if (!ImGui::GetIO().WantCaptureKeyboard && event->key.repeat == 0)
{ {
const u32 code = SDLKeyNames::KeyEventToInt(event); const u32 code = SDLKeyNames::KeyEventToInt(event);
const bool pressed = (event->type == SDL_KEYDOWN);
HandleHostKeyEvent(code & SDLKeyNames::KEY_MASK, code & SDLKeyNames::MODIFIER_MASK, pressed); HandleHostKeyEvent(code & SDLKeyNames::KEY_MASK, code & SDLKeyNames::MODIFIER_MASK, pressed);
} }
} }

View file

@ -47,7 +47,8 @@ bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event)
} }
else if (event_type == QEvent::KeyPress) else if (event_type == QEvent::KeyPress)
{ {
QString binding = QtUtils::KeyEventToString(static_cast<QKeyEvent*>(event)); const QKeyEvent* key_event = static_cast<const QKeyEvent*>(event);
const QString binding(QtUtils::KeyEventToString(key_event->key(), key_event->modifiers()));
if (!binding.isEmpty()) if (!binding.isEmpty())
m_new_binding_value = QStringLiteral("Keyboard/%1").arg(binding).toStdString(); m_new_binding_value = QStringLiteral("Keyboard/%1").arg(binding).toStdString();

View file

@ -36,7 +36,7 @@ void InputBindingWidget::updateText()
if (m_bindings.empty()) if (m_bindings.empty())
setText(QString()); setText(QString());
else if (m_bindings.size() > 1) else if (m_bindings.size() > 1)
setText(tr("%n bindings", "", m_bindings.size())); setText(tr("%n bindings", "", static_cast<int>(m_bindings.size())));
else else
setText(QString::fromStdString(m_bindings[0])); setText(QString::fromStdString(m_bindings[0]));
} }
@ -94,7 +94,8 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event)
} }
else if (event_type == QEvent::KeyPress) else if (event_type == QEvent::KeyPress)
{ {
QString binding = QtUtils::KeyEventToString(static_cast<QKeyEvent*>(event)); const QKeyEvent* key_event = static_cast<const QKeyEvent*>(event);
const QString binding(QtUtils::KeyEventToString(key_event->key(), key_event->modifiers()));
if (!binding.isEmpty()) if (!binding.isEmpty())
m_new_binding_value = QStringLiteral("Keyboard/%1").arg(binding).toStdString(); m_new_binding_value = QStringLiteral("Keyboard/%1").arg(binding).toStdString();

View file

@ -129,7 +129,10 @@ bool QtDisplayWidget::event(QEvent* event)
{ {
const QKeyEvent* key_event = static_cast<QKeyEvent*>(event); const QKeyEvent* key_event = static_cast<QKeyEvent*>(event);
if (!key_event->isAutoRepeat()) if (!key_event->isAutoRepeat())
emit windowKeyEvent(QtUtils::KeyEventToInt(key_event), event->type() == QEvent::KeyPress); {
emit windowKeyEvent(key_event->key(), static_cast<int>(key_event->modifiers()),
event->type() == QEvent::KeyPress);
}
return true; return true;
} }

View file

@ -27,7 +27,7 @@ Q_SIGNALS:
void windowResizedEvent(int width, int height); void windowResizedEvent(int width, int height);
void windowRestoredEvent(); void windowRestoredEvent();
void windowClosedEvent(); void windowClosedEvent();
void windowKeyEvent(int key_code, bool pressed); void windowKeyEvent(int key_code, int mods, bool pressed);
void windowMouseMoveEvent(int x, int y); void windowMouseMoveEvent(int x, int y);
void windowMouseButtonEvent(int button, bool pressed); void windowMouseButtonEvent(int button, bool pressed);
void windowMouseWheelEvent(const QPoint& angle_delta); void windowMouseWheelEvent(const QPoint& angle_delta);

View file

@ -9,6 +9,7 @@
#include "core/controller.h" #include "core/controller.h"
#include "core/gpu.h" #include "core/gpu.h"
#include "core/system.h" #include "core/system.h"
#include "frontend-common/fullscreen_ui.h"
#include "frontend-common/game_list.h" #include "frontend-common/game_list.h"
#include "frontend-common/imgui_fullscreen.h" #include "frontend-common/imgui_fullscreen.h"
#include "frontend-common/imgui_styles.h" #include "frontend-common/imgui_styles.h"
@ -29,6 +30,7 @@
#include <QtCore/QFile> #include <QtCore/QFile>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtCore/QTranslator> #include <QtCore/QTranslator>
#include <QtGui/QKeyEvent>
#include <QtWidgets/QFileDialog> #include <QtWidgets/QFileDialog>
#include <QtWidgets/QMenu> #include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox> #include <QtWidgets/QMessageBox>
@ -373,20 +375,30 @@ void QtHostInterface::resumeSystemFromMostRecentState()
loadState(QString::fromStdString(state_filename)); loadState(QString::fromStdString(state_filename));
} }
void QtHostInterface::onDisplayWindowKeyEvent(int key, bool pressed) void QtHostInterface::onDisplayWindowKeyEvent(int key, int mods, bool pressed)
{ {
DebugAssert(isOnWorkerThread()); DebugAssert(isOnWorkerThread());
ImGuiIO& io = ImGui::GetIO();
const u32 masked_key = static_cast<u32>(key) & IMGUI_KEY_MASK; const u32 masked_key = static_cast<u32>(key) & IMGUI_KEY_MASK;
if (masked_key < countof(ImGuiIO::KeysDown)) if (masked_key < countof(ImGuiIO::KeysDown))
{
ImGuiIO& io = ImGui::GetIO();
io.KeysDown[masked_key] = pressed; io.KeysDown[masked_key] = pressed;
if (io.WantCaptureKeyboard)
if (m_fullscreen_ui_enabled && FullscreenUI::IsBindingInput())
{
QString key_string(QtUtils::KeyEventToString(key, static_cast<Qt::KeyboardModifier>(mods)));
if (!key_string.isEmpty())
{
if (FullscreenUI::HandleKeyboardBinding(key_string.toUtf8().constData(), pressed))
return; return;
} }
}
HandleHostKeyEvent(key & ~Qt::KeyboardModifierMask, key & Qt::KeyboardModifierMask, pressed); if (io.WantCaptureKeyboard)
return;
const int key_id = QtUtils::KeyEventToInt(key, static_cast<Qt::KeyboardModifier>(mods));
HandleHostKeyEvent(key_id & ~Qt::KeyboardModifierMask, key_id & Qt::KeyboardModifierMask, pressed);
} }
void QtHostInterface::onDisplayWindowMouseMoveEvent(int x, int y) void QtHostInterface::onDisplayWindowMouseMoveEvent(int x, int y)

View file

@ -183,7 +183,7 @@ private Q_SLOTS:
void onDisplayWindowMouseWheelEvent(const QPoint& delta_angle); void onDisplayWindowMouseWheelEvent(const QPoint& delta_angle);
void onDisplayWindowResized(int width, int height); void onDisplayWindowResized(int width, int height);
void onDisplayWindowFocused(); void onDisplayWindowFocused();
void onDisplayWindowKeyEvent(int key, bool pressed); void onDisplayWindowKeyEvent(int key, int mods, bool pressed);
void doBackgroundControllerPoll(); void doBackgroundControllerPoll();
void doSaveSettings(); void doSaveSettings();

View file

@ -578,15 +578,13 @@ std::optional<int> GetKeyIdForIdentifier(const QString& key_identifier)
return std::nullopt; return std::nullopt;
} }
QString KeyEventToString(const QKeyEvent* ke) QString KeyEventToString(int key, Qt::KeyboardModifiers mods)
{ {
const int key = ke->key();
QString key_name = GetKeyIdentifier(key); QString key_name = GetKeyIdentifier(key);
if (key_name.isEmpty()) if (key_name.isEmpty())
return {}; return {};
QString ret; QString ret;
const Qt::KeyboardModifiers mods = ke->modifiers();
for (const QtKeyModifierEntry& mod : s_qt_key_modifiers) for (const QtKeyModifierEntry& mod : s_qt_key_modifiers)
{ {
if (mods & mod.mod && key != mod.key) if (mods & mod.mod && key != mod.key)
@ -628,11 +626,8 @@ std::optional<int> ParseKeyString(const QString& key_str)
return ret; return ret;
} }
int KeyEventToInt(const QKeyEvent* ke) int KeyEventToInt(int key, Qt::KeyboardModifiers mods)
{ {
const Qt::KeyboardModifiers mods = ke->modifiers();
const int key = ke->key();
int val = key; int val = key;
if (mods != 0) if (mods != 0)
{ {

View file

@ -40,13 +40,13 @@ QString GetKeyIdentifier(int key);
std::optional<int> GetKeyIdForIdentifier(const QString& key_identifier); std::optional<int> GetKeyIdForIdentifier(const QString& key_identifier);
/// Stringizes a key event. /// Stringizes a key event.
QString KeyEventToString(const QKeyEvent* ke); QString KeyEventToString(int key, Qt::KeyboardModifiers mods);
/// Returns an integer id for a stringized key event. Modifiers are in the upper bits. /// Returns an integer id for a stringized key event. Modifiers are in the upper bits.
std::optional<int> ParseKeyString(const QString& key_str); std::optional<int> ParseKeyString(const QString& key_str);
/// Returns a key id for a key event, including any modifiers. /// Returns a key id for a key event, including any modifiers.
int KeyEventToInt(const QKeyEvent* ke); int KeyEventToInt(int key, Qt::KeyboardModifiers mods);
/// Reads a whole stream to a Qt byte array. /// Reads a whole stream to a Qt byte array.
QByteArray ReadStreamToQByteArray(ByteStream* stream, bool rewind = false); QByteArray ReadStreamToQByteArray(ByteStream* stream, bool rewind = false);