feat(m63-d): migrate Settings onto the shared chrome
This commit is contained in:
@@ -7194,18 +7194,38 @@ func show_settings(category := "") -> void:
|
||||
safe.add_theme_constant_override("margin_top", 12 if short_layout else 24)
|
||||
safe.add_theme_constant_override("margin_bottom", 12 if short_layout else 24)
|
||||
add_child(safe)
|
||||
safe.add_child(_entry_chrome("SettingsFrame", "settings_frame"))
|
||||
var settings_frame := PageChrome.new().configure("card")
|
||||
settings_frame.name = "SettingsFrame"
|
||||
settings_frame.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
safe.add_child(settings_frame)
|
||||
# The full-page parchment card rolls 5.5% horizontally and 15% vertically;
|
||||
# everything must live on the face between those edges.
|
||||
var card_width := maxf(0.0, size.x - float(margin) * 2.0)
|
||||
var card_height := maxf(0.0, size.y - (12.0 if short_layout else 24.0) * 2.0)
|
||||
var card_inset_x := card_width * PageChrome.PANEL_EDGE_X + 8.0
|
||||
var card_inset_y := card_height * PageChrome.PANEL_EDGE_Y + 8.0
|
||||
var face := MarginContainer.new()
|
||||
face.name = "SettingsFace"
|
||||
face.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
face.add_theme_constant_override("margin_left", int(card_inset_x))
|
||||
face.add_theme_constant_override("margin_right", int(card_inset_x))
|
||||
face.add_theme_constant_override("margin_top", int(card_inset_y))
|
||||
face.add_theme_constant_override("margin_bottom", int(card_inset_y))
|
||||
safe.add_child(face)
|
||||
var outer := VBoxContainer.new()
|
||||
outer.name = "SettingsOuter"
|
||||
outer.add_theme_constant_override("separation", 8)
|
||||
safe.add_child(outer)
|
||||
face.add_child(outer)
|
||||
var heading := HBoxContainer.new()
|
||||
heading.name = "SettingsHeading"
|
||||
outer.add_child(heading)
|
||||
var title := _label(_tr("设置", "SETTINGS"), _scaled(24 if short_layout else 26), Color("#f5ead0"))
|
||||
var title := _label(_tr("设置", "SETTINGS"), UITokens.font_size("heading", _entry_text_scale()), PageChrome.INK)
|
||||
title.name = "SettingsTitle"
|
||||
title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
heading.add_child(title)
|
||||
heading.add_child(_label(_tr("来源:标题首页", "Caller: Title"), _scaled(12), Color("#e8d39d")))
|
||||
var caller_label := _label(_tr("来源:标题首页", "Caller: Title"), UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK_SOFT)
|
||||
caller_label.name = "SettingsCaller"
|
||||
heading.add_child(caller_label)
|
||||
var workspace := HBoxContainer.new()
|
||||
workspace.name = "SettingsWorkspace"
|
||||
workspace.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
@@ -7249,7 +7269,10 @@ func show_settings(category := "") -> void:
|
||||
workspace.add_child(scroll)
|
||||
var content := VBoxContainer.new()
|
||||
content.name = "SettingsContent"
|
||||
content.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
# A 20:1 shared plate would show metre-wide rolled ends; cap the reading
|
||||
# column so plates stay in the authored aspect range.
|
||||
content.custom_minimum_size.x = 720.0
|
||||
content.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
content.add_theme_constant_override("separation", 6)
|
||||
scroll.add_child(content)
|
||||
_build_settings_category(content)
|
||||
@@ -7257,7 +7280,7 @@ func show_settings(category := "") -> void:
|
||||
footer.name = "SettingsFooter"
|
||||
footer.add_theme_constant_override("separation", 8)
|
||||
outer.add_child(footer)
|
||||
var notice := _label(settings_notice, _scaled(12 if short_layout else 13), Color("#f0ca75"))
|
||||
var notice := _label(settings_notice, UITokens.font_size("micro", _entry_text_scale()), UITokens.COLOR_DANGER)
|
||||
notice.name = "SettingsNotice"
|
||||
notice.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
footer.add_child(notice)
|
||||
@@ -7301,17 +7324,17 @@ func _build_settings_category(content: VBoxContainer) -> void:
|
||||
content.add_child(_choice_button("SettingDynamicRange", _tr("动态范围", "Dynamic range"), String(settings_draft.dynamic_range).capitalize(), cycle_dynamic_range))
|
||||
"controls":
|
||||
content.add_child(_settings_heading(_tr("控制", "CONTROLS")))
|
||||
content.add_child(_label(_tr("触控、键鼠与控制器共享确认、取消和导航语义。", "Touch, keyboard/mouse and controller share confirm, cancel and navigation semantics."), _scaled(15), Color("#aebbc2")))
|
||||
content.add_child(_label(_tr("触控、键鼠与控制器共享确认、取消和导航语义。", "Touch, keyboard/mouse and controller share confirm, cancel and navigation semantics."), UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK_SOFT))
|
||||
content.add_child(_slider_row("SettingHoldDuration", _tr("长按确认时间", "Hold duration"), float(settings_draft.hold_duration), 0.3, 1.5, 0.1, set_hold_duration))
|
||||
content.add_child(_check_button("SettingVibration", _tr("震动", "Vibration"), bool(settings_draft.vibration), set_vibration))
|
||||
content.add_child(_unavailable_row("SettingRemapUnavailable", _tr("按键重映射:DEV-1 仅提供默认入口映射;完整冲突检查属于后续控制页面", "Remapping: DEV-1 uses the default entry map; conflict-safe remapping belongs to the later Controls page")))
|
||||
"language":
|
||||
content.add_child(_settings_heading(_tr("语言与地区格式", "LANGUAGE & LOCALE")))
|
||||
content.add_child(_choice_button("SettingLocale", _tr("界面语言", "Interface language"), _tr("简体中文", "English"), cycle_setting_locale))
|
||||
content.add_child(_label(_tr("日期 2026-08-17 · 数字 1,234.5 · 文本可换行", "Date 2026-08-17 · Number 1,234.5 · Text may wrap"), _scaled(16), Color("#f5ead0")))
|
||||
content.add_child(_label(_tr("日期 2026-08-17 · 数字 1,234.5 · 文本可换行", "Date 2026-08-17 · Number 1,234.5 · Text may wrap"), UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK))
|
||||
"credits":
|
||||
content.add_child(_settings_heading(_tr("制作人员、许可与数据", "CREDITS, LICENSES & DATA")))
|
||||
var credits := _label(_credits_text(), _scaled(14), Color("#f5ead0"))
|
||||
var credits := _label(_credits_text(), UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK)
|
||||
credits.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
credits.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
content.add_child(credits)
|
||||
@@ -7462,14 +7485,14 @@ func _next_float(options: Array, current: float) -> float:
|
||||
|
||||
|
||||
func _settings_heading(text_value: String) -> Label:
|
||||
return _label(text_value, _scaled(19), Color("#e8d39d"))
|
||||
return _label(text_value, UITokens.font_size("label", _entry_text_scale()), PageChrome.INK)
|
||||
|
||||
|
||||
func _slider_row(node_name: String, text_value: String, value: float, minimum: float, maximum: float, step: float, callback: Callable) -> HBoxContainer:
|
||||
var row := HBoxContainer.new()
|
||||
row.name = node_name
|
||||
row.custom_minimum_size.y = 42
|
||||
var label := _label("%s %.1f" % [text_value, value], _scaled(14), Color("#f5ead0"))
|
||||
var label := _label("%s %.1f" % [text_value, value], UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK)
|
||||
label.custom_minimum_size.x = 190
|
||||
row.add_child(label)
|
||||
var slider := HSlider.new()
|
||||
@@ -7480,9 +7503,10 @@ func _slider_row(node_name: String, text_value: String, value: float, minimum: f
|
||||
slider.value = value
|
||||
slider.custom_minimum_size.y = 24
|
||||
slider.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
slider.add_theme_stylebox_override("slider", _flat_style(Color("#0d151d"), Color("#866f47"), 1, 3))
|
||||
slider.add_theme_stylebox_override("grabber_area", _flat_style(Color("#73b9e7"), Color("#ead49b"), 1, 3))
|
||||
slider.add_theme_stylebox_override("grabber_area_highlight", _flat_style(Color("#a9d9f2"), Color("#f5ead0"), 1, 3))
|
||||
# No shared slider component exists yet; the track keeps token colours.
|
||||
slider.add_theme_stylebox_override("slider", _flat_style(Color("#0d151d"), Color("#a8935f"), 1, 3))
|
||||
slider.add_theme_stylebox_override("grabber_area", _flat_style(Color("#397681"), PageChrome.INK_SOFT, 1, 3))
|
||||
slider.add_theme_stylebox_override("grabber_area_highlight", _flat_style(Color("#4f9fb0"), PageChrome.INK, 1, 3))
|
||||
slider.value_changed.connect(callback)
|
||||
row.add_child(slider)
|
||||
return row
|
||||
@@ -7753,16 +7777,18 @@ func _choice_button(node_name: String, label_text: String, value_text: String, c
|
||||
button.tooltip_text = "%s: %s" % [label_text, value_text]
|
||||
button.custom_minimum_size = Vector2(0, 48)
|
||||
button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
var label := _button_label("ChoiceLabel", label_text, _scaled(15), Color("#f5ead0"))
|
||||
var label := _button_label("ChoiceLabel", label_text, UITokens.font_size("label", _entry_text_scale()), PageChrome.INK)
|
||||
label.anchor_left = PageChrome.PLATE_EDGE_X
|
||||
label.anchor_right = 0.58
|
||||
label.offset_left = 14.0
|
||||
label.offset_left = 6.0
|
||||
label.offset_right = -6.0
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
button.add_child(label)
|
||||
var value := _button_label("ValueLabel", value_text, _scaled(14), Color("#202a31"))
|
||||
var value := _button_label("ValueLabel", value_text, UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK)
|
||||
value.anchor_left = 0.58
|
||||
value.anchor_right = 1.0 - PageChrome.PLATE_EDGE_X
|
||||
value.offset_left = 6.0
|
||||
value.offset_right = -10.0
|
||||
value.offset_right = -6.0
|
||||
button.add_child(value)
|
||||
return button
|
||||
|
||||
@@ -7771,9 +7797,11 @@ func _action_button(node_name: String, text_value: String, callback: Callable) -
|
||||
var button := _entry_button_base(node_name, callback, "action_primary")
|
||||
button.tooltip_text = text_value
|
||||
button.custom_minimum_size = Vector2(UITokens.command_width("primary"), UITokens.command_height("primary"))
|
||||
var label := _button_label("ButtonLabel", text_value, _scaled(16), Color("#f5ead0"))
|
||||
label.offset_left = 46.0
|
||||
label.offset_right = -10.0
|
||||
var label := _button_label("ButtonLabel", text_value, UITokens.font_size("label", _entry_text_scale()), PageChrome.INK)
|
||||
label.anchor_left = PageChrome.PLATE_EDGE_X
|
||||
label.anchor_right = 1.0 - PageChrome.PLATE_EDGE_X
|
||||
label.offset_left = 6.0
|
||||
label.offset_right = -6.0
|
||||
button.add_child(label)
|
||||
return button
|
||||
|
||||
@@ -7782,9 +7810,11 @@ func _tool_button(node_name: String, text_value: String, callback: Callable) ->
|
||||
var button := _entry_button_base(node_name, callback, "tool")
|
||||
button.tooltip_text = text_value
|
||||
button.custom_minimum_size = Vector2(UITokens.command_width("secondary"), UITokens.command_height("secondary"))
|
||||
var label := _button_label("ButtonLabel", text_value, _scaled(14), Color("#f5ead0"))
|
||||
label.offset_left = 16.0
|
||||
label.offset_right = -10.0
|
||||
var label := _button_label("ButtonLabel", text_value, UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK)
|
||||
label.anchor_left = PageChrome.PLATE_EDGE_X
|
||||
label.anchor_right = 1.0 - PageChrome.PLATE_EDGE_X
|
||||
label.offset_left = 6.0
|
||||
label.offset_right = -6.0
|
||||
button.add_child(label)
|
||||
return button
|
||||
|
||||
@@ -7798,9 +7828,28 @@ func _check_button(node_name: String, text_value: String, enabled: bool, callbac
|
||||
check.flat = true
|
||||
for style_name in ["normal", "hover", "pressed", "disabled", "focus", "hover_pressed"]:
|
||||
check.add_theme_stylebox_override(style_name, StyleBoxEmpty.new())
|
||||
check.add_child(_entry_chrome("Chrome", "toggle"))
|
||||
var label := _button_label("ButtonLabel", text_value, _scaled(14), Color("#f5ead0"))
|
||||
label.offset_left = 14.0
|
||||
# The switch state is a shared pip so on/off reads without the old
|
||||
# bespoke toggle art.
|
||||
var chrome := PageChrome.new().configure("command_plate", {"state": "secondary"})
|
||||
chrome.name = "Chrome"
|
||||
chrome.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
check.add_child(chrome)
|
||||
var switch_pip := PageChrome.new().configure("pip", {"shape": "diamond", "filled": enabled})
|
||||
switch_pip.name = "SwitchPip"
|
||||
switch_pip.anchor_left = 1.0
|
||||
switch_pip.anchor_right = 1.0
|
||||
switch_pip.anchor_top = 0.5
|
||||
switch_pip.anchor_bottom = 0.5
|
||||
switch_pip.offset_left = -54.0
|
||||
switch_pip.offset_right = -22.0
|
||||
switch_pip.offset_top = -14.0
|
||||
switch_pip.offset_bottom = 14.0
|
||||
check.add_child(switch_pip)
|
||||
check.toggled.connect(func(on: bool) -> void: switch_pip.configure("pip", {"shape": "diamond", "filled": on}).queue_redraw())
|
||||
var label := _button_label("ButtonLabel", text_value, UITokens.font_size("micro", _entry_text_scale()), PageChrome.INK)
|
||||
label.anchor_left = PageChrome.PLATE_EDGE_X
|
||||
label.anchor_right = 1.0 - PageChrome.PLATE_EDGE_X
|
||||
label.offset_left = 6.0
|
||||
label.offset_right = -52.0
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
@@ -7815,7 +7864,13 @@ func _entry_button_base(node_name: String, callback: Callable, variant: String)
|
||||
button.flat = true
|
||||
for style_name in ["normal", "hover", "pressed", "disabled", "focus", "hover_pressed"]:
|
||||
button.add_theme_stylebox_override(style_name, StyleBoxEmpty.new())
|
||||
button.add_child(_entry_chrome("Chrome", variant))
|
||||
# M63-D: entry-family buttons use the shared hand-drawn plate; the authored
|
||||
# `Chrome` node name and variant meta stay for the focused contract.
|
||||
var plate_state := "primary" if variant == "action_primary" else "secondary"
|
||||
var chrome := PageChrome.new().configure("command_plate", {"state": plate_state})
|
||||
chrome.name = "Chrome"
|
||||
chrome.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
button.add_child(chrome)
|
||||
button.set_meta("entry_chrome_variant", variant)
|
||||
button.pressed.connect(callback, CONNECT_DEFERRED)
|
||||
return button
|
||||
@@ -7839,13 +7894,11 @@ func _set_entry_button_disabled(button: Button, disabled: bool, selected := fals
|
||||
if label == null:
|
||||
continue
|
||||
if selected:
|
||||
label.add_theme_color_override("font_color", Color("#202a31"))
|
||||
label.add_theme_color_override("font_color", PageChrome.INK)
|
||||
elif disabled:
|
||||
label.add_theme_color_override("font_color", Color("#4f565b") if child_name == "ValueLabel" else Color("#89939a"))
|
||||
elif child_name == "ValueLabel":
|
||||
label.add_theme_color_override("font_color", Color("#202a31"))
|
||||
label.add_theme_color_override("font_color", UITokens.COLOR_MUTED)
|
||||
else:
|
||||
label.add_theme_color_override("font_color", Color("#f5ead0"))
|
||||
label.add_theme_color_override("font_color", PageChrome.INK)
|
||||
|
||||
|
||||
func _set_entry_button_text(button: Button, text_value: String) -> void:
|
||||
|
||||
@@ -52,6 +52,9 @@ func _run() -> void:
|
||||
await _capture_setup(size, locale)
|
||||
await _capture_title(size, locale, "fresh")
|
||||
await _capture_title(size, locale, "recoverable")
|
||||
if size == AUTHORITY_SIZE:
|
||||
await _capture_settings(size, locale, "display")
|
||||
await _capture_settings(size, locale, "audio")
|
||||
var report_path := output_root.path_join("ink-violations-m63-entry.json")
|
||||
var file := FileAccess.open(report_path, FileAccess.WRITE)
|
||||
if file != null:
|
||||
@@ -67,7 +70,7 @@ func _run() -> void:
|
||||
return
|
||||
if title_recoverable_ok:
|
||||
print("ABG_M63_TITLE_RECOVERABLE_OK new_game=enabled continue=enabled")
|
||||
print("ABG_M63_ENTRY_VISUAL_PROBE_OK sizes=2 locales=2 pages=boot,setup,title states=running,error,fresh,recoverable views=static,dynamic,final")
|
||||
print("ABG_M63_ENTRY_VISUAL_PROBE_OK sizes=2 locales=2 pages=boot,setup,title,settings states=running,error,fresh,recoverable,display,audio views=static,dynamic,final")
|
||||
quit(0)
|
||||
|
||||
|
||||
@@ -231,6 +234,39 @@ func _capture_title(size: Vector2i, locale: String, state: String) -> void:
|
||||
await process_frame
|
||||
|
||||
|
||||
func _capture_settings(size: Vector2i, locale: String, category: String) -> void:
|
||||
var viewport := SubViewport.new()
|
||||
viewport.size = size
|
||||
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
||||
root.add_child(viewport)
|
||||
var shell := EntryShell.new()
|
||||
shell.auto_start = false
|
||||
viewport.add_child(shell)
|
||||
await _frames(3)
|
||||
shell.settings = SettingsStore.new().defaults()
|
||||
shell.settings.setup_completed = true
|
||||
shell.settings.locale = locale
|
||||
shell.size = Vector2(size)
|
||||
shell.show_settings(category)
|
||||
await _frames(4)
|
||||
_scan_ink(shell, locale, "settings-%s-%dx%d" % [category, size.x, size.y], true)
|
||||
await _save(viewport, "settings-%s-%dx%d-%s" % [category, size.x, size.y, locale], "final")
|
||||
for node_name in ["SettingsTitle", "SettingsCaller", "SettingsNotice"]:
|
||||
var control := shell.find_child(node_name, true, false) as CanvasItem
|
||||
if control != null:
|
||||
control.visible = false
|
||||
var content := shell.find_child("SettingsContent", true, false) as Control
|
||||
if content != null:
|
||||
for child in content.get_children():
|
||||
var canvas := child as CanvasItem
|
||||
if canvas != null:
|
||||
canvas.visible = false
|
||||
await _frames(2)
|
||||
await _save(viewport, "settings-%s-%dx%d-%s" % [category, size.x, size.y, locale], "static")
|
||||
viewport.queue_free()
|
||||
await process_frame
|
||||
|
||||
|
||||
func _scan_ink(view: Control, locale: String, label: String, strict := true) -> void:
|
||||
var violations := InkCheck.scan(view)
|
||||
if not strict:
|
||||
|
||||
Reference in New Issue
Block a user