status-desktop/ui/imports/shared/popups/SettingsDirtyToastMessage.qml

151 lines
4.1 KiB
QML

import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15
import utils 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
Rectangle {
id: root
property bool active: false
property bool cancelButtonVisible: true
property bool saveChangesButtonEnabled: false
property bool saveForLaterButtonVisible
property alias saveChangesText: saveChangesButton.text
property alias saveForLaterText: saveForLaterButton.text
property alias cancelChangesText: cancelChangesButton.text
property alias changesDetectedText: changesDetectedTextItem.text
property Flickable flickable: null
enum Type {
Danger,
Info
}
property int type: SettingsDirtyToastMessage.Type.Danger
signal saveChangesClicked
signal saveForLaterClicked
signal resetChangesClicked
function notifyDirty() {
toastAlertAnimation.running = true
saveChangesButton.forceActiveFocus()
}
implicitHeight: toastContent.implicitHeight + toastContent.anchors.topMargin + toastContent.anchors.bottomMargin
implicitWidth: toastContent.implicitWidth + toastContent.anchors.leftMargin + toastContent.anchors.rightMargin
opacity: active ? 1 : 0
color: Theme.palette.statusToastMessage.backgroundColor
radius: 8
border.color: type === SettingsDirtyToastMessage.Type.Danger ? Theme.palette.dangerColor2 : Theme.palette.primaryColor2
border.width: 2
layer.enabled: true
layer.effect: DropShadow {
verticalOffset: 3
radius: 8
samples: 15
fast: true
cached: true
color: root.border.color
spread: 0.1
}
onActiveChanged: {
if (!active || !flickable)
return;
const item = Global.applicationWindow.activeFocusItem;
const h1 = this.height;
const y1 = this.mapToGlobal(0, 0).y;
const h2 = item.height;
const y2 = item.mapToGlobal(0, 0).y;
const margin = 20;
const offset = h2 - (y1 - y2);
if (offset <= 0 || flickable.contentHeight <= 0)
return;
toastFlickAnimation.from = flickable.contentY;
toastFlickAnimation.to = flickable.contentY + offset + margin;
toastFlickAnimation.start()
}
NumberAnimation {
id: toastFlickAnimation
target: root.flickable
property: "contentY"
duration: 150
easing.type: Easing.InOutQuad
}
NumberAnimation on border.width {
id: toastAlertAnimation
from: 0
to: 4
loops: 2
duration: 600
onFinished: root.border.width = 2
}
Behavior on opacity {
NumberAnimation {}
}
MouseArea {
anchors.fill: parent
visible: root.active // This is required not to change cursorShape
enabled: root.active
hoverEnabled: true
}
RowLayout {
id: toastContent
anchors {
fill: parent
margins: 16
}
StatusBaseText {
id: changesDetectedTextItem
Layout.fillWidth: true
padding: 8
horizontalAlignment: Text.AlignHCenter
color: Theme.palette.directColor1
text: qsTr("Changes detected")
}
StatusButton {
id: cancelChangesButton
text: qsTr("Cancel")
enabled: root.active
visible: root.cancelButtonVisible
type: StatusBaseButton.Type.Danger
onClicked: root.resetChangesClicked()
}
StatusFlatButton {
id: saveForLaterButton
text: qsTr("Save for later")
enabled: root.active && root.saveChangesButtonEnabled
visible: root.saveForLaterButtonVisible
onClicked: root.saveForLaterClicked()
}
StatusButton {
id: saveChangesButton
objectName: "settingsDirtyToastMessageSaveButton"
enabled: root.active && root.saveChangesButtonEnabled
text: qsTr("Save changes")
onClicked: root.saveChangesClicked()
}
}
}