extends CanvasLayer # SettingsMenu - Handles UI logic for the premium settings panel @onready var tab_container = $PanelContainer/VBoxContainer/ContentSection/TabContainer @onready var close_button = $PanelContainer/VBoxContainer/Header/CloseButton # Video Controls @onready var fullscreen_toggle = %FullscreenToggle @onready var vsync_toggle = %VSyncToggle # Audio Controls @onready var master_slider = %MasterSlider @onready var music_slider = %MusicSlider @onready var sfx_slider = %SFXSlider # Controls (Keybinds) @onready var SettingsManager = get_node_or_null("/root/SettingsManager") var listening_action: String = "" # Set when waiting for a keypress func _ready(): # Theme inheritance is broken by CanvasLayer root, no need for theme = null _load_ui_values() _connect_signals() # Initial visibility visible = false func _load_ui_values(): if not SettingsManager: print("[SettingsMenu] ERROR: SettingsManager not found") return var s = SettingsManager.settings # Video fullscreen_toggle.button_pressed = s.video.fullscreen vsync_toggle.button_pressed = s.video.vsync # Audio master_slider.value = s.audio.master_volume music_slider.value = s.audio.music_volume sfx_slider.value = s.audio.sfx_volume # Controls _update_all_key_labels() func _connect_signals(): # Video fullscreen_toggle.toggled.connect(_on_video_setting_changed) vsync_toggle.toggled.connect(_on_video_setting_changed) # Audio master_slider.value_changed.connect(_on_audio_setting_changed.bind("master_volume")) music_slider.value_changed.connect(_on_audio_setting_changed.bind("music_volume")) sfx_slider.value_changed.connect(_on_audio_setting_changed.bind("sfx_volume")) # Close close_button.pressed.connect(func(): visible = false) # Connect remapping buttons for action_name in SettingsManager.settings.controls.keys(): var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn") if btn: btn.pressed.connect(_on_remap_button_pressed.bind(action_name)) func _on_video_setting_changed(_unused = false): SettingsManager.settings.video.fullscreen = fullscreen_toggle.button_pressed SettingsManager.settings.video.vsync = vsync_toggle.button_pressed SettingsManager.save_settings() SettingsManager.apply_video_settings() func _on_audio_setting_changed(key: String, value: float): SettingsManager.settings.audio[key] = value SettingsManager.save_settings() SettingsManager.apply_audio_settings() func _on_remap_button_pressed(action_name: String): listening_action = action_name var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn") if btn: btn.text = "..." btn.modulate = Color(0.5, 1.0, 0.5) # Signal "Listening" func _input(event): if listening_action != "" and event is InputEventKey and event.pressed: # Capture the key var keycode = event.keycode SettingsManager.set_control(listening_action, keycode) # Feedback and Reset _update_key_label(listening_action) listening_action = "" # Consume event to prevent triggers get_viewport().set_input_as_handled() func _update_all_key_labels(): for action_name in SettingsManager.settings.controls.keys(): _update_key_label(action_name) func _update_key_label(action_name: String): var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn") if btn: btn.text = SettingsManager.get_control_text(action_name) btn.modulate = Color.WHITE func open(): _load_ui_values() visible = true