diff --git a/app/gui/SettingsView.qml b/app/gui/SettingsView.qml index 48957801..ef6514c7 100644 --- a/app/gui/SettingsView.qml +++ b/app/gui/SettingsView.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.2 +import QtQuick.Window 2.2 import StreamingPreferences 1.0 import ComputerManager 1.0 @@ -25,6 +26,49 @@ Flickable { } } + function isChildOfFlickable(item) { + while (item) { + if (item.parent === contentItem) { + return true + } + + item = item.parent + } + return false + } + + NumberAnimation on contentY { + id: autoScrollAnimation + duration: 100 + } + + Window.onActiveFocusItemChanged: { + var item = Window.activeFocusItem + if (item) { + // Ignore non-child elements like the toolbar buttons + if (!isChildOfFlickable(item)) { + return + } + + // Map the focus item's position into our content item's coordinate space + var pos = item.mapToItem(contentItem, 0, 0) + + // Ensure some extra space is visible around the element we're scrolling to + var scrollMargin = height > 100 ? 50 : 0 + + if (pos.y - scrollMargin < contentY) { + autoScrollAnimation.from = contentY + autoScrollAnimation.to = Math.max(pos.y - scrollMargin, 0) + autoScrollAnimation.start() + } + else if (pos.y + item.height + scrollMargin > contentY + height) { + autoScrollAnimation.from = contentY + autoScrollAnimation.to = Math.min(pos.y + item.height + scrollMargin - height, contentHeight - height) + autoScrollAnimation.start() + } + } + } + StackView.onActivated: { // This enables Tab and BackTab based navigation rather than arrow keys. // It is required to shift focus between controls on the settings page. diff --git a/app/gui/sdlgamepadkeynavigation.cpp b/app/gui/sdlgamepadkeynavigation.cpp index ff978d9f..9d73ea64 100644 --- a/app/gui/sdlgamepadkeynavigation.cpp +++ b/app/gui/sdlgamepadkeynavigation.cpp @@ -239,31 +239,6 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() sendKey(QEvent::Type::KeyRelease, Qt::Key_Right); m_LastAxisNavigationEventTime = SDL_GetTicks(); } - - // In UI navigation mode (settings page), use the right stick to scroll - if (m_UiNavMode) { - short rightX = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTX); - short rightY = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTY); - - QPoint wheelDelta; - if (rightX > 30000) { - wheelDelta.setX(30); - } - else if (rightX < -30000) { - wheelDelta.setX(-30); - } - - if (rightY > 30000) { - wheelDelta.setY(-30); - } - else if (rightY < -30000) { - wheelDelta.setY(30); - } - - if (!wheelDelta.isNull()) { - sendWheel(wheelDelta); - } - } } } @@ -277,22 +252,6 @@ void SdlGamepadKeyNavigation::sendKey(QEvent::Type type, Qt::Key key, Qt::Keyboa } } -void SdlGamepadKeyNavigation::sendWheel(QPoint& angleDelta) -{ - QGuiApplication* app = static_cast(QGuiApplication::instance()); - QWindow* focusWindow = app->focusWindow(); - if (focusWindow != nullptr) { - QPoint mousePos(focusWindow->width() / 2, focusWindow->height() / 2); - QPoint globalPos(focusWindow->mapToGlobal(mousePos)); -#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) - QWheelEvent wheelEvent(mousePos, globalPos, QPoint(), angleDelta, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false, Qt::MouseEventSynthesizedByApplication); -#else - QWheelEvent wheelEvent(mousePos, globalPos, QPoint(), angleDelta, angleDelta.y(), Qt::Vertical, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, Qt::MouseEventSynthesizedByApplication, false); -#endif - app->sendEvent(focusWindow, &wheelEvent); - } -} - void SdlGamepadKeyNavigation::setUiNavMode(bool uiNavMode) { m_UiNavMode = uiNavMode; diff --git a/app/gui/sdlgamepadkeynavigation.h b/app/gui/sdlgamepadkeynavigation.h index f4e54a95..4fcb1c32 100644 --- a/app/gui/sdlgamepadkeynavigation.h +++ b/app/gui/sdlgamepadkeynavigation.h @@ -24,7 +24,6 @@ public: private: void sendKey(QEvent::Type type, Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier); - void sendWheel(QPoint& angleDelta); private slots: void onPollingTimerFired();