From 65c21f339213ad24abd88427ff847ec45af0ce31 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 19 May 2019 10:16:54 -0700 Subject: [PATCH] Improve gamepad navigation on settings page --- app/gui/AutoResizingComboBox.qml | 11 ++++++++ app/gui/SettingsView.qml | 6 ++-- app/gui/sdlgamepadkeynavigation.cpp | 44 ++++++----------------------- app/gui/sdlgamepadkeynavigation.h | 4 +-- 4 files changed, 25 insertions(+), 40 deletions(-) diff --git a/app/gui/AutoResizingComboBox.qml b/app/gui/AutoResizingComboBox.qml index 0924f3f2..41b81f91 100644 --- a/app/gui/AutoResizingComboBox.qml +++ b/app/gui/AutoResizingComboBox.qml @@ -1,6 +1,8 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 +import SdlGamepadKeyNavigation 1.0 + // https://stackoverflow.com/questions/45029968/how-do-i-set-the-combobox-width-to-fit-the-largest-item ComboBox { property int textWidth @@ -28,4 +30,13 @@ ComboBox { textWidth = Math.max(popupMetrics.width, textWidth) } } + + popup.onAboutToShow: { + // Switch to normal navigation for combo boxes + SdlGamepadKeyNavigation.setUiNavMode(false) + } + + popup.onAboutToHide: { + SdlGamepadKeyNavigation.setUiNavMode(true) + } } diff --git a/app/gui/SettingsView.qml b/app/gui/SettingsView.qml index 26f6c039..e9b331e4 100644 --- a/app/gui/SettingsView.qml +++ b/app/gui/SettingsView.qml @@ -25,11 +25,13 @@ Flickable { } StackView.onActivated: { - SdlGamepadKeyNavigation.setSettingsMode(true) + // This enables Tab and BackTab based navigation rather than arrow keys. + // It is required to shift focus between controls on the settings page. + SdlGamepadKeyNavigation.setUiNavMode(true) } StackView.onDeactivating: { - SdlGamepadKeyNavigation.setSettingsMode(false) + SdlGamepadKeyNavigation.setUiNavMode(false) // Save the prefs so the Session can observe the changes StreamingPreferences.save() diff --git a/app/gui/sdlgamepadkeynavigation.cpp b/app/gui/sdlgamepadkeynavigation.cpp index 76c13cd8..e048e4f4 100644 --- a/app/gui/sdlgamepadkeynavigation.cpp +++ b/app/gui/sdlgamepadkeynavigation.cpp @@ -10,7 +10,7 @@ SdlGamepadKeyNavigation::SdlGamepadKeyNavigation() : m_Enabled(false), - m_SettingsMode(false), + m_UiNavMode(false), m_LastAxisNavigationEventTime(0) { m_PollingTimer = new QTimer(this); @@ -106,7 +106,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() switch (event.cbutton.button) { case SDL_CONTROLLER_BUTTON_DPAD_UP: - if (m_SettingsMode) { + if (m_UiNavMode) { // Back-tab sendKey(type, Qt::Key_Tab, Qt::ShiftModifier); } @@ -115,7 +115,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() } break; case SDL_CONTROLLER_BUTTON_DPAD_DOWN: - if (m_SettingsMode) { + if (m_UiNavMode) { sendKey(type, Qt::Key_Tab); } else { @@ -124,24 +124,12 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() break; case SDL_CONTROLLER_BUTTON_DPAD_LEFT: sendKey(type, Qt::Key_Left); - if (m_SettingsMode) { - // Some settings controls respond to left/right (like the slider) - // and others respond to up/down (like combo boxes). They seem to - // be mutually exclusive though so let's just send both. - sendKey(type, Qt::Key_Up); - } break; case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: sendKey(type, Qt::Key_Right); - if (m_SettingsMode) { - // Some settings controls respond to left/right (like the slider) - // and others respond to up/down (like combo boxes). They seem to - // be mutually exclusive though so let's just send both. - sendKey(type, Qt::Key_Down); - } break; case SDL_CONTROLLER_BUTTON_A: - if (m_SettingsMode) { + if (m_UiNavMode) { sendKey(type, Qt::Key_Space); } else { @@ -183,7 +171,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() // Do nothing } else if (leftY < -30000) { - if (m_SettingsMode) { + if (m_UiNavMode) { // Back-tab sendKey(QEvent::Type::KeyPress, Qt::Key_Tab, Qt::ShiftModifier); sendKey(QEvent::Type::KeyRelease, Qt::Key_Tab, Qt::ShiftModifier); @@ -196,7 +184,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() m_LastAxisNavigationEventTime = SDL_GetTicks(); } else if (leftY > 30000) { - if (m_SettingsMode) { + if (m_UiNavMode) { sendKey(QEvent::Type::KeyPress, Qt::Key_Tab); sendKey(QEvent::Type::KeyRelease, Qt::Key_Tab); } @@ -210,27 +198,11 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() else if (leftX < -30000) { sendKey(QEvent::Type::KeyPress, Qt::Key_Left); sendKey(QEvent::Type::KeyRelease, Qt::Key_Left); - if (m_SettingsMode) { - // Some settings controls respond to left/right (like the slider) - // and others respond to up/down (like combo boxes). They seem to - // be mutually exclusive though so let's just send both. - sendKey(QEvent::Type::KeyPress, Qt::Key_Up); - sendKey(QEvent::Type::KeyRelease, Qt::Key_Up); - } - m_LastAxisNavigationEventTime = SDL_GetTicks(); } else if (leftX > 30000) { sendKey(QEvent::Type::KeyPress, Qt::Key_Right); sendKey(QEvent::Type::KeyRelease, Qt::Key_Right); - if (m_SettingsMode) { - // Some settings controls respond to left/right (like the slider) - // and others respond to up/down (like combo boxes). They seem to - // be mutually exclusive though so let's just send both. - sendKey(QEvent::Type::KeyPress, Qt::Key_Down); - sendKey(QEvent::Type::KeyRelease, Qt::Key_Down); - } - m_LastAxisNavigationEventTime = SDL_GetTicks(); } } @@ -246,9 +218,9 @@ void SdlGamepadKeyNavigation::sendKey(QEvent::Type type, Qt::Key key, Qt::Keyboa } } -void SdlGamepadKeyNavigation::setSettingsMode(bool settingsMode) +void SdlGamepadKeyNavigation::setUiNavMode(bool uiNavMode) { - m_SettingsMode = settingsMode; + m_UiNavMode = uiNavMode; } int SdlGamepadKeyNavigation::getConnectedGamepads() diff --git a/app/gui/sdlgamepadkeynavigation.h b/app/gui/sdlgamepadkeynavigation.h index 900b7edf..afb8154d 100644 --- a/app/gui/sdlgamepadkeynavigation.h +++ b/app/gui/sdlgamepadkeynavigation.h @@ -18,7 +18,7 @@ public: Q_INVOKABLE void disable(); - Q_INVOKABLE void setSettingsMode(bool settingsMode); + Q_INVOKABLE void setUiNavMode(bool settingsMode); Q_INVOKABLE int getConnectedGamepads(); @@ -32,6 +32,6 @@ private: QTimer* m_PollingTimer; QList m_Gamepads; bool m_Enabled; - bool m_SettingsMode; + bool m_UiNavMode; Uint32 m_LastAxisNavigationEventTime; };