Files
gplan-2/game/presentation/views/save_select_overlay.gd

113 lines
5.6 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## VERTICAL SLICE - NOT FOR PRODUCTION
## 选档界面·全屏页:3 存档位(新档/进档/删档)+ 槽摘要三项(钥石余额/冒险成功局数/冒险总局数)。
## 结构树层级:选档 → 进档 → 营地(本面零存档内功能入口——禁营地/冒险/生涯跳转与购买/查看入口);
## 删档必经二次确认(确认弹窗与分派归组合根消费方编排——本面只发意图信号)。
## 槽数与槽态(空/有档)唯一来自组合根喂入数据(open_save_select 每开重建——组合根经卡① 窥视 API
## 取数;视图禁自数文件/禁自拼槽名/禁硬编码槽判定);Q1 甲=零预选(视图零选中态字段、零持久化)。
## 摘要面仅三项,零断点/未完冒险读数(裁决 4——槽卡只消费喂入三键)。
## 构成件全部经 UiKit 工厂产出——零新素材/新色值(契约 7)。
class_name SaveSelectOverlay
extends Control
signal closed
signal new_slot_requested(slot: int)
signal load_slot_requested(slot: int)
signal delete_slot_requested(slot: int)
var _rows_box: VBoxContainer
var _summary_labels: Dictionary[int, Label] = {} # 槽号→摘要读数 label(冒险成功/冒险两值——探针取值缝)
var _occupied_flags: Dictionary[int, bool] = {} # 槽号→有档态(操作集二分断言缝;判定源=喂入数据)
var _new_btns: Dictionary[int, Button] = {} # 槽号→新档钮(空/坏槽——操作集断言与点击链驱动缝)
var _load_btns: Dictionary[int, Button] = {} # 槽号→进档钮(有档槽)
var _delete_btns: Dictionary[int, Button] = {} # 槽号→删档钮(有档槽——确认链驱动缝)
func _init() -> void:
# 全屏页壳(career_overlay 同款先例——暖亮底+石纹+暗角+56px 通栏顶条+内容列)
var page: Dictionary[Variant, Variant] = UiKit.page_shell(self, true)
var top: HBoxContainer = page.top_row
top.add_child(UiKit.label("存 档",UiKit.FS_TITLE, true, UiKit.WARM))
var top_sp := Control.new()
top_sp.size_flags_horizontal = Control.SIZE_EXPAND_FILL
top.add_child(top_sp)
var close_btn := UiKit.button("返回", 90.0) # 紧凑返回钮(生涯/设置先例形制)
close_btn.tooltip_text = "关闭选档界面,返回主菜单(进入存档位前不发生任何进度读写)"
close_btn.pressed.connect(_emit_closed)
top.add_child(close_btn)
var box: VBoxContainer = page.box
# 对比度口径:亮底页用亮墨族 token(career_overlay 同款——深墨族禁用)
box.add_child(UiKit.label("选择一个存档位进入。空存档位可新开档;删档需二次确认。",
UiKit.FS_HINT, false, UiKit.WARM_SOFT))
_rows_box = VBoxContainer.new()
_rows_box.add_theme_constant_override("separation", 10)
box.add_child(_rows_box)
visible = false # 显式初始化——不靠树序巧合(缺陷⑤家族纪律)
# ---- 开层(组合根唯一调用口——槽数据随开重建;删档确认后就地重喂刷新)----
# data = {"slots": [{"slot": int, "occupied": bool, "keystone": int, "cleared": int, "total": int}, ...]}
# 槽数=数组长度(位数唯一在卡① 承载面 SLOT_COUNT);occupied=组合根经窥视 API 判定
# (has_file∧readable——坏槽/高版本槽按空槽呈现,Q2 裁甲);摘要仅消费三键(裁决 4)。
func open_save_select(data: Dictionary) -> void:
for c in _rows_box.get_children():
_rows_box.remove_child(c)
c.queue_free() # 先摘树后释放——重建无同帧叠影
_slot_labels_clear()
var slots: Array[Variant] = []
slots.assign(data.get("slots", [])) # 元素为 Dictionary(喂入合同)——typed 容器过类型闸 R1
for sd: Dictionary in slots:
_build_slot_row(sd)
visible = true
func _slot_labels_clear() -> void:
_summary_labels.clear()
_occupied_flags.clear()
_new_btns.clear()
_load_btns.clear()
_delete_btns.clear()
func _build_slot_row(sd: Dictionary) -> void:
var slot := int(sd.get("slot", 0))
var occupied := bool(sd.get("occupied", false))
_occupied_flags[slot] = occupied
var row := HBoxContainer.new()
row.add_theme_constant_override("separation", 14)
_rows_box.add_child(row)
var name_l := UiKit.label("存档位 %d" % slot,UiKit.FS_SUB, true, UiKit.WARM)
name_l.custom_minimum_size = Vector2(110, 0)
row.add_child(name_l)
var sp := Control.new()
sp.size_flags_horizontal = Control.SIZE_EXPAND_FILL
if occupied:
row.add_child(UiKit.keystone_badge("钥石 %d" % int(sd.get("keystone", 0))))
var summary_l := UiKit.label("冒险成功 %d 局 · 冒险 %d 局" % [int(sd.get("cleared", 0)), int(sd.get("total", 0))],
UiKit.FS_BODY, false, UiKit.CANDLE)
_summary_labels[slot] = summary_l # 摘要读数缝(禁词断言枚举 Label 全集时含此件)
row.add_child(summary_l)
row.add_child(sp)
var load_btn := UiKit.primary_button("进档")
load_btn.tooltip_text = "激活存档位 %d 并进入营地" % slot
load_btn.pressed.connect(func() -> void: load_slot_requested.emit(slot))
row.add_child(load_btn)
_load_btns[slot] = load_btn
var del_btn := UiKit.danger_button("删档", "删除存档位 %d(需二次确认——删除后该档不可恢复)" % slot)
del_btn.pressed.connect(func() -> void: delete_slot_requested.emit(slot))
row.add_child(del_btn)
_delete_btns[slot] = del_btn
else:
row.add_child(UiKit.label("空存档位",UiKit.FS_BODY, false, UiKit.WARM_FAINT))
row.add_child(sp)
var new_btn := UiKit.primary_button("新档")
new_btn.tooltip_text = "在存档位 %d 新开一档(初始白板)" % slot
new_btn.pressed.connect(func() -> void: new_slot_requested.emit(slot))
row.add_child(new_btn)
_new_btns[slot] = new_btn
func _emit_closed() -> void:
closed.emit()