57 lines
2.1 KiB
GDScript
57 lines
2.1 KiB
GDScript
# 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())
|