From 25e0f99f43faadb68222029de54837579adf0b99 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Thu, 28 Oct 2021 21:54:52 -0400 Subject: [PATCH] homescreen: Add swipe down panel gesture --- .../qml/private/DragGestureHandler.qml | 21 ++++++ components/mobileshell/TopPanelControls.qml | 5 ++ .../homescreen/package/contents/ui/main.qml | 3 +- .../panel/package/contents/ui/main.qml | 65 +++++++++++++------ 4 files changed, 72 insertions(+), 22 deletions(-) diff --git a/components/mobilehomescreencomponents/qml/private/DragGestureHandler.qml b/components/mobilehomescreencomponents/qml/private/DragGestureHandler.qml index 0655795c..94069f3d 100644 --- a/components/mobilehomescreencomponents/qml/private/DragGestureHandler.qml +++ b/components/mobilehomescreencomponents/qml/private/DragGestureHandler.qml @@ -8,6 +8,7 @@ import QtQuick 2.14 import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.private.mobileshell 1.0 as MobileShell import ".." as Launcher @@ -29,6 +30,7 @@ DragHandler { } property real __initialMainFlickableX + property real __oldTranslationY: 0 property int __scrollDirection: DragGestureHandler.None onTranslationChanged: { if (active) { @@ -50,7 +52,20 @@ DragHandler { } if (__scrollDirection !== DragGestureHandler.Left && __scrollDirection !== DragGestureHandler.Right) { + // if swipe up, scroll app drawer root.appDrawer.flickable.contentY = Math.min(root.appDrawer.drawerTopMargin, Math.max(0, -translation.y)); + + if (translation.y < 0 && MobileShell.TopPanelControls.inSwipe) { + MobileShell.TopPanelControls.endSwipe(); + } + + // if swipe down, scroll top panel + if (translation.y > 0) { + if (!MobileShell.TopPanelControls.inSwipe) { + MobileShell.TopPanelControls.startSwipe(); + } + MobileShell.TopPanelControls.requestRelativeScroll(translation.y - __oldTranslationY); + } } } if (__scrollDirection !== DragGestureHandler.Vertical) { @@ -67,7 +82,10 @@ DragHandler { mainFlickable.contentX = newContentX; } } + + __oldTranslationY = translation.y; } + onActiveChanged: { if (active) { __initialMainFlickableX = mainFlickable.contentX; @@ -75,6 +93,9 @@ DragHandler { if (root.appDrawer) { root.appDrawer.snapDrawerStatus(); } + if (MobileShell.TopPanelControls.inSwipe) { + MobileShell.TopPanelControls.endSwipe(); + } if (__scrollDirection === DragGestureHandler.Left && (__initialMainFlickableX - mainFlickable.contentX > PlasmaCore.Units.gridUnit * 5)) { snapPrevPage(); } else if (__scrollDirection === DragGestureHandler.Right && (mainFlickable.contentX - __initialMainFlickableX > PlasmaCore.Units.gridUnit * 5)) { diff --git a/components/mobileshell/TopPanelControls.qml b/components/mobileshell/TopPanelControls.qml index 93d62f74..1712cf67 100644 --- a/components/mobileshell/TopPanelControls.qml +++ b/components/mobileshell/TopPanelControls.qml @@ -11,5 +11,10 @@ pragma Singleton QtObject { id: root + + signal startSwipe() + signal endSwipe() + signal requestRelativeScroll(real offsetY) + property bool inSwipe: false property real panelHeight: PlasmaCore.Units.gridUnit // set and updated in panel containment } diff --git a/containments/homescreen/package/contents/ui/main.qml b/containments/homescreen/package/contents/ui/main.qml index f7d1b745..3cc09b14 100644 --- a/containments/homescreen/package/contents/ui/main.qml +++ b/containments/homescreen/package/contents/ui/main.qml @@ -39,7 +39,7 @@ FocusScope { //END functions - // implement API signals +//BEGIN API implementation Connections { target: MobileShell.HomeScreenControls @@ -60,6 +60,7 @@ FocusScope { lastRequestedPosition = pos.y; } } +//END API implementation property bool componentComplete: false onWidthChanged: recalculateMaxFavoriteCount() diff --git a/containments/panel/package/contents/ui/main.qml b/containments/panel/package/contents/ui/main.qml index fba64f23..d1fa759d 100644 --- a/containments/panel/package/contents/ui/main.qml +++ b/containments/panel/package/contents/ui/main.qml @@ -34,19 +34,34 @@ Item { width: 480 height: PlasmaCore.Units.gridUnit - // set height binding to top panel API - Binding { - target: MobileShell.TopPanelControls - property: "panelHeight" - value: root.height - } +//BEGIN API implementation - // set height binding to top panel API Binding { target: MobileShell.TopPanelControls property: "panelHeight" value: root.height } + Binding { + target: MobileShell.TopPanelControls + property: "inSwipe" + value: slidingPanel.userInteracting + } + + Connections { + target: MobileShell.TopPanelControls + + function onStartSwipe() { + swipeMouseArea.startSwipe(0); + } + function onEndSwipe() { + swipeMouseArea.endSwipe(); + } + function onRequestRelativeScroll(offsetY) { + swipeMouseArea.updateOffset(offsetY); + } + } + +//END API implementation Plasmoid.backgroundHints: showingApp ? PlasmaCore.Types.StandardBackground : PlasmaCore.Types.NoBackground @@ -196,31 +211,39 @@ Item { showDropShadow: !showingApp } - // initial swipe down + // initial swipe down gesture MouseArea { + id: swipeMouseArea z: 99 property int oldMouseY: 0 - anchors.fill: parent - onPressed: { + function startSwipe(mouseX) { slidingPanel.cancelAnimations(); - slidingPanel.drawerX = Math.min(Math.max(0, mouse.x - slidingPanel.drawerWidth/2), slidingPanel.width - slidingPanel.contentItem.width) + slidingPanel.drawerX = Math.min(Math.max(0, mouseX - slidingPanel.drawerWidth/2), slidingPanel.width - slidingPanel.contentItem.width) slidingPanel.userInteracting = true; slidingPanel.flickable.contentY = slidingPanel.closedContentY; - oldMouseY = mouse.y; slidingPanel.visible = true; } - onPositionChanged: { - slidingPanel.updateOffset(mouse.y - oldMouseY); + + function endSwipe() { + slidingPanel.userInteracting = false; + slidingPanel.updateState(); + } + + function updateOffset(offsetY) { + slidingPanel.updateOffset(offsetY); + } + + anchors.fill: parent + onPressed: { oldMouseY = mouse.y; + startSwipe(mouse.x); } - onReleased: { - slidingPanel.userInteracting = false; - slidingPanel.updateState(); - } - onCanceled: { - slidingPanel.userInteracting = false; - slidingPanel.updateState(); + onReleased: endSwipe() + onCanceled: endSwipe() + onPositionChanged: { + updateOffset(mouse.y - oldMouseY); + oldMouseY = mouse.y; } }