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_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);
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)
{
const u32 code = SDLKeyNames::KeyEventToInt(event);
const bool pressed = (event->type == SDL_KEYDOWN);
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)
{
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())
m_new_binding_value = QStringLiteral("Keyboard/%1").arg(binding).toStdString();

View file

@ -36,7 +36,7 @@ void InputBindingWidget::updateText()
if (m_bindings.empty())
setText(QString());
else if (m_bindings.size() > 1)
setText(tr("%n bindings", "", m_bindings.size()));
setText(tr("%n bindings", "", static_cast<int>(m_bindings.size())));
else
setText(QString::fromStdString(m_bindings[0]));
}
@ -94,7 +94,8 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event)
}
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())
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);
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;
}

View file

@ -27,7 +27,7 @@ Q_SIGNALS:
void windowResizedEvent(int width, int height);
void windowRestoredEvent();
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 windowMouseButtonEvent(int button, bool pressed);
void windowMouseWheelEvent(const QPoint& angle_delta);

View file

@ -9,6 +9,7 @@
#include "core/controller.h"
#include "core/gpu.h"
#include "core/system.h"
#include "frontend-common/fullscreen_ui.h"
#include "frontend-common/game_list.h"
#include "frontend-common/imgui_fullscreen.h"
#include "frontend-common/imgui_styles.h"
@ -29,6 +30,7 @@
#include <QtCore/QFile>
#include <QtCore/QTimer>
#include <QtCore/QTranslator>
#include <QtGui/QKeyEvent>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMessageBox>
@ -373,20 +375,30 @@ void QtHostInterface::resumeSystemFromMostRecentState()
loadState(QString::fromStdString(state_filename));
}
void QtHostInterface::onDisplayWindowKeyEvent(int key, bool pressed)
void QtHostInterface::onDisplayWindowKeyEvent(int key, int mods, bool pressed)
{
DebugAssert(isOnWorkerThread());
ImGuiIO& io = ImGui::GetIO();
const u32 masked_key = static_cast<u32>(key) & IMGUI_KEY_MASK;
if (masked_key < countof(ImGuiIO::KeysDown))
{
ImGuiIO& io = ImGui::GetIO();
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;
}
}
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)

View file

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

View file

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

View file

@ -40,13 +40,13 @@ QString GetKeyIdentifier(int key);
std::optional<int> GetKeyIdForIdentifier(const QString& key_identifier);
/// 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.
std::optional<int> ParseKeyString(const QString& key_str);
/// 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.
QByteArray ReadStreamToQByteArray(ByteStream* stream, bool rewind = false);