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

157 lines
4.3 KiB
QML

import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15
import utils 1.0
import shared.controls 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 saveChangesTooltipText: saveChangesButton.tooltipText
property alias saveChangesTooltipVisible: saveChangesButton.enabled
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()
}
DisabledTooltipButton {
id: saveChangesButton
objectName: "settingsDirtyToastMessageSaveButton"
buttonType: DisabledTooltipButton.Normal
text: qsTr("Save changes")
enabled: false
interactive: root.active && root.saveChangesButtonEnabled
onClicked: root.saveChangesClicked()
}
}
}