Files
2026-09-26 16:25:34 -04:00

141 lines
4.2 KiB
QML

import QtQuick
import QtQuick.Window
import qs.Common
Item {
id: root
property string confirmTitle: ""
property string confirmMessage: ""
property string reviewUrl: ""
property Item returnFocusItem: null
property string confirmButtonText: I18n.tr("Confirm")
property string cancelButtonText: I18n.tr("Cancel")
property color confirmButtonColor: Theme.primary
property var onConfirm: function () {}
property var onCancel: function () {}
property real backgroundOpacity: Theme.scrimAlpha
signal dialogClosed
function show(title, message, onConfirmCallback, onCancelCallback) {
showWithOptions({
"title": title,
"message": message,
"onConfirm": onConfirmCallback,
"onCancel": onCancelCallback
});
}
function showWithOptions(options) {
returnFocusItem = root.Window.window?.activeFocusItem ?? null;
confirmTitle = options.title || "";
confirmMessage = options.message || "";
reviewUrl = options.reviewUrl || "";
confirmButtonText = options.confirmText || I18n.tr("Confirm");
cancelButtonText = options.cancelText || I18n.tr("Cancel");
confirmButtonColor = options.confirmColor || Theme.primary;
onConfirm = options.onConfirm || (() => {});
onCancel = options.onCancel || (() => {});
visible = true;
dialogContent.keyboardNavigation = false;
dialogContent.selectedButton = 0;
focusDialog();
}
function focusDialog() {
if (!visible)
return;
overlayFocusScope.forceActiveFocus();
}
function close() {
visible = false;
const focusItem = returnFocusItem;
returnFocusItem = null;
if (focusItem?.visible && focusItem.enabled)
focusItem.forceActiveFocus(Qt.OtherFocusReason);
dialogClosed();
}
function _activate(button) {
const cancelCallback = onCancel;
const confirmCallback = onConfirm;
close();
if (button === 0) {
cancelCallback && cancelCallback();
return;
}
confirmCallback && confirmCallback();
}
anchors.fill: parent
visible: false
z: 100
Connections {
target: root.Window.window
enabled: root.visible
function onActiveFocusItemChanged() {
if (!overlayFocusScope.activeFocus)
Qt.callLater(root.focusDialog);
}
}
FocusScope {
id: overlayFocusScope
anchors.fill: parent
focus: root.visible
Keys.onPressed: event => dialogContent.handleKey(event)
Rectangle {
anchors.fill: parent
color: Theme.scrimColor
opacity: root.backgroundOpacity
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: root._activate(0)
}
Rectangle {
width: Math.min(Theme.smallBreakpoint, parent.width - Theme.spacingL * 2)
height: dialogContent.implicitHeight + Theme.spacingL * 2
anchors.centerIn: parent
radius: Theme.windowRadius
color: Theme.foregroundColor(Theme.cardSurface, Theme.isFloatingWindow(root))
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
MouseArea {
anchors.fill: parent
hoverEnabled: true
}
ConfirmDialogContent {
id: dialogContent
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.leftMargin: Theme.spacingL
anchors.rightMargin: Theme.spacingL
anchors.topMargin: Theme.spacingL
confirmTitle: root.confirmTitle
confirmMessage: root.confirmMessage
reviewUrl: root.reviewUrl
confirmButtonText: root.confirmButtonText
cancelButtonText: root.cancelButtonText
confirmButtonColor: root.confirmButtonColor
onButtonActivated: button => root._activate(button)
onCancelled: root._activate(0)
}
}
}
}