C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Successful in 20s
JS/TS / lint (pull_request) Successful in 22s
Python / static (pull_request) Successful in 57s
Rust / fmt (pull_request) Successful in 1m2s
C++ / build (pull_request) Successful in 2m10s
Rust / build (pull_request) Successful in 1m50s
Rust / clippy (pull_request) Successful in 1m25s
Python / verify (pull_request) Successful in 2m58s
C++ / clang-tidy (pull_request) Successful in 7m8s
251 lines
5.2 KiB
QML
251 lines
5.2 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import QtQuick.Layouts
|
|
import ZShell.Blobs
|
|
import qs.Components
|
|
import ZShell.Config
|
|
import qs.Services
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property bool acceptAllowed: true
|
|
required property string acceptLabel
|
|
required property Component content
|
|
required property string header
|
|
property int horizontalContentMargin
|
|
required property string icon
|
|
required property string label
|
|
property bool open
|
|
property real openHeight: Math.min(rootParent.height * 0.8, 600)
|
|
property real openWidth: Math.min(rootParent.width * 0.8, 400)
|
|
required property Item rootParent
|
|
property bool separateContent
|
|
|
|
signal accepted
|
|
signal cancelled
|
|
|
|
function reparentWrapper(): void {
|
|
const newParent = open ? rootParent : root;
|
|
const pos = dialogWrapper.mapToItem(newParent, 0, 0);
|
|
dialogWrapper.parent = newParent;
|
|
dialogWrapper.x = pos.x;
|
|
dialogWrapper.y = pos.y;
|
|
}
|
|
|
|
Layout.fillWidth: true
|
|
implicitHeight: openButton.implicitHeight
|
|
z: open || dialogTransition.running ? 2 : 0
|
|
|
|
BlobGroup {
|
|
id: blobGroup
|
|
|
|
color: root.open ? Colors.palette.m3surfaceContainerHighest : Colors.tPalette.m3surfaceContainer
|
|
|
|
Behavior on color {
|
|
CAnim {
|
|
}
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: backdrop
|
|
|
|
anchors.fill: parent
|
|
enabled: false
|
|
hoverEnabled: enabled
|
|
parent: root.open ? root.rootParent : root
|
|
|
|
onClicked: root.open = false
|
|
}
|
|
|
|
Item {
|
|
id: dialogWrapper
|
|
|
|
height: openButton.implicitHeight
|
|
width: root.width
|
|
z: 1
|
|
|
|
states: State {
|
|
name: "open"
|
|
when: root.open
|
|
|
|
PropertyChanges {
|
|
backdrop.enabled: true
|
|
dialogBg.bottomLeftRadius: Tokens.rounding.largeIncreased
|
|
dialogBg.bottomRightRadius: Tokens.rounding.largeIncreased
|
|
dialogBg.radius: Tokens.rounding.largeIncreased
|
|
dialogContent.opacity: 1
|
|
dialogWrapper.height: root.openHeight
|
|
dialogWrapper.width: root.openWidth
|
|
dialogWrapper.x: (root.rootParent.width - root.openWidth) / 2
|
|
dialogWrapper.y: (root.rootParent.height - root.openHeight) / 2
|
|
elevation.opacity: 1
|
|
openButton.opacity: 0
|
|
}
|
|
}
|
|
transitions: Transition {
|
|
id: dialogTransition
|
|
|
|
SequentialAnimation {
|
|
ScriptAction {
|
|
script: root.reparentWrapper()
|
|
}
|
|
|
|
Anim {
|
|
properties: "x,y"
|
|
}
|
|
}
|
|
|
|
PropertyAction {
|
|
property: "enabled"
|
|
}
|
|
|
|
Anim {
|
|
properties: "opacity,radius,bottomLeftRadius,bottomRightRadius"
|
|
type: Anim.DefaultEffects
|
|
}
|
|
|
|
Anim {
|
|
properties: "width,height"
|
|
}
|
|
}
|
|
|
|
Elevation {
|
|
id: elevation
|
|
|
|
anchors.fill: parent
|
|
bottomLeftRadius: dialogBg.bottomLeftRadius
|
|
bottomRightRadius: dialogBg.bottomRightRadius
|
|
level: 4
|
|
opacity: 0
|
|
radius: dialogBg.radius
|
|
|
|
transform: Matrix4x4 {
|
|
matrix: dialogBg.deformMatrix
|
|
}
|
|
}
|
|
|
|
BlobRect {
|
|
id: dialogBg
|
|
|
|
anchors.fill: parent
|
|
bottomLeftRadius: Tokens.rounding.largeIncreased
|
|
bottomRightRadius: Tokens.rounding.largeIncreased
|
|
deformScale: 0
|
|
group: blobGroup
|
|
opacity: blobGroup.color.a * (root.enabled ? 1 : 0.5)
|
|
radius: Tokens.rounding.extraSmall
|
|
}
|
|
|
|
RowButton {
|
|
id: openButton
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
color: "transparent"
|
|
height: Math.min(implicitHeight, parent.height) // Clamp to parent height due to overshoot anim
|
|
icon: root.icon
|
|
last: true
|
|
text: root.label
|
|
|
|
transform: Matrix4x4 {
|
|
matrix: dialogBg.deformMatrix
|
|
}
|
|
|
|
onClicked: root.open = true
|
|
}
|
|
|
|
Loader {
|
|
id: dialogContent
|
|
|
|
active: opacity > 0
|
|
anchors.fill: parent
|
|
asynchronous: true
|
|
opacity: 0
|
|
|
|
sourceComponent: MouseArea {
|
|
onWheel: event => event.accepted = true
|
|
|
|
ColumnLayout {
|
|
anchors.bottomMargin: Tokens.padding.largeIncreased
|
|
anchors.fill: parent
|
|
anchors.margins: Tokens.padding.extraLarge
|
|
spacing: 0
|
|
|
|
CustomText {
|
|
font.pointSize: Tokens.font.size.large
|
|
text: root.header
|
|
}
|
|
|
|
Loader {
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Tokens.spacing.medium
|
|
active: root.separateContent
|
|
|
|
sourceComponent: CustomRect {
|
|
color: Colors.palette.m3outline
|
|
implicitHeight: 1
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
Layout.leftMargin: root.horizontalContentMargin
|
|
Layout.rightMargin: root.horizontalContentMargin
|
|
sourceComponent: root.content
|
|
}
|
|
|
|
Loader {
|
|
Layout.bottomMargin: Tokens.spacing.medium
|
|
Layout.fillWidth: true
|
|
active: root.separateContent
|
|
|
|
sourceComponent: CustomRect {
|
|
color: Colors.palette.m3outline
|
|
implicitHeight: 1
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.alignment: Qt.AlignRight
|
|
spacing: Tokens.spacing.extraSmall
|
|
|
|
TextButton {
|
|
horizontalPadding: Tokens.padding.largeIncreased
|
|
isRound: true
|
|
text: qsTr("Cancel")
|
|
type: TextButton.Text
|
|
verticalPadding: Tokens.padding.small
|
|
|
|
onClicked: {
|
|
root.cancelled();
|
|
root.open = false;
|
|
}
|
|
}
|
|
|
|
TextButton {
|
|
enabled: root.acceptAllowed
|
|
horizontalPadding: Tokens.padding.largeIncreased
|
|
isRound: true
|
|
text: root.acceptLabel
|
|
type: TextButton.Text
|
|
verticalPadding: Tokens.padding.small
|
|
|
|
onClicked: {
|
|
root.accepted();
|
|
root.open = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
transform: Matrix4x4 {
|
|
matrix: dialogBg.deformMatrix
|
|
}
|
|
}
|
|
}
|
|
}
|