# VERTICAL SLICE - NOT FOR PRODUCTION # 实现 GDD:design/ux/battle.md(D 区 toast 槽——非模态提示:拒绝原因双源/voided/chord/ # 零合法板;自动消退 2.5s;pattern 1/10 呈现通道)。 # Date: 2026-09-12 # 高内聚边界:纯呈现——组合根决定何时弹什么文案;本类只管槽位堆叠与消退动画。 class_name ToastStack extends Control const LIFE_SEC := 2.5 const MAX_SLOTS := 3 const COL_INFO := UiKit.INK const COL_WARN := UiKit.RED_MINE # 危险红族——拒绝/作废(旗朱退役 2026-09-26) const COL_GOLD := UiKit.GOLD_DEEP # 奖励金族——提示/达成(深金档) var _slot_box: VBoxContainer func _init() -> void: mouse_filter = Control.MOUSE_FILTER_IGNORE set_anchors_preset(Control.PRESET_TOP_WIDE) custom_minimum_size = Vector2(0, 84) _slot_box = VBoxContainer.new() _slot_box.mouse_filter = Control.MOUSE_FILTER_IGNORE _slot_box.alignment = BoxContainer.ALIGNMENT_BEGIN _slot_box.add_theme_constant_override("separation", 2) add_child(_slot_box) func show_toast(text: String, tone: String = "info") -> void: while _slot_box.get_child_count() >= MAX_SLOTS: var old: Control = _slot_box.get_child(0) _slot_box.remove_child(old) old.queue_free() var row := PanelContainer.new() row.mouse_filter = Control.MOUSE_FILTER_IGNORE row.clip_contents = true # 缺陷①约束:固定槽高裁剪,不回流布局 row.custom_minimum_size = Vector2(0, 24) var sb := UiKit.panel_flat(UiKit.TOAST_BG, COL_INFO, 2, 1, Vector4(8, 2, 8, 2)) var col := COL_INFO if tone == "warn": col = COL_WARN elif tone == "gold": col = COL_GOLD sb.border_color = col row.add_theme_stylebox_override("panel", sb) var lab := UiKit.label(("⚠ " if tone == "warn" else "") + text, 14, tone != "info") lab.add_theme_color_override("font_color", col) lab.clip_text = true row.add_child(lab) _slot_box.add_child(row) var tw := row.create_tween() tw.tween_interval(LIFE_SEC) tw.tween_property(row, "modulate:a", 0.0, 0.35) tw.tween_callback(func(): if is_instance_valid(row): row.queue_free())