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

185 lines
5.3 KiB
QML

import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtGraphicalEffects 1.15
import utils 1.0
import shared.controls 1.0
import shared.panels 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
Rectangle {
id: root
property bool loading: false
property bool active: false
property bool cancelButtonVisible: true
property bool saveChangesButtonEnabled: false
property bool saveForLaterButtonVisible
property alias saveChangesText: saveChangesButton.text
property string saveChangesTooltipText
property alias saveForLaterText: saveForLaterButton.text
property alias cancelChangesText: cancelChangesButton.text
property alias changesDetectedText: changesDetectedTextItem.text
property alias additionalComponent: additionalTextComponent
readonly property string defaultChangesDetectedText: qsTr("Changes detected")
readonly property string defaultSaveChangesText: qsTr("Save changes")
readonly property string defaultSaveForLaterText: qsTr("Save for later")
readonly property string defaultCancelChangesText: qsTr("Cancel")
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 = Window.window.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
}
ColumnLayout {
id: toastContent
anchors.fill: parent
anchors.margins: Theme.padding
spacing: Theme.padding
RowLayout {
Layout.alignment: Qt.AlignHCenter
StatusBaseText {
id: changesDetectedTextItem
Layout.fillWidth: true
padding: 8
horizontalAlignment: Text.AlignHCenter
color: Theme.palette.directColor1
text: root.defaultChangesDetectedText
}
StatusButton {
id: cancelChangesButton
text: root.defaultCancelChangesText
enabled: !root.loading && root.active
visible: root.cancelButtonVisible
type: StatusBaseButton.Type.Danger
onClicked: root.resetChangesClicked()
}
StatusFlatButton {
id: saveForLaterButton
text: root.defaultSaveForLaterText
loading: root.loading
enabled: root.active && root.saveChangesButtonEnabled
visible: root.saveForLaterButtonVisible
onClicked: root.saveForLaterClicked()
}
StatusButton {
id: saveChangesButton
objectName: "settingsDirtyToastMessageSaveButton"
loading: root.loading
text: root.defaultSaveChangesText
interactive: root.active && root.saveChangesButtonEnabled
tooltip.text: root.saveChangesTooltipText
onClicked: root.saveChangesClicked()
}
}
Separator {
id: separator
Layout.fillWidth: true
visible: additionalTextComponent.visible
}
StatusBaseText {
id: additionalTextComponent
Layout.alignment: Qt.AlignHCenter
font.pixelSize: Theme.tertiaryTextFontSize
visible: false
}
}
}