Files

162 lines
6.5 KiB
GDScript

## VERTICAL SLICE - NOT FOR PRODUCTION
## 设置覆盖层:音量/全屏/减动效三件+返回;生效与持久化全经构造注入的 SettingsStore——本类零落盘。
## 减动效开关唯一入口在设置面;探针/冒烟经 retarget(store) 换注隔离存档,禁碰真实 user://settings.cfg。
class_name SettingsOverlay
extends Control
signal closed
var _store
var _volume: HSlider
var _volume_val: Label
var _fs_btn: Button # SwitchToggle 拨杆(仍 Button 子类——探针接缝保持)
var _motion_btn: Button # 同上
var _fs_st: Label # 状态字随行(开/关)
var _motion_st: Label # 状态字(完整/快速)
func _init(store) -> void:
_store = store
_build()
_sync()
visible = false
# 探针隔离换注(冒烟/探针禁碰真实 user://settings.cfg——换注后按新 store 重挂控件态)
func retarget(store: SettingsStore) -> void:
_store = store
_sync()
func _build() -> void:
# 石板面板化(demo ③)+行牌化(标签+拨杆+状态字+后果说明行);
# 设置项零增减(只有主音量);
# 减动效与结算演出动画=同一设置,一行承载。
# 两列对齐(label 列定宽 140——demo .setrow label/控制两列)+
# 后果说明内联随行(demo .why 同排)+返回钮紧凑化(demo .btn9 紧凑)。
var shell: Dictionary[Variant, Variant] = UiKit.modal_shell(self, UiKit.BG_BRIGHT, Vector2(560, 0), 8,
UiKit.panel_skinned(Vector4(20, 16, 20, 16)))
var box: VBoxContainer = shell.box
_build_head(box)
_build_volume_row(box)
_build_fullscreen_row(box)
_build_motion_row(box)
_build_close_row(box)
## 头部域(设置项零增减——只有主音量;减动效与结算演出动画=同一设置,一行承载)
func _build_head(box: VBoxContainer) -> void:
var title := UiKit.label("设置",UiKit.FS_TITLE, true, UiKit.INK_TITLE)
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
box.add_child(title)
var hint := UiKit.label("系统级设置——独立存储不随存档(一安装一份,删游戏才消失)",UiKit.FS_HINT, false, UiKit.INK_HINT)
hint.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
box.add_child(hint)
box.add_child(HSeparator.new())
## 音量行(master bus 实时生效——入口归设置、生效口径归 音频.md)
func _build_volume_row(box: VBoxContainer) -> void:
var vol_row := HBoxContainer.new()
vol_row.add_theme_constant_override("separation", 14)
box.add_child(vol_row)
var vol_lab := UiKit.label("主音量",UiKit.FS_BODY, false, UiKit.INK_LABEL)
vol_lab.custom_minimum_size = Vector2(140, 0) # label 列定宽(两列对齐)
vol_row.add_child(vol_lab)
_volume = HSlider.new()
_volume.min_value = 0.0
_volume.max_value = 100.0
_volume.value = 100.0
_volume.custom_minimum_size = Vector2(200, 24) # 几何/量程内联(皮肤走全局主题)
_volume.step = 1
_volume.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_volume.value_changed.connect(_on_volume_changed)
vol_row.add_child(_volume)
_volume_val = UiKit.label("100%",UiKit.FS_BODY, true, UiKit.INK_TITLE)
_volume_val.custom_minimum_size = Vector2(60, 0)
vol_row.add_child(_volume_val)
## 全屏行(拨杆形——SwitchToggle;状态字随行)
func _build_fullscreen_row(box: VBoxContainer) -> void:
var fs_row := HBoxContainer.new()
fs_row.add_theme_constant_override("separation", 14)
box.add_child(fs_row)
var fs_lab := UiKit.label("全屏",UiKit.FS_BODY, false, UiKit.INK_LABEL)
fs_lab.custom_minimum_size = Vector2(140, 0) # 同上
fs_row.add_child(fs_lab)
_fs_btn = UiKit._switch_toggle(false)
_fs_btn.toggled.connect(_on_fullscreen_toggled)
fs_row.add_child(_fs_btn)
_fs_st = UiKit.label("关",UiKit.FS_HINT, true, UiKit.INK_LABEL)
fs_row.add_child(_fs_st)
## 结算演出动画行(=减动效实称;拨杆 on=完整,off=快速时长减半。
## reduced_motion 单设置同驱 UiKit.motion_scale 与结算演播——demo「减动效」行与
## 本行系同一设置,不另立行(拆两行=一设置双行重复))
func _build_motion_row(box: VBoxContainer) -> void:
var motion_row := HBoxContainer.new()
motion_row.add_theme_constant_override("separation", 14)
box.add_child(motion_row)
var motion_lab := UiKit.label("结算演出动画",UiKit.FS_BODY, false, UiKit.INK_LABEL)
motion_lab.custom_minimum_size = Vector2(140, 0) # 同上
motion_row.add_child(motion_lab)
_motion_btn = UiKit._switch_toggle(true)
_motion_btn.toggled.connect(_on_motion_toggled)
motion_row.add_child(_motion_btn)
_motion_st = UiKit.label("完整",UiKit.FS_HINT, true, UiKit.INK_LABEL)
motion_row.add_child(_motion_st)
var why := UiKit.label("快速 = 时长减半(运动敏感 / 演示用)",UiKit.FS_CAPTION, false, UiKit.INK_HINT)
motion_row.add_child(why) # 内联随行(demo .why 同排)
box.add_child(HSeparator.new())
## 返回钮域(退出游戏归开始菜单——设置面不再承载〔退出只在一级菜单出现〕)
func _build_close_row(box: VBoxContainer) -> void:
var close_row := HBoxContainer.new()
close_row.alignment = BoxContainer.ALIGNMENT_CENTER
box.add_child(close_row)
var close_btn := UiKit.button("返回", 90.0) # 紧凑返回钮(demo 紧凑形)
close_btn.pressed.connect(_emit_closed)
close_row.add_child(close_btn)
func _sync() -> void:
_volume.set_value_no_signal(roundf(_store.volume_linear * 100.0))
_volume_val.text = "%d%%" % roundi(_store.volume_linear * 100.0)
_fs_btn.set_pressed_no_signal(_store.fullscreen)
_fs_st.text = "开" if _store.fullscreen else "关"
_motion_btn.set_pressed_no_signal(not _store.reduced_motion) # 拨杆 on=完整
_sync_motion_text()
# 文案随状态即时刷新(否则切换后文案恒「开」,玩家无法得知当前态)+语义命名
# (「减动效」玩家读不懂——实称「结算演出动画」速度档)+操作提示内联(所见即所得)。
func _sync_motion_text() -> void:
_motion_st.text = "快速" if _store.reduced_motion else "完整"
func _on_volume_changed(v: float) -> void:
_store.volume_linear = v / 100.0
_store.apply()
_store.save_settings()
_volume_val.text = "%d%%" % int(v)
func _on_fullscreen_toggled(on: bool) -> void:
_store.fullscreen = on
_store.apply()
_store.save_settings()
func _on_motion_toggled(on: bool) -> void:
_store.reduced_motion = not on # 拨杆语义翻转:on=完整(off=快速)
_store.apply()
_store.save_settings()
_sync_motion_text() # 切换即时刷新文案(漏刷新会让状态文字恒「开」)
func _emit_closed() -> void:
closed.emit()