Add overswipe gesture

This commit is contained in:
Devin Lin 2021-10-24 00:16:38 -04:00
parent 43c327655d
commit dcbdf8f101
4 changed files with 74 additions and 42 deletions

View file

@ -16,7 +16,8 @@ QtObject {
signal resetHomeScreenPosition() signal resetHomeScreenPosition()
signal snapHomeScreenPosition() signal snapHomeScreenPosition()
signal requestRelativeScroll(point pos) signal requestRelativeScroll(point pos)
signal setHomeScreenOpacity(int opacity) signal hideHomeScreen(bool animate)
signal showHomeScreen(bool animate)
property Item homeScreen property Item homeScreen
property QtObject homeScreenWindow property QtObject homeScreenWindow
property bool homeScreenVisible: true property bool homeScreenVisible: true

View file

@ -61,13 +61,29 @@ FocusScope {
} }
} }
opacity: 1 opacity: 1
Behavior on opacity {
NumberAnimation { duration: PlasmaCore.Units.shortDuration } NumberAnimation on opacity {
id: opacityAnimation
duration: PlasmaCore.Units.longDuration
} }
Connections { Connections {
target: MobileShell.HomeScreenControls target: MobileShell.HomeScreenControls
function onSetHomeScreenOpacity(opacity) { function onHideHomeScreen(animate) {
root.opacity = opacity; if (animate) {
opacityAnimation.to = 0;
opacityAnimation.restart();
} else {
root.opacity = 0;
}
}
function onShowHomeScreen(animate) {
if (animate) {
opacityAnimation.to = 1;
opacityAnimation.restart();
} else {
root.opacity = 1;
}
} }
} }

View file

