Warning, /plasma/plasma-mobile/kwin/mobiletaskswitcher/qml/Task.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2015 Marco Martin <notmart@gmail.com> 0002 // SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org> 0003 // SPDX-License-Identifier: GPL-2.0-or-later 0004 0005 import QtQuick 0006 import QtQuick.Layouts 0007 import Qt5Compat.GraphicalEffects 0008 0009 import org.kde.kirigami 2.20 as Kirigami 0010 import org.kde.plasma.core as PlasmaCore 0011 import org.kde.plasma.components 3.0 as PlasmaComponents 0012 import org.kde.kwin 3.0 as KWinComponents 0013 0014 Item { 0015 id: delegate 0016 0017 required property var taskSwitcher 0018 0019 required property QtObject window 0020 required property int index 0021 0022 required property var model 0023 0024 required property real previewHeight 0025 required property real previewWidth 0026 0027 readonly property real dragOffset: -control.y 0028 0029 // whether this task is being interacted with 0030 readonly property bool interactingActive: control.pressed && control.passedDragThreshold 0031 0032 // whether to show the text header 0033 property bool showHeader: true 0034 0035 // the amount to darken the task preview by 0036 property real darken: 0 0037 0038 opacity: 1 - dragOffset / taskSwitcher.height 0039 0040 //BEGIN functions 0041 function closeApp() { 0042 delegate.window.closeWindow(); 0043 } 0044 0045 function activateApp() { 0046 taskSwitcherState.wasInActiveTask = false; 0047 taskSwitcher.activateWindow(model.index, delegate.window); 0048 delegate.window.setMaximize(true, true); 0049 } 0050 0051 function minimizeApp() { 0052 delegate.window.minimized = true; 0053 } 0054 //END functions 0055 0056 MouseArea { 0057 id: control 0058 width: parent.width 0059 height: parent.height 0060 enabled: !taskSwitcher.taskSwitcherState.currentlyBeingOpened 0061 0062 // set cursor shape here, since taphandler seems to not be able to do it 0063 cursorShape: Qt.PointingHandCursor 0064 0065 property bool movingUp: false 0066 property real oldY: y 0067 onYChanged: { 0068 movingUp = y < oldY; 0069 oldY = y; 0070 } 0071 0072 onClicked: { 0073 if (!taskSwitcher.taskSwitcherState.currentlyBeingOpened && !passedDragThreshold) { 0074 delegate.activateApp(); 0075 } 0076 } 0077 0078 // pixels before we start treating it as drag event 0079 readonly property real dragThreshold: 5 0080 0081 property real startPosition: 0 0082 property bool hasStartPosition: false 0083 property bool passedDragThreshold: false 0084 0085 onPositionChanged: (mouse) => { 0086 // map it to the root area, so that it doesn't jitter (since this item is moving) 0087 const yPos = control.mapToItem(delegate, mouse.x, mouse.y).y 0088 0089 // reset start position 0090 if (!hasStartPosition) { 0091 startPosition = yPos; 0092 hasStartPosition = true; 0093 } 0094 0095 // set threshold 0096 if (!passedDragThreshold && Math.abs(y) > dragThreshold) { 0097 passedDragThreshold = true; 0098 } 0099 0100 // update position 0101 // y < 0 - dragging up (dismissing the app) 0102 y = Math.min(0, yPos - startPosition); 0103 } 0104 0105 onPressedChanged: { 0106 yAnimator.stop(); 0107 0108 // reset values 0109 if (pressed) { 0110 hasStartPosition = false; 0111 passedDragThreshold = false; 0112 } 0113 0114 // run animation when finger lets go 0115 if (!pressed) { 0116 if (control.movingUp && control.y < -Kirigami.Units.gridUnit * 2) { 0117 yAnimator.to = -root.height; 0118 } else { 0119 yAnimator.to = 0; 0120 } 0121 yAnimator.start(); 0122 } 0123 } 0124 0125 // if the app doesn't close within a certain time, drag it back 0126 Timer { 0127 id: uncloseTimer 0128 interval: 3000 0129 onTriggered: { 0130 yAnimator.to = 0; 0131 yAnimator.restart(); 0132 } 0133 } 0134 0135 NumberAnimation on y { 0136 id: yAnimator 0137 running: !control.pressed 0138 duration: Kirigami.Units.longDuration 0139 easing.type: Easing.InOutQuad 0140 to: 0 0141 onFinished: { 0142 if (to != 0) { // close app 0143 delegate.closeApp(); 0144 uncloseTimer.start(); 0145 } 0146 } 0147 } 0148 0149 // application 0150 ColumnLayout { 0151 id: column 0152 anchors.fill: parent 0153 spacing: 0 0154 0155 // header 0156 RowLayout { 0157 id: appHeader 0158 Layout.fillWidth: true 0159 Layout.fillHeight: true 0160 Layout.minimumHeight: column.height - appView.height 0161 spacing: Kirigami.Units.smallSpacing * 2 0162 opacity: delegate.showHeader ? 1 : 0 0163 0164 Behavior on opacity { 0165 NumberAnimation { duration: Kirigami.Units.shortDuration } 0166 } 0167 0168 Kirigami.Icon { 0169 Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium 0170 Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium 0171 Layout.alignment: Qt.AlignVCenter 0172 source: delegate.window.icon 0173 } 0174 0175 PlasmaComponents.Label { 0176 Layout.fillWidth: true 0177 Layout.alignment: Qt.AlignVCenter 0178 elide: Text.ElideRight 0179 text: delegate.window.caption 0180 color: "white" 0181 } 0182 0183 PlasmaComponents.ToolButton { 0184 Layout.alignment: Qt.AlignVCenter 0185 z: 99 0186 icon.name: "window-close" 0187 icon.width: Kirigami.Units.iconSizes.smallMedium 0188 icon.height: Kirigami.Units.iconSizes.smallMedium 0189 onClicked: delegate.closeApp() 0190 } 0191 } 0192 0193 // app preview 0194 Rectangle { 0195 id: appView 0196 Layout.preferredWidth: delegate.previewWidth 0197 Layout.preferredHeight: delegate.previewHeight 0198 Layout.maximumWidth: delegate.previewWidth 0199 Layout.maximumHeight: delegate.previewHeight 0200 0201 color: "transparent" 0202 clip: true 0203 0204 // scale animation on press 0205 property real zoomScale: control.pressed ? 0.9 : 1 0206 Behavior on zoomScale { 0207 NumberAnimation { 0208 duration: 200 0209 easing.type: Easing.OutExpo 0210 } 0211 } 0212 0213 transform: Scale { 0214 origin.x: appView.width / 2; 0215 origin.y: appView.height / 2; 0216 xScale: appView.zoomScale 0217 yScale: appView.zoomScale 0218 } 0219 0220 Item { 0221 id: item 0222 anchors.fill: parent 0223 0224 KWinComponents.WindowThumbnail { 0225 id: thumbSource 0226 wId: delegate.window.internalId 0227 anchors.fill: parent 0228 0229 layer.enabled: true 0230 layer.effect: ColorOverlay { 0231 color: Qt.rgba(0, 0, 0, delegate.darken) 0232 } 0233 } 0234 } 0235 } 0236 } 0237 } 0238 } 0239 0240