## 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()