2023-05-13 15:15:52 +00:00
|
|
|
// SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org>
|
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
2021-12-22 23:29:00 +00:00
|
|
|
|
2023-05-13 15:15:52 +00:00
|
|
|
import QtQuick
|
|
|
|
|
import QtQuick.Effects
|
2021-12-22 23:29:00 +00:00
|
|
|
|
|
|
|
|
import org.kde.kirigami 2.12 as Kirigami
|
|
|
|
|
|
|
|
|
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
|
|
|
|
|
|
|
|
|
Item {
|
|
|
|
|
id: root
|
|
|
|
|
|
|
|
|
|
default property Item contentItem
|
|
|
|
|
|
|
|
|
|
property bool tapEnabled: false
|
|
|
|
|
|
|
|
|
|
property bool swipeGestureEnabled: false
|
|
|
|
|
|
|
|
|
|
property real dragOffset: 0
|
|
|
|
|
|
|
|
|
|
signal tapped()
|
|
|
|
|
signal dismissRequested()
|
|
|
|
|
signal configureClicked() // TODO implement settings button
|
|
|
|
|
|
|
|
|
|
onContentItemChanged: {
|
|
|
|
|
contentItem.parent = contentParent;
|
|
|
|
|
contentItem.anchors.fill = contentParent;
|
2023-07-25 01:13:52 +00:00
|
|
|
contentItem.anchors.margins = Kirigami.Units.gridUnit;
|
2021-12-22 23:29:00 +00:00
|
|
|
contentParent.children.push(contentItem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
implicitHeight: contentParent.implicitHeight
|
|
|
|
|
|
|
|
|
|
NumberAnimation on dragOffset {
|
|
|
|
|
id: dragAnim
|
2023-07-25 01:13:52 +00:00
|
|
|
duration: Kirigami.Units.longDuration
|
2021-12-22 23:29:00 +00:00
|
|
|
onFinished: {
|
|
|
|
|
if (to !== 0) {
|
|
|
|
|
root.dismissRequested();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-13 15:15:52 +00:00
|
|
|
// shadow
|
|
|
|
|
MultiEffect {
|
2021-12-22 23:29:00 +00:00
|
|
|
anchors.fill: mainCard
|
2023-05-13 15:15:52 +00:00
|
|
|
visible: Math.abs(dragOffset) !== root.width
|
|
|
|
|
source: mainCard
|
|
|
|
|
blurMax: 16
|
|
|
|
|
shadowEnabled: true
|
|
|
|
|
shadowVerticalOffset: 1
|
|
|
|
|
shadowOpacity: 0.5
|
2023-07-25 01:13:52 +00:00
|
|
|
shadowColor: Qt.lighter(Kirigami.Theme.backgroundColor, 0.1)
|
2021-12-22 23:29:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shadow
|
|
|
|
|
Rectangle {
|
|
|
|
|
visible: Math.abs(dragOffset) !== root.width
|
|
|
|
|
anchors.fill: mainCard
|
|
|
|
|
anchors.leftMargin: -1
|
|
|
|
|
anchors.rightMargin: -1
|
|
|
|
|
anchors.bottomMargin: -1
|
2023-05-13 15:15:52 +00:00
|
|
|
|
2023-07-25 01:13:52 +00:00
|
|
|
color: Qt.darker(Kirigami.Theme.backgroundColor, 1.3)
|
|
|
|
|
radius: Kirigami.Units.smallSpacing
|
2021-12-22 23:29:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// card
|
|
|
|
|
Rectangle {
|
|
|
|
|
id: mainCard
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.leftMargin: root.dragOffset > 0 ? root.dragOffset : 0
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
anchors.rightMargin: root.dragOffset < 0 ? -root.dragOffset : 0
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
|
2023-07-25 01:13:52 +00:00
|
|
|
color: (root.tapEnabled && mouseArea.pressed) ? Qt.darker(Kirigami.Theme.backgroundColor, 1.1) : Kirigami.Theme.backgroundColor
|
|
|
|
|
radius: Kirigami.Units.smallSpacing
|
2021-12-22 23:29:00 +00:00
|
|
|
implicitHeight: contentParent.implicitHeight
|
|
|
|
|
clip: true
|
|
|
|
|
|
|
|
|
|
// ensure this is behind the content to not interfere
|
|
|
|
|
MouseArea {
|
|
|
|
|
id: mouseArea
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: {
|
|
|
|
|
if (root.tapEnabled) {
|
|
|
|
|
root.tapped()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// content parent
|
|
|
|
|
Item {
|
|
|
|
|
id: contentParent
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: root.dragOffset > 0 ? parent.left : undefined
|
|
|
|
|
anchors.right: root.dragOffset < 0 ? parent.right : undefined
|
|
|
|
|
|
|
|
|
|
width: root.width
|
|
|
|
|
implicitHeight: contentItem.implicitHeight + contentItem.anchors.topMargin + contentItem.anchors.bottomMargin
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DragHandler {
|
|
|
|
|
id: dragHandler
|
|
|
|
|
enabled: root.swipeGestureEnabled
|
|
|
|
|
yAxis.enabled: false
|
|
|
|
|
|
|
|
|
|
property real startDragOffset: 0
|
|
|
|
|
property real startPosition: 0
|
|
|
|
|
property bool startActive: false
|
|
|
|
|
|
|
|
|
|
onTranslationChanged: {
|
|
|
|
|
if (startActive) {
|
|
|
|
|
startDragOffset = root.dragOffset;
|
|
|
|
|
startPosition = translation.x;
|
|
|
|
|
startActive = false;
|
|
|
|
|
}
|
|
|
|
|
root.dragOffset = startDragOffset + (translation.x - startPosition);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onActiveChanged: {
|
|
|
|
|
dragAnim.stop();
|
|
|
|
|
startActive = active;
|
|
|
|
|
|
|
|
|
|
if (!active) { // release event
|
2023-07-25 01:13:52 +00:00
|
|
|
let threshold = Kirigami.Units.gridUnit * 5; // drag threshold
|
2021-12-22 23:29:00 +00:00
|
|
|
if (root.dragOffset > threshold) {
|
|
|
|
|
dragAnim.to = root.width;
|
|
|
|
|
} else if (root.dragOffset < -threshold) {
|
|
|
|
|
dragAnim.to = -root.width;
|
|
|
|
|
} else {
|
|
|
|
|
dragAnim.to = 0;
|
|
|
|
|
}
|
|
|
|
|
dragAnim.restart();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|