shift-shell/components/mobileshell/qml/actiondrawer/ActionDrawerOpenSurface.qml

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

180 lines
5.9 KiB
QML
Raw Normal View History

/*
* SPDX-FileCopyrightText: 2021-2024 Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.15
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell as MobileShell
/**
* Component that triggers the opening and closing of an ActionDrawer when dragged on with touch or mouse.
*/
MobileShell.SwipeArea {
id: root
2023-09-30 17:06:41 +00:00
mode: MobileShell.SwipeArea.VerticalOnly
required property ActionDrawer actionDrawer
property var virtualDesktopInfo: null
readonly property real touchpadDirectionLockThreshold: 12
readonly property real touchpadWorkspaceSwitchThreshold: 80
readonly property real touchpadAxisDominance: 1.25
property point touchpadStartPoint: Qt.point(0, 0)
property string touchpadGestureMode: ""
property bool touchpadWorkspaceSwitched: false
function startSwipe() {
if (actionDrawer.intendedToBeVisible) {
// ensure the action drawer state is consistent
actionDrawer.closeImmediately();
}
actionDrawer.cancelAnimations();
actionDrawer.dragging = true;
actionDrawer.opened = false;
// must be after properties other are set, we cannot have actionDrawer.updateState() be called
actionDrawer.offset = 0;
actionDrawer.oldOffset = 0;
actionDrawer.intendedToBeVisible = true;
}
function startSwipeWithPoint(point) {
if (ShellSettings.Settings.convergenceModeEnabled) {
actionDrawer.openToPinnedMode = false;
} else if (point.x < root.width / 2) {
actionDrawer.openToPinnedMode = ShellSettings.Settings.actionDrawerTopLeftMode == ShellSettings.Settings.Pinned;
} else {
actionDrawer.openToPinnedMode = ShellSettings.Settings.actionDrawerTopRightMode == ShellSettings.Settings.Pinned;
}
startSwipe();
}
function endSwipe() {
actionDrawer.dragging = false;
actionDrawer.updateState();
}
function updateOffset(offsetY) {
actionDrawer.offset += offsetY;
}
function workspaceScrollAvailable() {
return ShellSettings.Settings.convergenceModeEnabled
&& virtualDesktopInfo !== null
&& virtualDesktopInfo.numberOfDesktops > 1;
}
function desktopIndexForId(desktopId) {
if (virtualDesktopInfo === null || !virtualDesktopInfo.desktopIds) {
return -1;
}
for (let i = 0; i < virtualDesktopInfo.desktopIds.length; ++i) {
if (String(virtualDesktopInfo.desktopIds[i]) === String(desktopId)) {
return i;
}
}
return -1;
}
function activateAdjacentWorkspace(direction) {
if (!workspaceScrollAvailable()) {
return;
}
const currentIndex = desktopIndexForId(virtualDesktopInfo.currentDesktop);
if (currentIndex < 0) {
return;
}
const targetIndex = Math.max(0, Math.min(virtualDesktopInfo.desktopIds.length - 1, currentIndex + direction));
if (targetIndex !== currentIndex) {
virtualDesktopInfo.requestActivate(virtualDesktopInfo.desktopIds[targetIndex]);
}
}
function startTouchpadScroll(point) {
touchpadStartPoint = point;
touchpadGestureMode = "";
touchpadWorkspaceSwitched = false;
if (!ShellSettings.Settings.convergenceModeEnabled) {
touchpadGestureMode = "drawer";
startSwipeWithPoint(point);
}
}
function moveTouchpadScroll(totalDeltaX, totalDeltaY, deltaX, deltaY) {
if (touchpadGestureMode === "") {
const absX = Math.abs(totalDeltaX);
const absY = Math.abs(totalDeltaY);
if (absY >= touchpadDirectionLockThreshold && absY > absX * touchpadAxisDominance) {
touchpadGestureMode = "drawer";
startSwipeWithPoint(touchpadStartPoint);
updateOffset(totalDeltaY);
return;
} else if (workspaceScrollAvailable() && absX >= touchpadDirectionLockThreshold && absX > absY * touchpadAxisDominance) {
touchpadGestureMode = "workspace";
} else {
return;
}
}
if (touchpadGestureMode === "drawer") {
updateOffset(deltaY);
return;
}
if (!touchpadWorkspaceSwitched && Math.abs(totalDeltaX) >= touchpadWorkspaceSwitchThreshold) {
touchpadWorkspaceSwitched = true;
activateAdjacentWorkspace(totalDeltaX < 0 ? 1 : -1);
}
}
function endTouchpadScroll() {
if (touchpadGestureMode === "drawer") {
endSwipe();
}
touchpadGestureMode = "";
touchpadWorkspaceSwitched = false;
}
anchors.fill: parent
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
scrollGestureEnabled: false
cursorShape: ShellSettings.Settings.convergenceModeEnabled ? Qt.PointingHandCursor : Qt.ArrowCursor
}
onSwipeStarted: (point) => startSwipeWithPoint(point)
onSwipeEnded: endSwipe()
onSwipeMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => updateOffset(deltaY);
onTouchpadScrollStarted: (point) => startTouchpadScroll(point)
onTouchpadScrollEnded: endTouchpadScroll()
onTouchpadScrollMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => moveTouchpadScroll(totalDeltaX, totalDeltaY, deltaX, deltaY);
// In convergence mode, allow click to toggle the action drawer (mouse-friendly)
onClicked: {
if (ShellSettings.Settings.convergenceModeEnabled) {
if (actionDrawer.intendedToBeVisible) {
actionDrawer.close();
} else {
actionDrawer.openToPinnedMode = false;
actionDrawer.intendedToBeVisible = true;
actionDrawer.open();
}
}
}
}