iter54-卡2:营地交互修复批(开局隐藏点收一处 _start_adventure+确认弹窗按钮位次镜像确认→次→取消+营地顶栏可见栏体 camp_hud_band_surface 单参出口 CAMP_HUD_BAND×0.80)——对照表 R1-R8 全绿(探针 R1/R2/R4 落点断言/confirm_dialog_test 七断言/系统测试 R5 五钉 76 检查 0 失败/R6 WCAG 4.29:1),S13 ui_kit 基线 23→24 随卡预申报修订
This commit is contained in:
1 parent
96123978c1
commit
4c424af358
12 files changed
+278
-17
No files matched your search
@@ -190,8 +190,8 @@ func _start_adventure_from_menu() -> void:
|
||||
# 主菜单「开始冒险」钮已随三入口化撤出(卡② mn6——主菜单侧断点互斥确认链同步摘除,
|
||||
# 弹窗本体与两分支逻辑归卡④大门承接)。本函数为探针直调中间态保留(mn10——冒险段探针
|
||||
# 直调位点逐个登记实现报告「已知中间态」;卡④到位后由大门两分支换代)。无激活态写盘拒绝
|
||||
# 由卡① sv3 承接(结算不落盘)。
|
||||
ui.screens.start_overlay.visible = false
|
||||
# 由卡① sv3 承接(结算不落盘)。开始层隐藏已收进 _start_adventure()(营地交互修复批契约 1
|
||||
# ——开局路径隐藏点唯一出口)。
|
||||
_start_adventure()
|
||||
|
||||
|
||||
@@ -290,6 +290,7 @@ static func build_adventure_params(save_manager_ref: SaveManagerCore, meta_ref:
|
||||
# 冒险模式(三关连探——AdventureRunner 编排;转发信号签名与 runner 一致,接线照原样对接;
|
||||
# 信号连接只在组合根)
|
||||
func _start_adventure() -> void:
|
||||
ui.screens.start_overlay.visible = false # 开局路径开始层隐藏唯一出口(营地交互修复批契约 1——三处调用方经此收口;失败分支开始层终态=隐藏,致命屏接管)
|
||||
ui.flow.close(ui.modals.menu.debug_overlay) # 开冒险路径显式关浮窗(调试浮窗默认开态下开局不带窗;对局中经角标再开)
|
||||
begin_session(true)
|
||||
_wire_adventure()
|
||||
|
||||
@@ -11,10 +11,15 @@ func _init() -> void:
|
||||
set_anchors_preset(Control.PRESET_TOP_WIDE)
|
||||
custom_minimum_size = Vector2(0, 48) # 高 48px 浮层覆盖、不挤压画面(camp.md §顶栏)
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE # HUD 栏不挡场景命中区(浮层覆盖语义)
|
||||
UiKit.camp_hud_band_surface(self) # 栏体色面——整件外观单一出口(色值与 α、铺满、不吃点击、挂载全在出口内);先入=绘制序底,徽章后入不被盖
|
||||
_badge = UiKit.keystone_badge("钥石 0")
|
||||
_badge.set_anchors_preset(Control.PRESET_CENTER_RIGHT)
|
||||
_badge.position = Vector2(-160, 8) # 顶栏右位次(UiKit 现行件域内——代拍板 3)
|
||||
add_child(_badge)
|
||||
var dock := HBoxContainer.new() # 右对齐容器承载徽章(Q2 已裁乙——位数增宽自然向左展;摆位机制先例=confirm_dialog 钮行同款容器 alignment)
|
||||
dock.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dock.offset_right = -12.0 # 右缘内缩 12px(UiKit 钮间距同档——白名单 3)
|
||||
dock.alignment = BoxContainer.ALIGNMENT_END
|
||||
dock.mouse_filter = Control.MOUSE_FILTER_IGNORE # 容器自身默认 STOP——与出口内 IGNORE 是两个点,必须同批落(漏一处顶排物件点不动)
|
||||
dock.add_child(_badge)
|
||||
add_child(dock)
|
||||
|
||||
|
||||
## 余额写入(格式串=既有消费面同款「钥石 %d」——badge 工厂约定单点,禁第二格式串)
|
||||
|
||||
@@ -30,13 +30,15 @@ func _init() -> void:
|
||||
box.add_child(btn_row)
|
||||
_cancel_btn = UiKit.button("取消")
|
||||
_cancel_btn.pressed.connect(_emit_cancelled)
|
||||
btn_row.add_child(_cancel_btn)
|
||||
_secondary_btn = UiKit.button("次选项")
|
||||
_secondary_btn.pressed.connect(_emit_secondary)
|
||||
btn_row.add_child(_secondary_btn)
|
||||
_confirm_btn = UiKit.button("确认")
|
||||
_confirm_btn.pressed.connect(_emit_confirmed)
|
||||
# 位次定值(HUD框架.md:90 三条纪律·其三——推进钮在左、次推进居中、维持在右;四处消费方
|
||||
# 共用本件同一序。信号按按钮对象路由、不按位次——换序不改路由〔营地交互修复批契约 3〕)
|
||||
btn_row.add_child(_confirm_btn)
|
||||
btn_row.add_child(_secondary_btn)
|
||||
btn_row.add_child(_cancel_btn)
|
||||
visible = false
|
||||
|
||||
|
||||
|
||||
@@ -193,6 +193,7 @@ const TIP_BG := Color(0.16, 0.12, 0.09, 0.96) # tooltip 深底
|
||||
const STAND_STONE := Color8(150, 130, 100) # 站桩石板地台·板身(standee_body 方向稿取色)
|
||||
const PLAZA_EDGE := Color8(76, 64, 56) # 小石台描边(art-bible §4.1 换色合并②合并目标——贴图已落此值,缺位回退同值)
|
||||
const CAMP_HEADER_BAND := Color8(110, 69, 38) # 营地柜台头带深棕 #6E4526(4-camp.png 方向稿取色;对齐 demo --wood-deep)
|
||||
const CAMP_HUD_BAND := Color(CAMP_HEADER_BAND, 0.80) # 营地顶栏栏体=头带深棕×α0.80(camp.md §顶栏定值——派生收口单点,非色板新增;同文件 TOAST_BG/TIP_BG 带 α 先例)
|
||||
const CAMP_ROW_PLATE := Color8(240, 230, 206) # 营地行板暖米(同上)
|
||||
const CAMP_BADGE_PANEL := Color8(40, 32, 24) # 营地钥石徽暗底(同上)
|
||||
const HP_BAR_BACK := Color8(40, 34, 32) # 迷你血条深底 #282220(兼血数垫牌;站桩名字行素底同源——§6.1/§7.2 文字禁压地台)
|
||||
@@ -656,6 +657,19 @@ static func keystone_badge(text: String, icon_path := TEX_ICON_KEYSTONE, icon_px
|
||||
return KeystoneBadge.new(text, icon_path, icon_px)
|
||||
|
||||
|
||||
## 营地顶栏栏体面(整件外观单一出口——营地交互修复批契约 4/5):色值与 α、铺满、不吃点击、
|
||||
## 挂上宿主五件事全写死在体内;形参只有 host——调用方没有可以忘记的形参。返回句柄供调用方
|
||||
## 读取与断言;徽章摆位不由本出口负责(归顶栏件内右对齐容器)。须在宿主入树前调用
|
||||
## (set_anchors_preset 是入树前动作——_modal_dim/overlay_bg 同形)。
|
||||
static func camp_hud_band_surface(host: Control) -> ColorRect:
|
||||
var rect := ColorRect.new()
|
||||
rect.color = CAMP_HUD_BAND
|
||||
rect.set_anchors_preset(Control.PRESET_FULL_RECT) # 四边 offset 归零铺满宿主
|
||||
rect.mouse_filter = Control.MOUSE_FILTER_IGNORE # 栏体不吃点击(顶排物件命中区不受阻——契约 5)
|
||||
host.add_child(rect)
|
||||
return rect
|
||||
|
||||
|
||||
# 按钮皮·五态矩阵(逐实例 override 不动主题层)
|
||||
# 悬停:常态图+modulate 提亮(0.06 档与 primary_button 现行 lightened(0.06) 同纪律,零新素材);
|
||||
# 禁用:本族底+α0.45 幽灵化(与 font_disabled_color 同纪律);
|
||||
|
||||
@@ -744,10 +744,30 @@ func _ready() -> void:
|
||||
_problems.append("大门取消:未无变更退回营地(写口零调用/营地根 visible 失守)〔营地图批 V3〕")
|
||||
ProbeUiUtil.push_click_at(main, main.ui.modals.camp.scene.get_hotspot_rect(&"gate").get_center())
|
||||
await get_tree().process_frame
|
||||
ProbeUiUtil.push_click(main, main.ui.modals.menu.confirm_dialog._confirm_btn) # 真点「确认」→开始新冒险
|
||||
await get_tree().process_frame
|
||||
# R4 位次真点(营地交互修复批——位次与语义绑定钉):真点前消费方前置读(gate_new 在册)→
|
||||
# 按类型定位按钮行 child(0) 全局矩形中心真点——位次若错接,此点命中「否」,下方主证(翻转)即红。
|
||||
# oracle: design/gdd/systems/表现与支撑/HUD框架.md:90 确认弹窗位次定值:推进在左、维持居右(R4 位次真点)
|
||||
if String(main._confirm_consumer) != "gate_new":
|
||||
_problems.append("R4 前置:确认消费方非 gate_new(分派面漂移)〔营地交互批 V3〕")
|
||||
var gate_row := _first_hbox(main.ui.modals.menu.confirm_dialog)
|
||||
if gate_row == null or gate_row.get_child_count() != 3:
|
||||
_problems.append("R4:按钮行缺失或子节点数≠3(位次判据面塌)〔营地交互批 V3〕")
|
||||
else:
|
||||
ProbeUiUtil.push_click_at(main, (gate_row.get_child(0) as Control).get_global_rect().get_center()) # 真点推进钮(左位)
|
||||
for i in 3:
|
||||
await get_tree().process_frame # 停点成形帧口径(先例 3 帧——screen_flow_probe 选路停点成形窗)
|
||||
if not main.run_scope.is_adventure or main.ui.modals.camp.scene.visible:
|
||||
_problems.append("大门确认:冒险未发起或营地场景屏未隐藏〔营地图批 V3〕〔营地图批 B1〕")
|
||||
if String(main._confirm_consumer) != "":
|
||||
_problems.append("R4 主证:确认后消费方未清零〔营地交互批 V3〕")
|
||||
# 开局终态两钉(营地交互修复批——开始层隐藏收一处后的落点断言):
|
||||
# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:78 关卡开始 → 呈现节点图选路停点(开局终态两钉)
|
||||
# R1=确认后开始层不可见(被测改动特有提交面——修复前该句恒红=「开局被开始层盖住」缺陷本体);
|
||||
# R2=关卡画面(选路停点)在位(开局终态呈现面,与既有 is_adventure 断言同批缺一即红)
|
||||
if main.ui.screens.start_overlay.visible:
|
||||
_problems.append("大门无断点确认后:开始层滞留可见(开局被开始层盖住缺陷回潮)〔营地交互批 V1〕")
|
||||
if not main.ui.modals.run.level_screen.visible:
|
||||
_problems.append("大门无断点确认后:关卡画面(选路停点)未在位〔营地交互批 V2〕")
|
||||
# 有断点三出口(选路停点形注入——同开场行③ set_breakpoint 先例)
|
||||
main.save_manager.set_breakpoint({
|
||||
"master_seed": 42, "rng_counter": 0, "hero_hp": 30, "gp": 10, "keystone": 0,
|
||||
@@ -1215,6 +1235,17 @@ func _stoptest_assert_hit() -> void:
|
||||
_problems.append("停手定型化段:停手钮真点零命中登记(驱动空转假绿)〔QA收口 V2〕")
|
||||
|
||||
|
||||
func _first_hbox(node: Node) -> HBoxContainer:
|
||||
# oracle: design/gdd/systems/表现与支撑/HUD框架.md:90 (位次真点定位——R4 判据面辅助)
|
||||
if node is HBoxContainer:
|
||||
return node
|
||||
for ch in node.get_children():
|
||||
var found := _first_hbox(ch)
|
||||
if found != null:
|
||||
return found
|
||||
return null
|
||||
|
||||
|
||||
func _report_stall(st: Dictionary) -> void:
|
||||
# oracle: design/engineering/test-conventions.md:30 (判定上报通道——验证函数组)
|
||||
var why := ""
|
||||
|
||||
@@ -200,6 +200,7 @@ func _suites() -> Array:
|
||||
{"path": "res://tests/unit/presentation/tune_sim_batch_parity_test.gd", "expect": 0}, # 测速循环批双实现对拍(帧索引/运行态/进度串/stats/报告五面——信号步进 vs await 基线)
|
||||
{"path": "res://tests/unit/presentation/standee_present_values_test.gd", "expect": 0}, # 战斗一屏样张批 V5–V12(血条危险红/名字行素底不压地台与提档 FS_HINT/徽标/护甲 PNG 绑定/素材入包/地台色合并退役)
|
||||
{"path": "res://tests/unit/presentation/reward_overlay_test.gd", "expect": 0}, # 奖励节点 UI 直验(盲区补漏)
|
||||
{"path": "res://tests/unit/presentation/confirm_dialog_test.gd", "expect": 0}, # 确认弹窗按钮位次与语义同钉(推进/次推/维持子节点序——营地交互修复批 R3)
|
||||
{"path": "res://tests/unit/presentation/level_map_info_fog_test.gd", "expect": 0}, # 信息迷雾——呈现显隐/Boss 豁免/详情零显示/大图拟合
|
||||
{"path": "res://tests/unit/presentation/forge_workbench_test.gd", "expect": 0}, # 工作间两区六路线 UI 直验(V13 自动化前置面)
|
||||
{"path": "res://tests/unit/presentation/camp_scene_layout_test.gd", "expect": 0}, # 营地场景布局数据件校验(V14——fail-fast 判据+七命中区几何红线)
|
||||
|
||||
@@ -44,6 +44,7 @@ func _split_tail() -> void:
|
||||
await _smoke_run_lifecycle()
|
||||
await _smoke_sim_guards()
|
||||
await _smoke_lifecycle_matrix()
|
||||
await _smoke_camp_hud_band()
|
||||
else:
|
||||
check(false, "V2/V3 前置:autoload 链未就绪(ConfigDB/SaveManager)")
|
||||
print("[system_test] 摘要:%d 项检查,%d 项失败" % [_checks, _failures])
|
||||
@@ -603,4 +604,49 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
for p in ["user://smoke_lifecycle.json", "user://smoke_lifecycle.json.tmp",
|
||||
"user://smoke_lifecycle_resume.json", "user://smoke_lifecycle_resume.json.tmp"]:
|
||||
if FileAccess.file_exists(p):
|
||||
DirAccess.remove_absolute(p)
|
||||
DirAccess.remove_absolute(p)
|
||||
|
||||
|
||||
func _smoke_camp_hud_band() -> void:
|
||||
# oracle: design/gdd/ux/camp.md:41 (营地顶栏栏体定值与落座——几何/色值/吃点击五钉组)
|
||||
print("--- 营地交互修复批 T3 顶栏栏体(R5:色值/铺满/不吃点击/首子件/徽章落座)---")
|
||||
var main: Node = load("res://presentation/main.tscn").instantiate()
|
||||
root.add_child(main)
|
||||
await process_frame
|
||||
await process_frame
|
||||
main._camp_pres.open_camp() # 营地屏 boot 态为隐——先开营地(装配链 main_ui_build→camp_scene_view 落座)
|
||||
for i in range(3):
|
||||
await process_frame # 排版帧(容器重排在途读数不可信)
|
||||
var band: Control = main.ui.modals.camp.scene.hud_band
|
||||
check(band != null and band.is_inside_tree(), "R5 前置:顶栏件经装配链在树(camp_scene_view.hud_band 公开句柄)")
|
||||
if band == null:
|
||||
main.queue_free()
|
||||
await process_frame
|
||||
return
|
||||
var badge_min: float = band.get_child(band.get_child_count() - 1).get_child(0).get_combined_minimum_size().y if band.get_child_count() > 0 else -1.0
|
||||
print("[system_test] 徽章 get_combined_minimum_size().y 实测 = %s(T3.0 前置读数——48=顶格落座前提)" % str(badge_min))
|
||||
check(band.get_child_count() >= 2 and band.get_child(0) is ColorRect,
|
||||
"R5④ 栏体色面是顶栏件第一个子节点(子节点序=绘制序——色面先入不盖徽章)")
|
||||
if band.get_child_count() >= 2 and band.get_child(0) is ColorRect:
|
||||
var surface: ColorRect = band.get_child(0)
|
||||
check(String(surface.color.to_html(true)) == "6e4526cc",
|
||||
"R5① 栏体色=#6E4526×α0.80(to_html 字面编码——禁浮点分量直等)〔营地交互批 V4〕")
|
||||
var band_rect: Rect2 = band.get_global_rect()
|
||||
var surf_rect: Rect2 = surface.get_global_rect()
|
||||
print("[system_test] 顶栏件实测 get_global_rect=%s、栏体=%s(R5② 承重=ui_registry FULL_RECT 注册)" % [band_rect, surf_rect])
|
||||
check(absf(surf_rect.size.x - band_rect.size.x) < 0.51 and absf(surf_rect.size.y - band_rect.size.y) < 0.51
|
||||
and absf(surf_rect.size.y - 48.0) < 0.51,
|
||||
"R5② 栏体铺满宿主且高 48(全局矩形等值)〔营地交互批 V4〕")
|
||||
check(surface.mouse_filter == Control.MOUSE_FILTER_IGNORE,
|
||||
"R5③ 栏体不吃点击(MOUSE_FILTER_IGNORE——顶排物件命中区不受阻)〔营地交互批 V4〕")
|
||||
var dock: Control = band.get_child(band.get_child_count() - 1)
|
||||
var badge: Control = dock.get_child(0) if dock.get_child_count() > 0 else null
|
||||
check(badge != null,
|
||||
"R5⑤ 前置:徽章经右对齐容器在座(dock 尾子件)")
|
||||
if badge != null:
|
||||
var brect: Rect2 = badge.get_global_rect()
|
||||
check(absf(brect.position.y - band_rect.position.y) < 0.51
|
||||
and absf(brect.end.x - (band_rect.end.x - 12.0)) < 0.51,
|
||||
"R5⑤ 徽章顶格右位(y=栏顶格、end.x=栏右缘−12——全局矩形不与局部 position 混写)〔营地交互批 V4〕")
|
||||
main.queue_free()
|
||||
await process_frame
|
||||
@@ -11,7 +11,14 @@ const _EXPECTED_KEYS: Array[StringName] = [&"gate", &"forge", &"dummy", &"chest"
|
||||
|
||||
func _initialize() -> void:
|
||||
# oracle: design/gdd/ux/camp.md:29 (营地场景布局数据件——纵深与地平线组)
|
||||
call_deferred("_test_layout_hotspot_geometry")
|
||||
call_deferred("_run_all")
|
||||
|
||||
|
||||
func _run_all() -> void:
|
||||
# oracle: design/gdd/ux/camp.md:29 (套件统一收尾——双测试函数单进程单 quit)
|
||||
await _test_layout_hotspot_geometry()
|
||||
await _test_hud_band_contrast_over_bg()
|
||||
quit(Kit.finish("camp_scene_layout_test", "PASS — 布局几何+顶栏栏体对比 全过"))
|
||||
|
||||
|
||||
func _test_layout_hotspot_geometry() -> void:
|
||||
@@ -19,7 +26,6 @@ func _test_layout_hotspot_geometry() -> void:
|
||||
var table: CampSceneLayoutTable = load("res://data/tables/camp_scene_layout.tres")
|
||||
Kit.check("V14 布局表加载且 schema 类在位〔营地图批 V14〕", table is CampSceneLayoutTable and table != null)
|
||||
if table == null:
|
||||
quit(Kit.finish("camp_scene_layout_test"))
|
||||
return
|
||||
var problems: Array[String] = table.validate()
|
||||
Kit.check("V14 校验函数通过(问题清单空,实得 %s)〔营地图批 V14〕" % [problems], problems.is_empty())
|
||||
@@ -88,4 +94,54 @@ func _test_layout_hotspot_geometry() -> void:
|
||||
var load_ok: bool = db.load_tables("res://data/tables", true)
|
||||
Kit.check("V14 ConfigDB 装载含营地布局表且校验过(is_ready=%s)〔营地图批 V14〕" % db.is_ready,
|
||||
load_ok and db.is_ready and db.presentation.camp_scene_layout != null)
|
||||
quit(Kit.finish("camp_scene_layout_test"))
|
||||
|
||||
|
||||
# 顶栏栏体规格侧对比核验(R6——与 R5 分工:R5 核实装等值,本行核规格值本身达标):
|
||||
# 按规格句在测试内写死 #6E4526 与 α0.80,与背景贴图顶带实测均色做 α 合成后算 WCAG 对比 ≥3.0。
|
||||
# 禁把视图件的 color 直接当预期值喂进算式(oracle 镜像——test-conventions §8.7 判红)。
|
||||
func _test_hud_band_contrast_over_bg() -> void:
|
||||
# oracle: design/gdd/ux/camp.md:41 (顶栏栏体定值——对落位带底色对比 ≥3:1 组)
|
||||
var table: CampSceneLayoutTable = load("res://data/tables/camp_scene_layout.tres")
|
||||
var band_h := 48
|
||||
if table != null:
|
||||
band_h = int(table.hud_band_h) # 带高取数据出口(禁字面量)
|
||||
var tex = load("res://assets/art/scene/scene_camp_bg.png")
|
||||
var img: Image = null
|
||||
if tex != null and tex.get_image() != null:
|
||||
img = tex.get_image()
|
||||
var scan_n := 0
|
||||
var r_sum := 0.0
|
||||
var g_sum := 0.0
|
||||
var b_sum := 0.0
|
||||
if img != null:
|
||||
for y in range(0, mini(band_h, img.get_height())):
|
||||
for x in range(img.get_width()): # 双层全像素扫描(非步长抽样——terrain_tile_sets_test 同款)
|
||||
var c := img.get_pixel(x, y)
|
||||
r_sum += c.r
|
||||
g_sum += c.g
|
||||
b_sum += c.b
|
||||
scan_n += 1
|
||||
Kit.check("R6 扫描面非空前置(顶带像素 %d > 0——贴图装载且带高在界)〔营地交互批 V5〕" % scan_n, scan_n > 0)
|
||||
if scan_n == 0:
|
||||
return
|
||||
var bg := Color(r_sum / float(scan_n), g_sum / float(scan_n), b_sum / float(scan_n))
|
||||
# 规格侧算式(camp.md:41 写死——#6E4526 × α0.80 对落位带背景合成)
|
||||
var fg := Color(0x6e / 255.0, 0x45 / 255.0, 0x26 / 255.0, 0.80)
|
||||
var mixed := Color(
|
||||
fg.r * fg.a + bg.r * (1.0 - fg.a),
|
||||
fg.g * fg.a + bg.g * (1.0 - fg.a),
|
||||
fg.b * fg.a + bg.b * (1.0 - fg.a))
|
||||
var lum_fg: float = _wcag_lum(mixed)
|
||||
var lum_bg: float = _wcag_lum(bg)
|
||||
var ratio: float = (maxf(lum_fg, lum_bg) + 0.05) / (minf(lum_fg, lum_bg) + 0.05)
|
||||
print("[camp_scene_layout_test] 顶带均色=%s 合成后=%s WCAG 对比=%.2f:1(规格 ≥3:1)" % [bg, mixed, ratio])
|
||||
Kit.check("R6 栏体合成色对落位带底色对比 ≥3.0(实测 %.2f)〔营地交互批 V5〕" % ratio, ratio >= 3.0)
|
||||
|
||||
|
||||
## WCAG 相对亮度(sRGB 线性化——命名函数形态,避多行 lambda 嵌套三元解析坑)
|
||||
func _wcag_lum(c: Color) -> float:
|
||||
return 0.2126 * _srgb_lin(c.r) + 0.7152 * _srgb_lin(c.g) + 0.0722 * _srgb_lin(c.b)
|
||||
|
||||
|
||||
func _srgb_lin(v: float) -> float:
|
||||
return v / 12.92 if v <= 0.03928 else pow((v + 0.055) / 1.055, 2.4)
|
||||
@@ -0,0 +1,59 @@
|
||||
extends SceneTree
|
||||
# 确认弹窗按钮位次与语义同钉单元套——
|
||||
# 守 ConfirmDialog 公开入口 open()/open_three()(四处消费方实际用的两个公开方法)的按钮行子节点序:
|
||||
# 推进钮恒 child(0)、次推进 child(1)、维持 child(2)(HUD框架.md:90 三条纪律·其三——营地交互修复批 R3)。
|
||||
# 判据面=树的公开子节点序+Button 公开 text,零私有成员直读;次钮在 open() 里只置 visible=false
|
||||
# 不从子节点表移除——双钮形态下子节点仍为 3,按下标断必取 child(2)。
|
||||
# 运行:godot --headless --path game --script res://tests/unit/presentation/confirm_dialog_test.gd(expect 0)
|
||||
const Kit := preload("res://tests/unit/test_kit.gd")
|
||||
const ConfirmDialogScript := preload("res://presentation/views/confirm_dialog.gd")
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
# oracle: design/gdd/systems/表现与支撑/HUD框架.md:90 (确认弹窗按钮位次定值——位次与语义同钉组)
|
||||
call_deferred("_run")
|
||||
|
||||
|
||||
# 按类型向下定位第一个 HBoxContainer(该弹窗树内唯一横排——modal_shell 产 CenterContainer+
|
||||
# PanelContainer+VBox 不产横排;HSeparator 与 UiKit.button 产件也不是 HBoxContainer)
|
||||
func _find_btn_row(node: Node) -> HBoxContainer:
|
||||
if node is HBoxContainer:
|
||||
return node
|
||||
for ch in node.get_children():
|
||||
var found := _find_btn_row(ch)
|
||||
if found != null:
|
||||
return found
|
||||
return null
|
||||
|
||||
|
||||
func _test_two_button_row_order() -> void:
|
||||
# oracle: design/gdd/systems/表现与支撑/HUD框架.md:90 双钮形态位次=推进在左、维持在右(两钮同钉组)
|
||||
var ov: Control = ConfirmDialogScript.new()
|
||||
root.add_child(ov)
|
||||
ov.open("t", "推进", "维持")
|
||||
var row := _find_btn_row(ov)
|
||||
Kit.check("双钮形态按钮行子节点数=3(次钮只隐藏不移除——非空前置)", row != null and row.get_child_count() == 3)
|
||||
if row != null and row.get_child_count() == 3:
|
||||
Kit.check("双钮形态位次 child(0)=推进", String((row.get_child(0) as Button).text) == "推进")
|
||||
Kit.check("双钮形态位次 child(2)=维持(次钮占 child(1) 位——按下标断必取 child(2))", String((row.get_child(2) as Button).text) == "维持")
|
||||
ov.queue_free()
|
||||
|
||||
|
||||
func _test_three_button_row_order() -> void:
|
||||
# oracle: design/gdd/systems/表现与支撑/HUD框架.md:90 三钮形态位次=推进/次推/维持(三钮同钉组)
|
||||
var ov: Control = ConfirmDialogScript.new()
|
||||
root.add_child(ov)
|
||||
ov.open_three("t", "推进", "次推", "维持")
|
||||
var row := _find_btn_row(ov)
|
||||
Kit.check("三钮形态按钮行子节点数=3(非空前置)", row != null and row.get_child_count() == 3)
|
||||
if row != null and row.get_child_count() == 3:
|
||||
Kit.check("三钮形态位次 child(0)=推进", String((row.get_child(0) as Button).text) == "推进")
|
||||
Kit.check("三钮形态位次 child(1)=次推", String((row.get_child(1) as Button).text) == "次推")
|
||||
Kit.check("三钮形态位次 child(2)=维持", String((row.get_child(2) as Button).text) == "维持")
|
||||
ov.queue_free()
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
_test_two_button_row_order()
|
||||
_test_three_button_row_order()
|
||||
quit(Kit.finish("confirm_dialog_test", "PASS — 双钮/三钮形态位次与语义同钉 全过"))
|
||||
Reference in new issue
Block a user