2023-06-12 23:58:17 +00:00
|
|
|
// SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org>
|
|
|
|
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
2022-04-06 02:06:05 +00:00
|
|
|
|
2023-03-15 06:29:46 +00:00
|
|
|
import QtQuick
|
|
|
|
|
import QtQuick.Window
|
2022-04-06 02:06:05 +00:00
|
|
|
|
2023-03-15 06:29:46 +00:00
|
|
|
import org.kde.plasma.plasmoid
|
|
|
|
|
import org.kde.taskmanager as TaskManager
|
2022-04-06 02:06:05 +00:00
|
|
|
|
2023-11-02 11:08:17 +00:00
|
|
|
import org.kde.plasma.private.mobileshell as MobileShell
|
2023-03-18 19:28:17 +00:00
|
|
|
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
2023-03-15 06:29:46 +00:00
|
|
|
import org.kde.plasma.private.mobileshell.state as MobileShellState
|
|
|
|
|
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
|
2022-04-06 02:06:05 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The base homescreen component, implementing features that simplify
|
|
|
|
|
* homescreen implementation.
|
|
|
|
|
*/
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 21:59:36 +00:00
|
|
|
Item {
|
2022-04-06 02:06:05 +00:00
|
|
|
id: root
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Emitted when an action is triggered to open the homescreen.
|
|
|
|
|
*/
|
|
|
|
|
signal homeTriggered()
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
/**
|
|
|
|
|
* Emitted when resetting the homescreen position is requested.
|
|
|
|
|
*/
|
|
|
|
|
signal resetHomeScreenPosition()
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
/**
|
|
|
|
|
* Emitted when moving the homescreen position is requested.
|
|
|
|
|
*/
|
|
|
|
|
signal requestRelativeScroll(var pos)
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
/**
|
2022-04-06 21:59:36 +00:00
|
|
|
* The visual item that is the homescreen.
|
2022-04-06 02:06:05 +00:00
|
|
|
*/
|
2022-04-06 21:59:36 +00:00
|
|
|
property alias contentItem: itemContainer.contentItem
|
|
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
/**
|
|
|
|
|
* Whether a component is being shown on top of the homescreen within the same
|
|
|
|
|
* window.
|
|
|
|
|
*/
|
2023-03-06 06:38:43 +00:00
|
|
|
readonly property bool overlayShown: startupFeedback.visible
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2023-09-20 12:41:40 +00:00
|
|
|
/**
|
|
|
|
|
* The root PlasmoidItem of the containment this is used into
|
|
|
|
|
*/
|
|
|
|
|
property PlasmoidItem plasmoidItem
|
|
|
|
|
|
2022-12-11 02:05:13 +00:00
|
|
|
/**
|
|
|
|
|
* Margins for the homescreen, taking panels into account.
|
|
|
|
|
*/
|
2022-12-11 02:40:21 +00:00
|
|
|
property real topMargin
|
|
|
|
|
property real bottomMargin
|
|
|
|
|
property real leftMargin
|
|
|
|
|
property real rightMargin
|
|
|
|
|
|
|
|
|
|
function evaluateMargins() {
|
2023-09-20 12:41:40 +00:00
|
|
|
topMargin = plasmoidItem.availableScreenRect.y
|
2023-11-05 22:42:34 +00:00
|
|
|
bottomMargin = root.height - (plasmoidItem.availableScreenRect.y + plasmoidItem.availableScreenRect.height)
|
2023-09-20 12:41:40 +00:00
|
|
|
leftMargin = plasmoidItem.availableScreenRect.x
|
|
|
|
|
rightMargin = root.width - (plasmoidItem.availableScreenRect.x + plasmoidItem.availableScreenRect.width)
|
2022-12-11 02:40:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Connections {
|
2023-06-12 23:58:17 +00:00
|
|
|
target: Plasmoid
|
2022-12-11 02:40:21 +00:00
|
|
|
|
|
|
|
|
// avoid binding loops with root.height and root.width changing along with the availableScreenRect
|
|
|
|
|
function onAvailableScreenRectChanged() {
|
|
|
|
|
Qt.callLater(() => root.evaluateMargins());
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-11 02:05:13 +00:00
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
//BEGIN API implementation
|
2022-12-11 02:05:13 +00:00
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
Connections {
|
2023-03-20 01:32:19 +00:00
|
|
|
target: MobileShellState.ShellDBusClient
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2023-03-20 01:32:19 +00:00
|
|
|
function onOpenHomeScreenRequested() {
|
2023-03-19 01:48:49 +00:00
|
|
|
if (WindowPlugin.WindowMaximizedTracker.showingWindow) {
|
2022-04-06 21:59:36 +00:00
|
|
|
itemContainer.zoomIn();
|
|
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2023-03-20 01:32:19 +00:00
|
|
|
resetHomeScreenPosition();
|
2023-03-06 06:38:43 +00:00
|
|
|
|
2023-03-15 06:29:46 +00:00
|
|
|
WindowPlugin.WindowUtil.unsetAllMinimizedGeometries(root);
|
|
|
|
|
WindowPlugin.WindowUtil.minimizeAll();
|
2023-03-06 06:38:43 +00:00
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
root.homeTriggered();
|
|
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2023-03-20 01:32:19 +00:00
|
|
|
function onResetHomeScreenPositionRequested() {
|
2022-04-06 02:06:05 +00:00
|
|
|
root.resetHomeScreenPosition();
|
|
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2023-03-20 01:32:19 +00:00
|
|
|
function onOpenAppLaunchAnimationRequested(splashIcon, title, x, y, sourceIconSize) {
|
2022-04-06 02:06:05 +00:00
|
|
|
startupFeedback.open(splashIcon, title, x, y, sourceIconSize);
|
|
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2023-03-20 01:32:19 +00:00
|
|
|
function onCloseAppLaunchAnimationRequested() {
|
2022-04-06 02:06:05 +00:00
|
|
|
startupFeedback.close();
|
|
|
|
|
}
|
2023-03-25 06:29:40 +00:00
|
|
|
|
|
|
|
|
function onIsTaskSwitcherVisibleChanged() {
|
|
|
|
|
if (MobileShellState.ShellDBusClient.isTaskSwitcherVisible) {
|
|
|
|
|
itemContainer.zoomOutImmediately();
|
2023-03-26 18:22:14 +00:00
|
|
|
} else if (!WindowPlugin.WindowMaximizedTracker.showingWindow) {
|
2023-03-25 06:29:40 +00:00
|
|
|
itemContainer.zoomIn();
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-06 02:06:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//END API implementation
|
2022-12-11 02:05:13 +00:00
|
|
|
|
2023-03-25 03:35:26 +00:00
|
|
|
Connections {
|
|
|
|
|
target: MobileShellState.LockscreenDBusClient
|
|
|
|
|
|
2023-03-26 17:03:11 +00:00
|
|
|
function onLockscreenLocked() {
|
|
|
|
|
itemContainer.zoomOut();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onLockscreenUnlocked() {
|
2023-03-25 03:35:26 +00:00
|
|
|
// run zoom animation after login
|
2023-03-26 18:22:14 +00:00
|
|
|
itemContainer.zoomOutImmediately();
|
2023-03-26 17:03:11 +00:00
|
|
|
itemContainer.zoomIn();
|
2023-03-25 03:35:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
Component.onCompleted: {
|
2022-12-11 02:40:21 +00:00
|
|
|
// determine the margins used
|
|
|
|
|
evaluateMargins();
|
2022-04-06 02:06:05 +00:00
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 21:59:36 +00:00
|
|
|
// homescreen visual component
|
2023-11-02 11:08:17 +00:00
|
|
|
MobileShell.BaseItem {
|
2022-04-06 21:59:36 +00:00
|
|
|
id: itemContainer
|
|
|
|
|
anchors.fill: parent
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 21:59:36 +00:00
|
|
|
// animations
|
|
|
|
|
opacity: 0
|
2023-03-25 06:29:40 +00:00
|
|
|
property real zoomScale: 1
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2023-03-25 06:29:40 +00:00
|
|
|
readonly property real zoomScaleOut: 0.8
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 21:59:36 +00:00
|
|
|
function zoomIn() {
|
2022-04-30 15:07:07 +00:00
|
|
|
// don't use check animationsEnabled here, so we ensure the scale and opacity is always 1 when disabled
|
2022-04-06 21:59:36 +00:00
|
|
|
scaleAnim.to = 1;
|
|
|
|
|
scaleAnim.restart();
|
|
|
|
|
opacityAnim.to = 1;
|
|
|
|
|
opacityAnim.restart();
|
|
|
|
|
}
|
2023-03-25 06:29:40 +00:00
|
|
|
|
2022-04-06 21:59:36 +00:00
|
|
|
function zoomOut() {
|
2023-03-25 06:29:40 +00:00
|
|
|
scaleAnim.to = zoomScaleOut;
|
|
|
|
|
scaleAnim.restart();
|
|
|
|
|
opacityAnim.to = 0;
|
|
|
|
|
opacityAnim.restart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function zoomOutImmediately() {
|
2023-03-26 18:22:14 +00:00
|
|
|
scaleAnim.stop();
|
|
|
|
|
opacityAnim.stop();
|
2023-03-25 06:29:40 +00:00
|
|
|
zoomScale = zoomScaleOut;
|
|
|
|
|
opacity = 0;
|
2022-04-06 21:59:36 +00:00
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 21:59:36 +00:00
|
|
|
NumberAnimation on opacity {
|
|
|
|
|
id: opacityAnim
|
2023-03-25 06:29:40 +00:00
|
|
|
duration: 300
|
2022-04-06 21:59:36 +00:00
|
|
|
running: false
|
|
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 21:59:36 +00:00
|
|
|
NumberAnimation on zoomScale {
|
|
|
|
|
id: scaleAnim
|
2023-03-25 06:29:40 +00:00
|
|
|
duration: 600
|
2022-04-06 21:59:36 +00:00
|
|
|
running: false
|
|
|
|
|
easing.type: Easing.OutExpo
|
|
|
|
|
}
|
2023-03-26 18:22:14 +00:00
|
|
|
|
2022-06-27 20:53:40 +00:00
|
|
|
function evaluateAnimChange() {
|
|
|
|
|
// only animate if homescreen is visible
|
2023-03-26 18:22:14 +00:00
|
|
|
if (!WindowPlugin.WindowMaximizedTracker.showingWindow && !MobileShellState.ShellDBusClient.isTaskSwitcherVisible) {
|
2023-03-06 06:38:43 +00:00
|
|
|
itemContainer.zoomIn();
|
|
|
|
|
} else {
|
|
|
|
|
itemContainer.zoomOut();
|
2022-06-27 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-19 02:34:27 +00:00
|
|
|
|
2022-06-27 20:53:40 +00:00
|
|
|
Connections {
|
2023-03-19 02:34:27 +00:00
|
|
|
target: WindowPlugin.WindowMaximizedTracker
|
|
|
|
|
|
|
|
|
|
function onShowingWindowChanged() {
|
2022-06-27 20:53:40 +00:00
|
|
|
itemContainer.evaluateAnimChange();
|
2022-04-06 21:59:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
|
|
|
|
transform: Scale {
|
|
|
|
|
origin.x: itemContainer.width / 2;
|
|
|
|
|
origin.y: itemContainer.height / 2;
|
2022-04-06 21:59:36 +00:00
|
|
|
xScale: itemContainer.zoomScale
|
|
|
|
|
yScale: itemContainer.zoomScale
|
|
|
|
|
}
|
2022-04-06 02:06:05 +00:00
|
|
|
}
|
2023-06-12 23:58:17 +00:00
|
|
|
|
2022-04-06 02:06:05 +00:00
|
|
|
// start app animation component
|
2023-11-02 11:08:17 +00:00
|
|
|
MobileShell.StartupFeedback {
|
2022-04-06 02:06:05 +00:00
|
|
|
id: startupFeedback
|
|
|
|
|
z: 999999
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
}
|
|
|
|
|
}
|