Move WindowHeap delegate to own file
This makes easier for individual effects to personalize it without adding ad-hoc api in the main WindowHeap class. WindowHeap and WindowHEapDelegate are still quite coupled and thing can probably still be improved, but the code should be more readable already
This commit is contained in:
parent
6d9d4c190a
commit
fd25e96969
6 changed files with 414 additions and 375 deletions
|
@ -105,9 +105,6 @@ DropArea {
|
|||
animationEnabled: container.animationEnabled
|
||||
organized: container.organized
|
||||
layout: effect.layout
|
||||
supportsCloseWindows: false
|
||||
supportsDragUpGesture: false
|
||||
showCaptions: false
|
||||
model: KWinComponents.ClientFilterModel {
|
||||
activity: KWinComponents.Workspace.currentActivity
|
||||
desktop: desktopView.desktop
|
||||
|
@ -117,6 +114,11 @@ DropArea {
|
|||
~KWinComponents.ClientFilterModel.Desktop &
|
||||
~KWinComponents.ClientFilterModel.Notification;
|
||||
}
|
||||
delegate: WindowHeapDelegate {
|
||||
windowHeap: heap
|
||||
closeButtonVisible: false
|
||||
windowTitleVisible: false
|
||||
}
|
||||
onActivated: effect.deactivate(effect.animationDuration);
|
||||
onWindowClicked: {
|
||||
if (eventPoint.event.button !== Qt.MiddleButton) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.kde.kwin.private.effects 1.0
|
|||
import org.kde.milou 0.3 as Milou
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
FocusScope {
|
||||
id: container
|
||||
|
@ -183,13 +184,11 @@ FocusScope {
|
|||
id: heap
|
||||
visible: !(container.organized && searchField.text)
|
||||
anchors.fill: parent
|
||||
layout: effect.layout
|
||||
layoutMode: effect.layout
|
||||
padding: PlasmaCore.Units.largeSpacing
|
||||
animationDuration: effect.animationDuration
|
||||
animationEnabled: container.animationEnabled
|
||||
organized: container.organized
|
||||
supportsCloseWindows: true
|
||||
supportsDragUpGesture: true
|
||||
onWindowClicked: {
|
||||
if (eventPoint.event.button !== Qt.MiddleButton) {
|
||||
return;
|
||||
|
@ -207,6 +206,22 @@ FocusScope {
|
|||
~KWinComponents.ClientFilterModel.Notification;
|
||||
}
|
||||
onActivated: effect.deactivate();
|
||||
delegate: WindowHeapDelegate {
|
||||
windowHeap: heap
|
||||
|
||||
targetScale: {
|
||||
var localPressPosition = dragHandler.centroid.scenePressPosition.y - heap.expoLayout.Kirigami.ScenePosition.y;
|
||||
if (localPressPosition == 0) {
|
||||
return 0.1
|
||||
} else {
|
||||
var localPosition = dragHandler.centroid.scenePosition.y - heap.expoLayout.Kirigami.ScenePosition.y;
|
||||
return Math.max(0.1, Math.min(localPosition / localPressPosition, 1))
|
||||
}
|
||||
}
|
||||
|
||||
opacity: 1 - downGestureProgress
|
||||
onDownGestureTriggered: client.closeWindow()
|
||||
}
|
||||
}
|
||||
|
||||
Milou.ResultsView {
|
||||
|
@ -246,7 +261,7 @@ FocusScope {
|
|||
|
||||
Behavior on opacity {
|
||||
enabled: !container.effect.gestureInProgress
|
||||
NumberAnimation { duration: animationDuration; easing.type: Easing.OutCubic }
|
||||
NumberAnimation { duration: effect.animationDuration; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,11 +22,10 @@ FocusScope {
|
|||
Down
|
||||
}
|
||||
|
||||
property bool supportsCloseWindows: false
|
||||
property bool supportsDragUpGesture: false
|
||||
property bool showCaptions: true
|
||||
property alias model: windowsRepeater.model
|
||||
property alias delegate: windowsRepeater.delegate
|
||||
property alias layout: expoLayout.mode
|
||||
property alias expoLayout: expoLayout
|
||||
property int selectedIndex: -1
|
||||
property int animationDuration: PlasmaCore.Units.longDuration
|
||||
property bool animationEnabled: false
|
||||
|
@ -110,369 +109,7 @@ FocusScope {
|
|||
|
||||
Repeater {
|
||||
id: windowsRepeater
|
||||
|
||||
Item {
|
||||
id: thumb
|
||||
|
||||
required property QtObject client
|
||||
required property int index
|
||||
|
||||
readonly property bool selected: heap.selectedIndex == index
|
||||
readonly property bool hidden: {
|
||||
if (heap.showOnly === "activeClass") {
|
||||
return heap.activeClass !== String(thumb.client.resourceName); // thumb.client.resourceName is not an actual String as comes from a QByteArray so === would fail
|
||||
} else {
|
||||
return heap.showOnly.length && heap.showOnly.indexOf(client.internalId) == -1;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (thumb.client.active) {
|
||||
heap.activeClass = thumb.client.resourceName;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: thumb.client
|
||||
function onActiveChanged() {
|
||||
if (thumb.client.active) {
|
||||
heap.activeClass = thumb.client.resourceName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state: {
|
||||
if (effect.gestureInProgress) {
|
||||
return "partial";
|
||||
}
|
||||
if (heap.effectiveOrganized) {
|
||||
return hidden ? "active-hidden" : "active";
|
||||
}
|
||||
return client.minimized ? "initial-minimized" : "initial";
|
||||
}
|
||||
|
||||
visible: opacity > 0
|
||||
z: thumb.activeDragHandler.active ? 100 : client.stackingOrder
|
||||
|
||||
component TweenBehavior : Behavior {
|
||||
enabled: thumb.state !== "partial" && heap.animationEnabled && !thumb.activeDragHandler.active
|
||||
NumberAnimation {
|
||||
duration: heap.animationDuration
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
TweenBehavior on x {}
|
||||
TweenBehavior on y {}
|
||||
TweenBehavior on width {}
|
||||
TweenBehavior on height {}
|
||||
|
||||
KWinComponents.WindowThumbnailItem {
|
||||
id: thumbSource
|
||||
wId: thumb.client.internalId
|
||||
state: thumb.activeDragHandler.active ? "drag" : "normal"
|
||||
readonly property QtObject screen: targetScreen
|
||||
readonly property QtObject client: thumb.client
|
||||
|
||||
Drag.active: thumb.activeDragHandler.active
|
||||
Drag.source: thumb.client
|
||||
Drag.hotSpot: Qt.point(
|
||||
thumb.activeDragHandler.centroid.pressPosition.x * thumb.activeDragHandler.targetScale,
|
||||
thumb.activeDragHandler.centroid.pressPosition.y * thumb.activeDragHandler.targetScale)
|
||||
|
||||
onXChanged: effect.checkItemDraggedOutOfScreen(thumbSource)
|
||||
onYChanged: effect.checkItemDraggedOutOfScreen(thumbSource)
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "normal"
|
||||
PropertyChanges {
|
||||
target: thumbSource
|
||||
x: 0
|
||||
y: 0
|
||||
width: thumb.width
|
||||
height: thumb.height
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "drag"
|
||||
PropertyChanges {
|
||||
target: thumbSource
|
||||
x: -thumb.activeDragHandler.centroid.pressPosition.x * thumb.activeDragHandler.targetScale +
|
||||
thumb.activeDragHandler.centroid.position.x
|
||||
y: -thumb.activeDragHandler.centroid.pressPosition.y * thumb.activeDragHandler.targetScale +
|
||||
thumb.activeDragHandler.centroid.position.y
|
||||
width: cell.width * thumb.activeDragHandler.targetScale
|
||||
height: cell.height * thumb.activeDragHandler.targetScale
|
||||
opacity: thumb.activeDragHandler.targetOpacity
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: Transition {
|
||||
to: "normal"
|
||||
enabled: heap.animationEnabled
|
||||
NumberAnimation {
|
||||
duration: heap.animationDuration
|
||||
properties: "x, y, width, height, opacity"
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: thumb.activeDragHandler.active ? Qt.ClosedHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
|
||||
PC3.Label {
|
||||
anchors.fill: thumbSource
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: i18nd("kwin_effects", "Drag Down To Close")
|
||||
opacity: 1 - thumbSource.opacity
|
||||
visible: !thumb.hidden
|
||||
}
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: icon
|
||||
usesPlasmaTheme: false
|
||||
width: PlasmaCore.Units.iconSizes.large
|
||||
height: width
|
||||
source: thumb.client.icon
|
||||
anchors.horizontalCenter: thumbSource.horizontalCenter
|
||||
anchors.bottom: thumbSource.bottom
|
||||
anchors.bottomMargin: -height / 4
|
||||
visible: !thumb.hidden && !activeDragHandler.active
|
||||
|
||||
|
||||
PC3.Label {
|
||||
id: caption
|
||||
visible: heap.showCaptions
|
||||
width: Math.min(implicitWidth, thumbSource.width)
|
||||
anchors.top: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
elide: Text.ElideRight
|
||||
text: thumb.client.caption
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
ExpoCell {
|
||||
id: cell
|
||||
layout: expoLayout
|
||||
enabled: !thumb.hidden
|
||||
naturalX: thumb.client.x - targetScreen.geometry.x - expoLayout.Kirigami.ScenePosition.x
|
||||
naturalY: thumb.client.y - targetScreen.geometry.y - expoLayout.Kirigami.ScenePosition.y
|
||||
naturalWidth: thumb.client.width
|
||||
naturalHeight: thumb.client.height
|
||||
persistentKey: thumb.client.internalId
|
||||
bottomMargin: icon.height / 4 + caption.height
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "initial"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
x: thumb.client.x - targetScreen.geometry.x - (heap.absolutePositioning ? expoLayout.Kirigami.ScenePosition.x : 0)
|
||||
y: thumb.client.y - targetScreen.geometry.y - (heap.absolutePositioning ? expoLayout.Kirigami.ScenePosition.y : 0)
|
||||
width: thumb.client.width
|
||||
height: thumb.client.height
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "partial"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
x: (thumb.client.x - targetScreen.geometry.x - (heap.absolutePositioning ? expoLayout.Kirigami.ScenePosition.x : 0)) * (1 - effect.partialActivationFactor) + cell.x * effect.partialActivationFactor
|
||||
y: (thumb.client.y - targetScreen.geometry.y - (heap.absolutePositioning ? expoLayout.Kirigami.ScenePosition.y : 0)) * (1 - effect.partialActivationFactor) + cell.y * effect.partialActivationFactor
|
||||
width: thumb.client.width * (1 - effect.partialActivationFactor) + cell.width * effect.partialActivationFactor
|
||||
height: thumb.client.height * (1 - effect.partialActivationFactor) + cell.height * effect.partialActivationFactor
|
||||
opacity: thumb.client.minimized ? effect.partialActivationFactor : 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: effect.partialActivationFactor
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: effect.partialActivationFactor
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "initial-minimized"
|
||||
extend: "initial"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "active"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
x: cell.x
|
||||
y: cell.y
|
||||
width: cell.width
|
||||
height: cell.height
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "active-hidden"
|
||||
extend: "active"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: Transition {
|
||||
to: "initial, active, active-hidden"
|
||||
enabled: heap.animationEnabled
|
||||
NumberAnimation {
|
||||
duration: heap.animationDuration
|
||||
properties: "x, y, width, height, opacity"
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -PlasmaCore.Units.smallSpacing
|
||||
imagePath: "widgets/viewitem"
|
||||
prefix: "hover"
|
||||
z: -1
|
||||
visible: !thumb.activeDragHandler.active && (hoverHandler.hovered || selected)
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
onHoveredChanged: if (hovered != selected) {
|
||||
heap.resetSelected();
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onTapped: {
|
||||
KWinComponents.Workspace.activeClient = thumb.client;
|
||||
heap.activated();
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Pen
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
onTapped: {
|
||||
heap.windowClicked(thumb.client, eventPoint)
|
||||
}
|
||||
}
|
||||
|
||||
component DragManager : DragHandler {
|
||||
id: dragHandler
|
||||
target: null
|
||||
grabPermissions: PointerHandler.CanTakeOverFromAnything
|
||||
|
||||
readonly property double targetScale: {
|
||||
if (!heap.supportsDragUpGesture) {
|
||||
return 1;
|
||||
}
|
||||
const localPressPosition = centroid.scenePressPosition.y - expoLayout.Kirigami.ScenePosition.y;
|
||||
if (localPressPosition == 0) {
|
||||
return 0.1
|
||||
} else {
|
||||
const localPosition = centroid.scenePosition.y - expoLayout.Kirigami.ScenePosition.y;
|
||||
return Math.max(0.1, Math.min(localPosition / localPressPosition, 1))
|
||||
}
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
heap.dragActive = active;
|
||||
if (active) {
|
||||
thumb.activeDragHandler = dragHandler;
|
||||
} else {
|
||||
thumbSource.Drag.drop();
|
||||
let globalPos = targetScreen.mapToGlobal(centroid.scenePosition);
|
||||
effect.checkItemDroppedOutOfScreen(globalPos, thumbSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
property DragManager activeDragHandler: dragHandler
|
||||
DragManager {
|
||||
id: dragHandler
|
||||
readonly property double targetOpacity: 1
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
|
||||
}
|
||||
DragManager {
|
||||
id: touchDragHandler
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
readonly property double targetOpacity: {
|
||||
if (!heap.supportsCloseWindows) {
|
||||
return 1;
|
||||
}
|
||||
const startDistance = heap.Kirigami.ScenePosition.y + heap.height - centroid.scenePressPosition.y;
|
||||
const localPosition = heap.Kirigami.ScenePosition.y + heap.height - centroid.scenePosition.y;
|
||||
return Math.min(localPosition / startDistance, 1);
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (!active) {
|
||||
if (heap.supportsCloseWindows && targetOpacity < 0.4) {
|
||||
thumb.client.closeWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PC3.Button {
|
||||
id: closeButton
|
||||
visible: heap.supportsCloseWindows && (hoverHandler.hovered || Kirigami.Settings.tabletMode || Kirigami.Settings.hasTransientTouchInput) && thumb.client.closeable && !dragHandler.active
|
||||
anchors {
|
||||
right: thumbSource.right
|
||||
rightMargin: PlasmaCore.Units.smallSpacing
|
||||
top: thumbSource.top
|
||||
topMargin: PlasmaCore.Units.smallSpacing
|
||||
}
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
icon.name: "window-close"
|
||||
implicitWidth: PlasmaCore.Units.iconSizes.medium
|
||||
implicitHeight: implicitWidth
|
||||
onClicked: thumb.client.closeWindow();
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (selected) {
|
||||
heap.resetSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: WindowHeapDelegate {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
380
src/effects/private/qml/WindowHeapDelegate.qml
Normal file
380
src/effects/private/qml/WindowHeapDelegate.qml
Normal file
|
@ -0,0 +1,380 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
import org.kde.kwin 3.0 as KWinComponents
|
||||
import org.kde.kwin.private.effects 1.0
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
|
||||
Item {
|
||||
id: thumb
|
||||
|
||||
required property QtObject client
|
||||
required property int index
|
||||
required property Item windowHeap
|
||||
|
||||
readonly property alias dragHandler: thumb.activeDragHandler
|
||||
readonly property bool selected: thumb.windowHeap.selectedIndex == index
|
||||
//TODO: move?
|
||||
readonly property bool hidden: {
|
||||
if (thumb.windowHeap.showOnly === "activeClass") {
|
||||
return thumb.windowHeap.activeClass !== String(thumb.client.resourceName); // thumb.client.resourceName is not an actual String as comes from a QByteArray so === would fail
|
||||
} else {
|
||||
return thumb.windowHeap.showOnly.length && thumb.windowHeap.showOnly.indexOf(client.internalId) == -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Show a close button on this thumbnail
|
||||
property bool closeButtonVisible: true
|
||||
// Show a text label under this thumbnail
|
||||
property bool windowTitleVisible: true
|
||||
|
||||
//scale up and down the whole thumbnail without affecting layouting
|
||||
property real targetScale: 1.0
|
||||
|
||||
// Swipe down gesture by touch, in some effects will close the window
|
||||
readonly property alias downGestureProgress: touchDragHandler.downGestureProgress
|
||||
signal downGestureTriggered()
|
||||
|
||||
|
||||
|
||||
Component.onCompleted: {
|
||||
if (thumb.client.active) {
|
||||
thumb.windowHeap.activeClass = thumb.client.resourceName;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: thumb.client
|
||||
function onActiveChanged() {
|
||||
if (thumb.client.active) {
|
||||
thumb.windowHeap.activeClass = thumb.client.resourceName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state: {
|
||||
if (effect.gestureInProgress) {
|
||||
return "partial";
|
||||
}
|
||||
if (thumb.windowHeap.effectiveOrganized) {
|
||||
return hidden ? "active-hidden" : "active";
|
||||
}
|
||||
return client.minimized ? "initial-minimized" : "initial";
|
||||
}
|
||||
|
||||
visible: opacity > 0
|
||||
z: thumb.activeDragHandler.active ? 100 : client.stackingOrder
|
||||
|
||||
component TweenBehavior : Behavior {
|
||||
enabled: thumb.state !== "partial" && thumb.windowHeap.animationEnabled && !thumb.activeDragHandler.active
|
||||
NumberAnimation {
|
||||
duration: thumb.windowHeap.animationDuration
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
TweenBehavior on x {}
|
||||
TweenBehavior on y {}
|
||||
TweenBehavior on width {}
|
||||
TweenBehavior on height {}
|
||||
|
||||
KWinComponents.WindowThumbnailItem {
|
||||
id: thumbSource
|
||||
wId: thumb.client.internalId
|
||||
state: thumb.activeDragHandler.active ? "drag" : "normal"
|
||||
readonly property QtObject screen: targetScreen
|
||||
readonly property QtObject client: thumb.client
|
||||
|
||||
Drag.active: thumb.activeDragHandler.active
|
||||
Drag.source: thumb.client
|
||||
Drag.hotSpot: Qt.point(
|
||||
thumb.activeDragHandler.centroid.pressPosition.x * thumb.targetScale,
|
||||
thumb.activeDragHandler.centroid.pressPosition.y * thumb.targetScale)
|
||||
|
||||
onXChanged: effect.checkItemDraggedOutOfScreen(thumbSource)
|
||||
onYChanged: effect.checkItemDraggedOutOfScreen(thumbSource)
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "normal"
|
||||
PropertyChanges {
|
||||
target: thumbSource
|
||||
x: 0
|
||||
y: 0
|
||||
width: thumb.width * thumb.targetScale
|
||||
height: thumb.height * thumb.targetScale
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "drag"
|
||||
PropertyChanges {
|
||||
target: thumbSource
|
||||
x: -thumb.activeDragHandler.centroid.pressPosition.x * thumb.targetScale +
|
||||
thumb.activeDragHandler.centroid.position.x
|
||||
y: -thumb.activeDragHandler.centroid.pressPosition.y * thumb.targetScale +
|
||||
thumb.activeDragHandler.centroid.position.y
|
||||
width: cell.width * thumb.targetScale
|
||||
height: cell.height * thumb.targetScale
|
||||
opacity: thumb.activeDragHandler.targetOpacity
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: Transition {
|
||||
to: "normal"
|
||||
enabled: thumb.windowHeap.animationEnabled
|
||||
NumberAnimation {
|
||||
duration: thumb.windowHeap.animationDuration
|
||||
properties: "x, y, width, height, opacity"
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: thumb.activeDragHandler.active ? Qt.ClosedHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
|
||||
PC3.Label {
|
||||
anchors.fill: thumbSource
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: i18nd("kwin_effects", "Drag Down To Close")
|
||||
opacity: 1 - thumbSource.opacity
|
||||
visible: !thumb.hidden
|
||||
}
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: icon
|
||||
width: PlasmaCore.Units.iconSizes.large
|
||||
height: width
|
||||
source: thumb.client.icon
|
||||
anchors.horizontalCenter: thumbSource.horizontalCenter
|
||||
anchors.bottom: thumbSource.bottom
|
||||
anchors.bottomMargin: -height / 4
|
||||
visible: !thumb.hidden && !activeDragHandler.active
|
||||
|
||||
|
||||
PC3.Label {
|
||||
id: caption
|
||||
visible: thumb.windowTitleVisible
|
||||
width: Math.min(implicitWidth, thumbSource.width)
|
||||
anchors.top: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
elide: Text.ElideRight
|
||||
text: thumb.client.caption
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
ExpoCell {
|
||||
id: cell
|
||||
layout: windowHeap.expoLayout
|
||||
enabled: !thumb.hidden
|
||||
naturalX: thumb.client.x - targetScreen.geometry.x - windowHeap.expoLayout.Kirigami.ScenePosition.x
|
||||
naturalY: thumb.client.y - targetScreen.geometry.y - windowHeap.expoLayout.Kirigami.ScenePosition.y
|
||||
naturalWidth: thumb.client.width
|
||||
naturalHeight: thumb.client.height
|
||||
persistentKey: thumb.client.internalId
|
||||
bottomMargin: icon.height / 4 + caption.height
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "initial"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
x: thumb.client.x - targetScreen.geometry.x - (thumb.windowHeap.absolutePositioning ? windowHeap.expoLayout.Kirigami.ScenePosition.x : 0)
|
||||
y: thumb.client.y - targetScreen.geometry.y - (thumb.windowHeap.absolutePositioning ? windowHeap.expoLayout.Kirigami.ScenePosition.y : 0)
|
||||
width: thumb.client.width
|
||||
height: thumb.client.height
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "partial"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
x: (thumb.client.x - targetScreen.geometry.x - (thumb.windowHeap.absolutePositioning ? windowHeap.expoLayout.Kirigami.ScenePosition.x : 0)) * (1 - effect.partialActivationFactor) + cell.x * effect.partialActivationFactor
|
||||
y: (thumb.client.y - targetScreen.geometry.y - (thumb.windowHeap.absolutePositioning ? windowHeap.expoLayout.Kirigami.ScenePosition.y : 0)) * (1 - effect.partialActivationFactor) + cell.y * effect.partialActivationFactor
|
||||
width: thumb.client.width * (1 - effect.partialActivationFactor) + cell.width * effect.partialActivationFactor
|
||||
height: thumb.client.height * (1 - effect.partialActivationFactor) + cell.height * effect.partialActivationFactor
|
||||
opacity: thumb.client.minimized ? effect.partialActivationFactor : 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: effect.partialActivationFactor
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: effect.partialActivationFactor
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "initial-minimized"
|
||||
extend: "initial"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "active"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
x: cell.x
|
||||
y: cell.y
|
||||
width: cell.width
|
||||
height: cell.height
|
||||
}
|
||||
PropertyChanges {
|
||||
target: icon
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "active-hidden"
|
||||
extend: "active"
|
||||
PropertyChanges {
|
||||
target: thumb
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: Transition {
|
||||
to: "initial, active, active-hidden"
|
||||
enabled: thumb.windowHeap.animationEnabled
|
||||
NumberAnimation {
|
||||
duration: thumb.windowHeap.animationDuration
|
||||
properties: "x, y, width, height, opacity"
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -PlasmaCore.Units.smallSpacing
|
||||
imagePath: "widgets/viewitem"
|
||||
prefix: "hover"
|
||||
z: -1
|
||||
visible: !thumb.activeDragHandler.active && (hoverHandler.hovered || selected)
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
onHoveredChanged: if (hovered != selected) {
|
||||
thumb.windowHeap.resetSelected();
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onTapped: {
|
||||
KWinComponents.Workspace.activeClient = thumb.client;
|
||||
thumb.windowHeap.activated();
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Pen
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
onTapped: {
|
||||
thumb.windowHeap.windowClicked(thumb.client, eventPoint)
|
||||
}
|
||||
}
|
||||
|
||||
component DragManager : DragHandler {
|
||||
id: dragHandler
|
||||
target: null
|
||||
grabPermissions: PointerHandler.CanTakeOverFromAnything
|
||||
|
||||
onActiveChanged: {
|
||||
thumb.windowHeap.dragActive = active;
|
||||
if (active) {
|
||||
thumb.activeDragHandler = dragHandler;
|
||||
} else {
|
||||
thumbSource.Drag.drop();
|
||||
var globalPos = targetScreen.mapToGlobal(centroid.scenePosition);
|
||||
effect.checkItemDroppedOutOfScreen(globalPos, thumbSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
property DragManager activeDragHandler: dragHandler
|
||||
DragManager {
|
||||
id: dragHandler
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
|
||||
}
|
||||
DragManager {
|
||||
id: touchDragHandler
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
readonly property double downGestureProgress: {
|
||||
if (!active) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const startDistance = thumb.windowHeap.Kirigami.ScenePosition.y + thumb.windowHeap.height - centroid.scenePressPosition.y;
|
||||
const localPosition = thumb.windowHeap.Kirigami.ScenePosition.y + thumb.windowHeap.height - centroid.scenePosition.y;
|
||||
return Math.min(startDistance / localPosition, 1);
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (!active) {
|
||||
if (downGestureProgress > 0.6) {
|
||||
thumb.downGestureTriggered();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PC3.Button {
|
||||
id: closeButton
|
||||
visible: thumb.closeButtonVisible && (hoverHandler.hovered || Kirigami.Settings.tabletMode || Kirigami.Settings.hasTransientTouchInput) && thumb.client.closeable && !dragHandler.active
|
||||
anchors {
|
||||
right: thumbSource.right
|
||||
rightMargin: PlasmaCore.Units.smallSpacing
|
||||
top: thumbSource.top
|
||||
topMargin: PlasmaCore.Units.smallSpacing
|
||||
}
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
icon.name: "window-close"
|
||||
implicitWidth: PlasmaCore.Units.iconSizes.medium
|
||||
implicitHeight: implicitWidth
|
||||
onClicked: thumb.client.closeWindow();
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (selected) {
|
||||
thumb.windowHeap.resetSelected();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,3 +8,4 @@ plugin effectsplugin
|
|||
classname EffectKitExtensionPlugin
|
||||
|
||||
WindowHeap 1.0 WindowHeap.qml
|
||||
WindowHeapDelegate 1.0 WindowHeapDelegate.qml
|
||||
|
|
|
@ -119,8 +119,7 @@ Item {
|
|||
animationEnabled: container.animationEnabled
|
||||
organized: container.organized
|
||||
showOnly: container.effect.mode === WindowView.ModeWindowClass ? "activeClass" : selectedIds
|
||||
layout: effect.layout
|
||||
supportsCloseWindows: true
|
||||
layoutMode: effect.layout
|
||||
onWindowClicked: {
|
||||
if (eventPoint.event.button !== Qt.MiddleButton) {
|
||||
return;
|
||||
|
@ -138,6 +137,11 @@ Item {
|
|||
~KWinComponents.ClientFilterModel.Desktop &
|
||||
~KWinComponents.ClientFilterModel.Notification;
|
||||
}
|
||||
delegate: WindowHeapDelegate {
|
||||
windowHeap: heap
|
||||
opacity: 1 - downGestureProgress
|
||||
onDownGestureTriggered: client.closeWindow()
|
||||
}
|
||||
onActivated: effect.deactivate(animationDuration);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue