mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
Add overswipe gesture
This commit is contained in:
parent
43c327655d
commit
dcbdf8f101
4 changed files with 74 additions and 42 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue