Improve gamepad navigation on settings page

This commit is contained in:
Cameron Gutman 2019-05-19 10:16:54 -07:00
parent 97fb30cdf1
commit 65c21f3392
4 changed files with 25 additions and 40 deletions

View file

@ -1,6 +1,8 @@
import QtQuick 2.9 import QtQuick 2.9
import QtQuick.Controls 2.2 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 // https://stackoverflow.com/questions/45029968/how-do-i-set-the-combobox-width-to-fit-the-largest-item
ComboBox { ComboBox {
property int textWidth property int textWidth
@ -28,4 +30,13 @@ ComboBox {
textWidth = Math.max(popupMetrics.width, textWidth) textWidth = Math.max(popupMetrics.width, textWidth)
} }
} }
popup.onAboutToShow: {
// Switch to normal navigation for combo boxes
SdlGamepadKeyNavigation.setUiNavMode(false)
}
popup.onAboutToHide: {
SdlGamepadKeyNavigation.setUiNavMode(true)
}
} }

View file

@ -25,11 +25,13 @@ Flickable {
} }
StackView.onActivated: { 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: { StackView.onDeactivating: {
SdlGamepadKeyNavigation.setSettingsMode(false) SdlGamepadKeyNavigation.setUiNavMode(false)
// Save the prefs so the Session can observe the changes // Save the prefs so the Session can observe the changes
StreamingPreferences.save() StreamingPreferences.save()

View file

@ -10,7 +10,7 @@
SdlGamepadKeyNavigation::SdlGamepadKeyNavigation() SdlGamepadKeyNavigation::SdlGamepadKeyNavigation()
: m_Enabled(false), : m_Enabled(false),
m_SettingsMode(false), m_UiNavMode(false),
m_LastAxisNavigationEventTime(0) m_LastAxisNavigationEventTime(0)
{ {
m_PollingTimer = new QTimer(this); m_PollingTimer = new QTimer(this);
@ -106,7 +106,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
switch (event.cbutton.button) { switch (event.cbutton.button) {
case SDL_CONTROLLER_BUTTON_DPAD_UP: case SDL_CONTROLLER_BUTTON_DPAD_UP:
if (m_SettingsMode) { if (m_UiNavMode) {
// Back-tab // Back-tab
sendKey(type, Qt::Key_Tab, Qt::ShiftModifier); sendKey(type, Qt::Key_Tab, Qt::ShiftModifier);
} }
@ -115,7 +115,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
} }
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
if (m_SettingsMode) { if (m_UiNavMode) {
sendKey(type, Qt::Key_Tab); sendKey(type, Qt::Key_Tab);
} }
else { else {
@ -124,24 +124,12 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
break; break;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
sendKey(type, Qt::Key_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; break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
sendKey(type, Qt::Key_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; break;
case SDL_CONTROLLER_BUTTON_A: case SDL_CONTROLLER_BUTTON_A:
if (m_SettingsMode) { if (m_UiNavMode) {
sendKey(type, Qt::Key_Space); sendKey(type, Qt::Key_Space);
} }
else { else {
@ -183,7 +171,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
// Do nothing // Do nothing
} }
else if (leftY < -30000) { else if (leftY < -30000) {
if (m_SettingsMode) { if (m_UiNavMode) {
// Back-tab // Back-tab
sendKey(QEvent::Type::KeyPress, Qt::Key_Tab, Qt::ShiftModifier); sendKey(QEvent::Type::KeyPress, Qt::Key_Tab, Qt::ShiftModifier);
sendKey(QEvent::Type::KeyRelease, 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(); m_LastAxisNavigationEventTime = SDL_GetTicks();
} }
else if (leftY > 30000) { else if (leftY > 30000) {
if (m_SettingsMode) { if (m_UiNavMode) {
sendKey(QEvent::Type::KeyPress, Qt::Key_Tab); sendKey(QEvent::Type::KeyPress, Qt::Key_Tab);
sendKey(QEvent::Type::KeyRelease, Qt::Key_Tab); sendKey(QEvent::Type::KeyRelease, Qt::Key_Tab);
} }
@ -210,27 +198,11 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
else if (leftX < -30000) { else if (leftX < -30000) {
sendKey(QEvent::Type::KeyPress, Qt::Key_Left); sendKey(QEvent::Type::KeyPress, Qt::Key_Left);
sendKey(QEvent::Type::KeyRelease, 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(); m_LastAxisNavigationEventTime = SDL_GetTicks();
} }
else if (leftX > 30000) { else if (leftX > 30000) {
sendKey(QEvent::Type::KeyPress, Qt::Key_Right); sendKey(QEvent::Type::KeyPress, Qt::Key_Right);
sendKey(QEvent::Type::KeyRelease, 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(); 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() int SdlGamepadKeyNavigation::getConnectedGamepads()

View file

@ -18,7 +18,7 @@ public:
Q_INVOKABLE void disable(); Q_INVOKABLE void disable();
Q_INVOKABLE void setSettingsMode(bool settingsMode); Q_INVOKABLE void setUiNavMode(bool settingsMode);
Q_INVOKABLE int getConnectedGamepads(); Q_INVOKABLE int getConnectedGamepads();
@ -32,6 +32,6 @@ private:
QTimer* m_PollingTimer; QTimer* m_PollingTimer;
QList<SDL_GameController*> m_Gamepads; QList<SDL_GameController*> m_Gamepads;
bool m_Enabled; bool m_Enabled;
bool m_SettingsMode; bool m_UiNavMode;
Uint32 m_LastAxisNavigationEventTime; Uint32 m_LastAxisNavigationEventTime;
}; };