# Dialogs (P1) —— 基于 UiManager 的通用弹窗:confirm / alert / input。 # # var dlg := preload("res://ui/dialogs.gd").new(ui_manager) # ui_manager: UiManager # dlg.confirm("确定要删除吗?", func(): do_delete()) # dlg.alert("已保存") # dlg.input("输入名字", func(t): rename(t), "默认值") # # 走 UiManager.open(root, modal=true):ESC / 取消 关闭,回调只在确认时触发。 extends RefCounted var ui: CanvasLayer # UiManager func _init(ui_manager: CanvasLayer) -> void: ui = ui_manager func alert(text: String, on_close: Callable = Callable()) -> void: var d := _panel(320, 130) _label(d, text, 20, 24, 280) _button(d, "确定", 130, 88, func(): ui.close(d) if on_close.is_valid(): on_close.call()) ui.open(d, true) func confirm(text: String, on_ok: Callable, on_cancel: Callable = Callable()) -> void: var d := _panel(340, 140) _label(d, text, 20, 22, 300) _button(d, "确定", 60, 96, func(): ui.close(d) if on_ok.is_valid(): on_ok.call()) _button(d, "取消", 190, 96, func(): ui.close(d) if on_cancel.is_valid(): on_cancel.call()) ui.open(d, true) func input(prompt: String, on_submit: Callable, default_text := "") -> void: var d := _panel(360, 150) _label(d, prompt, 20, 18, 320) var le := LineEdit.new() le.text = default_text le.position = Vector2(20, 52) le.size = Vector2(320, 28) d.add_child(le) _button(d, "确定", 70, 104, func(): var t := le.text ui.close(d) if on_submit.is_valid(): on_submit.call(t)) _button(d, "取消", 200, 104, func(): ui.close(d)) le.grab_focus() ui.open(d, true) # --- 小工具 --------------------------------------------------------------- func _panel(w: int, h: int) -> Control: var p := Panel.new() p.custom_minimum_size = Vector2(w, h) p.size = Vector2(w, h) p.position = Vector2((1920 - w) / 2.0, (1080 - h) / 2.0) var sb := StyleBoxFlat.new() sb.bg_color = Color(0.11, 0.12, 0.15, 0.97) sb.border_color = Color(0.4, 0.36, 0.28) sb.set_border_width_all(1) sb.set_corner_radius_all(4) p.add_theme_stylebox_override("panel", sb) p.set_meta("is_titlebar", true) # 整块可拖 return p func _label(parent: Control, text: String, x: int, y: int, w: int) -> Label: var l := Label.new() l.text = text l.position = Vector2(x, y) l.size = Vector2(w, 0) l.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART l.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER parent.add_child(l) return l func _button(parent: Control, text: String, x: int, y: int, on_press: Callable) -> Button: var b := Button.new() b.text = text b.position = Vector2(x, y) b.size = Vector2(90, 26) b.pressed.connect(on_press) parent.add_child(b) return b