2026-10-09 12:49:07 +02:00

53 lines
1.9 KiB
GDScript

@tool
extends RefCounted
## Self-freeing confirmation-dialog factory for the dock.
##
## A stateless `static func` helper (no instance). The dock's two yes/no
## confirm flows (clear-audit, overwrite-.mcp.json) build the same
## ConfirmationDialog shape; this is the single place that shape — and the
## self-free guarantee — lives.
# Toast/severity-free by design: the factory only builds + shows the dialog and
# runs the caller's confirm/cancel callbacks. Any toast a flow needs is emitted
# from within its own callback (the caller's concern, not the factory's).
## Builds a ConfirmationDialog, pops it centered on the editor base control, and
## frees it on EVERY dismissal — OK runs `on_confirm`, Cancel/Esc/✕ runs
## `on_cancel` (if given) — then `queue_free()`s itself. No caller cleanup is
## needed: the self-free is baked in here so no call site can leak the dialog.
##
## `cancel_text` empty → keep the default "Cancel" button label. `on_cancel`
## empty → dismiss-and-free only (the plain "are you sure?" case).
##
## The engine routes the window-close (✕) and Esc through the same `canceled`
## signal as the Cancel button (AcceptDialog::_cancel_pressed), so connecting
## `confirmed` + `canceled` covers all three dismissal paths.
static func confirm(
title: String,
body: String,
ok_text: String,
on_confirm: Callable,
cancel_text: String = "",
on_cancel: Callable = Callable()) -> void:
var dialog := ConfirmationDialog.new()
dialog.exclusive = false
dialog.title = title
dialog.dialog_text = body
dialog.ok_button_text = ok_text
if not cancel_text.is_empty():
dialog.cancel_button_text = cancel_text
dialog.confirmed.connect(func() -> void:
if on_confirm.is_valid():
on_confirm.call()
dialog.queue_free()
)
dialog.canceled.connect(func() -> void:
if on_cancel.is_valid():
on_cancel.call()
dialog.queue_free()
)
EditorInterface.get_base_control().add_child(dialog)
dialog.popup_centered()