@ -28,11 +28,16 @@ NanoShell.FullScreenOverlay {
property TaskManager.TasksModel model property TaskManager.TasksModel model
// properties controlled from main.qml MouseArea (swipe to open gesture) // properties controlled from main.qml MouseArea (swipe to open gesture)
property real oldOffset: 0 property real oldYOffset: 0
property real offset: 0 property real yOffset: 0
readonly property real targetOffsetDist: window.height - tasksView.height // offset distance to perfect opening // offset constants
readonly property real targetYOffsetDist: window.height - tasksView.height // offset distance to perfect opening
readonly property real dismissYOffsetDist: window.height
// set from main.qml
property bool wasInActiveTask: false // whether we were in an app before opening the task switcher property bool wasInActiveTask: false // whether we were in an app before opening the task switcher
property bool currentlyDragging: false // whether we are in a swipe up gesture
Component.onCompleted: plasmoid.nativeInterface.panel = window; Component.onCompleted: plasmoid.nativeInterface.panel = window;
@ -47,7 +52,11 @@ NanoShell.FullScreenOverlay {
window.contentItem.opacity = 1; window.contentItem.opacity = 1;
} }
// hide homescreen elements to make use of wallpaper // hide homescreen elements to make use of wallpaper
MobileShell.HomeScreenControls.setHomeScreenOpacity(visible ? 0 : 1); if (visible) {
MobileShell.HomeScreenControls.hideHomeScreen(!window.wasInActiveTask); // only animate if going from homescreen
} else {
MobileShell.HomeScreenControls.showHomeScreen(true);
}
MobileShell.HomeScreenControls.taskSwitcherVisible = visible; MobileShell.HomeScreenControls.taskSwitcherVisible = visible;
} }
@ -62,7 +71,7 @@ NanoShell.FullScreenOverlay {
Rectangle { Rectangle {
id: backgroundRect id: backgroundRect
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.6 * (window.wasInActiveTask ? 1 : Math.min(1, window.offset / window.targetOffsetDist))) color: Qt.rgba(0, 0, 0, 0.6 * (window.wasInActiveTask ? 1 : Math.min(1, window.yOffset / window.targetYOffsetDist)))
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@ -72,7 +81,7 @@ NanoShell.FullScreenOverlay {
//BEGIN functions //BEGIN functions
function show(animation) { function show(animation) {
window.offset = 0; window.yOffset = 0;
window.wasInActiveTask = window.model.activeTask.row >= 0; window.wasInActiveTask = window.model.activeTask.row >= 0;
// skip to first active task // skip to first active task
@ -85,7 +94,7 @@ NanoShell.FullScreenOverlay {
// animate app shrink // animate app shrink
if (animation) { if (animation) {
offsetAnimator.to = window.targetOffsetDist; offsetAnimator.to = window.targetYOffsetDist;
offsetAnimator.restart(); offsetAnimator.restart();
} }
} }
@ -95,11 +104,12 @@ NanoShell.FullScreenOverlay {
} }
function snapOffset() { function snapOffset() {
let opening = window.offset > window.oldOffset; let movingUp = window.yOffset > window.oldYOffset;
if (opening || window.offset >= window.targetOffsetDist) {
offsetAnimator.to = window.targetOffsetDist; if (movingUp || window.yOffset >= window.targetYOffsetDist) { // open task switcher and stay
offsetAnimator.to = window.targetYOffsetDist;
offsetAnimator.restart(); offsetAnimator.restart();
} else { } else { // close task switcher and return to app
if (!window.wasInActiveTask) { // if pulled up from homescreen, don't activate app if (!window.wasInActiveTask) { // if pulled up from homescreen, don't activate app
offsetAnimator.activateApp = false; offsetAnimator.activateApp = false;
} }
@ -139,7 +149,7 @@ NanoShell.FullScreenOverlay {
//END functions //END functions
// animate app grow and shrink // animate app grow and shrink
NumberAnimation on offset { NumberAnimation on yOffset {
id: offsetAnimator id: offsetAnimator
duration: PlasmaCore.Units.longDuration duration: PlasmaCore.Units.longDuration
easing.type: Easing.InOutQuad easing.type: Easing.InOutQuad
@ -148,7 +158,7 @@ NanoShell.FullScreenOverlay {
// states of to: // states of to:
// 0 - open/resume app (zoom up the thumbnail) // 0 - open/resume app (zoom up the thumbnail)
// window.targetOffsetDist - animate shrinking of thumbnail, to listview (open task switcher) // window.targetYOffsetDist - animate shrinking of thumbnail, to listview (open task switcher)
to: 0 to: 0
onFinished: { onFinished: {
if (to === 0) { // close task switcher, and switch to current app if (to === 0) { // close task switcher, and switch to current app
@ -159,6 +169,8 @@ NanoShell.FullScreenOverlay {
setSingleActiveWindow(window.currentTaskIndex); setSingleActiveWindow(window.currentTaskIndex);
} }
activateApp = true; activateApp = true;
} else if (to == window.dismissYOffsetDist) {
window.hide();
} }
} }
} }
@ -166,7 +178,7 @@ NanoShell.FullScreenOverlay {
ListView { ListView {
id: tasksView id: tasksView
z: 100 z: 100
opacity: window.wasInActiveTask ? 1 : Math.min(1, window.offset / window.targetOffsetDist) opacity: window.wasInActiveTask ? 1 : Math.min(1, window.yOffset / window.targetYOffsetDist)
property real horizontalMargin: PlasmaCore.Units.gridUnit * 3 property real horizontalMargin: PlasmaCore.Units.gridUnit * 3
anchors.centerIn: parent anchors.centerIn: parent
@ -175,6 +187,18 @@ NanoShell.FullScreenOverlay {
height: window.height - (MobileShell.TopPanelControls.panelHeight + window.panelHeight + footerButtons.height height: window.height - (MobileShell.TopPanelControls.panelHeight + window.panelHeight + footerButtons.height
+ PlasmaCore.Units.gridUnit * 2 + PlasmaCore.Units.largeSpacing * 2) + PlasmaCore.Units.gridUnit * 2 + PlasmaCore.Units.largeSpacing * 2)
// scale gesture
scale: {
if (window.wasInActiveTask || !taskSwitcher.currentlyDragging) {
let maxScale = 1 / tasksView.scalingFactor;
let subtract = (maxScale - 1) * (window.yOffset / window.targetYOffsetDist);
let finalScale = Math.max(0, Math.min(maxScale, maxScale - subtract));
return finalScale;
}
return 1;
}
// ensure that window previews are exactly to the scale of the device screen // ensure that window previews are exactly to the scale of the device screen
property real windowHeight: window.height - window.panelHeight - MobileShell.TopPanelControls.panelHeight property real windowHeight: window.height - window.panelHeight - MobileShell.TopPanelControls.panelHeight
property real scalingFactor: { property real scalingFactor: {
@ -229,18 +253,6 @@ NanoShell.FullScreenOverlay {
// ensure that window previews are exactly to the scale of the device screen // ensure that window previews are exactly to the scale of the device screen
previewWidth: tasksView.scalingFactor * window.width previewWidth: tasksView.scalingFactor * window.width
previewHeight: tasksView.scalingFactor * tasksView.windowHeight previewHeight: tasksView.scalingFactor * tasksView.windowHeight
// swipe gesture
scale: {
if (task.curIndex === window.currentTaskIndex && window.wasInActiveTask /* TODO activate from homescreen */) {
let maxScale = 1 / tasksView.scalingFactor;
let subtract = (maxScale - 1) * (window.offset / window.targetOffsetDist);
let finalScale = Math.max(1, Math.min(maxScale, maxScale - subtract));
return finalScale;
}
return 1;
}
} }
} }

View file

@ -98,7 +98,6 @@ PlasmaCore.ColorScope {
property int startMouseY: 0 property int startMouseY: 0
property int oldMouseX: 0 property int oldMouseX: 0
property int startMouseX: 0 property int startMouseX: 0
property bool isDragging: false
property bool opening: false property bool opening: false
drag.filterChildren: true drag.filterChildren: true
property Button activeButton property Button activeButton
@ -113,24 +112,28 @@ PlasmaCore.ColorScope {
if (newButton != activeButton) { if (newButton != activeButton) {
activeButton = null; activeButton = null;
} }
if (!isDragging && Math.abs(startMouseY - oldMouseY) < root.height) {
if (!taskSwitcher.currentlyDragging && Math.abs(startMouseY - oldMouseY) < root.height) {
oldMouseY = mouse.y; oldMouseY = mouse.y;
return; return;
} else { } else if (mainMouseArea.pressed) {
isDragging = true; taskSwitcher.currentlyDragging = true;
} }
taskSwitcher.oldOffset = taskSwitcher.offset // update offsets with drags
taskSwitcher.offset = Math.max(0, taskSwitcher.offset - (mouse.y - oldMouseY)); taskSwitcher.oldYOffset = taskSwitcher.yOffset;
taskSwitcher.yOffset = Math.max(0, taskSwitcher.yOffset - (mouse.y - oldMouseY));
opening = oldMouseY > mouse.y; opening = oldMouseY > mouse.y;
if (taskSwitcher.visibility == Window.Hidden && Math.abs(startMouseY - mouse.y) > PlasmaCore.Units.gridUnit && taskSwitcher.tasksCount) { if (taskSwitcher.visibility == Window.Hidden && Math.abs(startMouseY - mouse.y) > PlasmaCore.Units.gridUnit && taskSwitcher.tasksCount) {
// start task switcher gesture
activeButton = null; activeButton = null;
taskSwitcher.show(false); taskSwitcher.show(false);
} else if (taskSwitcher.tasksCount === 0) { } else if (taskSwitcher.tasksCount === 0) { // no tasks, let's scroll up the homescreen instead
//no tasks, let's scroll up the homescreen instead
MobileShell.HomeScreenControls.requestRelativeScroll(Qt.point(mouse.x - oldMouseX, mouse.y - oldMouseY)); MobileShell.HomeScreenControls.requestRelativeScroll(Qt.point(mouse.x - oldMouseX, mouse.y - oldMouseY));
} }
oldMouseY = mouse.y; oldMouseY = mouse.y;
oldMouseX = mouse.x; oldMouseX = mouse.x;
} }
@ -146,10 +149,10 @@ PlasmaCore.ColorScope {
return; return;
} }
if (isDragging) { if (taskSwitcher.currentlyDragging) {
taskSwitcher.currentlyDragging = false;
taskSwitcher.snapOffset(); taskSwitcher.snapOffset();
} }
} }
DropShadow { DropShadow {
@ -202,7 +205,7 @@ PlasmaCore.ColorScope {
} }
root.minimizeAll(); root.minimizeAll();
MobileShell.HomeScreenControls.resetHomeScreenPosition(); MobileShell.HomeScreenControls.resetHomeScreenPosition();
MobileShell.HomeScreenControls.setHomeScreenOpacity(1); MobileShell.HomeScreenControls.showHomeScreen(true);
plasmoid.nativeInterface.allMinimizedChanged(); plasmoid.nativeInterface.allMinimizedChanged();
} }
iconSizeFactor: 1 iconSizeFactor: 1