221 lines
8.0 KiB
GDScript
221 lines
8.0 KiB
GDScript
extends Control
|
|
|
|
signal back_to_main_menu
|
|
|
|
@onready var master_slider = $SettingsContainer/MasterVolumeContainer/MasterVolumeSlider
|
|
@onready var music_slider = $SettingsContainer/MusicVolumeContainer/MusicVolumeSlider
|
|
@onready var sfx_slider = $SettingsContainer/SFXVolumeContainer/SFXVolumeSlider
|
|
@onready var language_stepper = $SettingsContainer/LanguageContainer/LanguageStepper
|
|
|
|
@export var settings_manager: Node = SettingsManager
|
|
@export var localization_manager: Node = LocalizationManager
|
|
|
|
|
|
# Navigation system variables
|
|
var navigable_controls: Array[Control] = []
|
|
var current_control_index: int = 0
|
|
var original_control_scales: Array[Vector2] = []
|
|
var original_control_modulates: Array[Color] = []
|
|
|
|
func _ready():
|
|
add_to_group("localizable")
|
|
DebugManager.log_info("SettingsMenu ready", "Settings")
|
|
# Language selector is initialized automatically
|
|
|
|
var master_callback = _on_volume_slider_changed.bind("master_volume")
|
|
if not master_slider.value_changed.is_connected(master_callback):
|
|
master_slider.value_changed.connect(master_callback)
|
|
|
|
var music_callback = _on_volume_slider_changed.bind("music_volume")
|
|
if not music_slider.value_changed.is_connected(music_callback):
|
|
music_slider.value_changed.connect(music_callback)
|
|
|
|
var sfx_callback = _on_volume_slider_changed.bind("sfx_volume")
|
|
if not sfx_slider.value_changed.is_connected(sfx_callback):
|
|
sfx_slider.value_changed.connect(sfx_callback)
|
|
|
|
# Language stepper connections are handled in the .tscn file
|
|
|
|
_update_controls_from_settings()
|
|
update_text()
|
|
_setup_navigation_system()
|
|
|
|
func _update_controls_from_settings():
|
|
master_slider.value = settings_manager.get_setting("master_volume")
|
|
music_slider.value = settings_manager.get_setting("music_volume")
|
|
sfx_slider.value = settings_manager.get_setting("sfx_volume")
|
|
|
|
# Language display is handled by the ValueStepper component
|
|
|
|
func _on_volume_slider_changed(value, setting_key):
|
|
# Input validation for volume settings
|
|
if not setting_key in ["master_volume", "music_volume", "sfx_volume"]:
|
|
DebugManager.log_error("Invalid volume setting key: " + str(setting_key), "Settings")
|
|
return
|
|
|
|
if not (value is float or value is int):
|
|
DebugManager.log_error("Invalid volume value type: " + str(typeof(value)), "Settings")
|
|
return
|
|
|
|
# Clamp value to valid range
|
|
var clamped_value = clamp(float(value), 0.0, 1.0)
|
|
if clamped_value != value:
|
|
DebugManager.log_warn("Volume value %f clamped to %f" % [value, clamped_value], "Settings")
|
|
|
|
if not settings_manager.set_setting(setting_key, clamped_value):
|
|
DebugManager.log_error("Failed to set volume setting: " + setting_key, "Settings")
|
|
|
|
func _exit_settings():
|
|
DebugManager.log_info("Exiting settings", "Settings")
|
|
settings_manager.save_settings()
|
|
back_to_main_menu.emit()
|
|
|
|
func _input(event):
|
|
if event.is_action_pressed("action_east") or event.is_action_pressed("pause_menu"):
|
|
DebugManager.log_debug("Cancel/back action pressed in settings", "Settings")
|
|
_exit_settings()
|
|
get_viewport().set_input_as_handled()
|
|
return
|
|
|
|
# Vertical navigation between controls
|
|
if event.is_action_pressed("move_up"):
|
|
_navigate_controls(-1)
|
|
get_viewport().set_input_as_handled()
|
|
elif event.is_action_pressed("move_down"):
|
|
_navigate_controls(1)
|
|
get_viewport().set_input_as_handled()
|
|
|
|
# Horizontal navigation for current control
|
|
elif event.is_action_pressed("move_left"):
|
|
_adjust_current_control(-1)
|
|
get_viewport().set_input_as_handled()
|
|
elif event.is_action_pressed("move_right"):
|
|
_adjust_current_control(1)
|
|
get_viewport().set_input_as_handled()
|
|
|
|
# Activate current control
|
|
elif event.is_action_pressed("action_south"):
|
|
_activate_current_control()
|
|
get_viewport().set_input_as_handled()
|
|
|
|
func _on_back_button_pressed():
|
|
AudioManager.play_ui_click()
|
|
DebugManager.log_info("Back button pressed", "Settings")
|
|
_exit_settings()
|
|
|
|
|
|
|
|
func update_text():
|
|
$SettingsContainer/SettingsTitle.text = tr("settings_title")
|
|
$SettingsContainer/MasterVolumeContainer/MasterVolume.text = tr("master_volume")
|
|
$SettingsContainer/MusicVolumeContainer/MusicVolume.text = tr("music_volume")
|
|
$SettingsContainer/SFXVolumeContainer/SFXVolume.text = tr("sfx_volume")
|
|
$SettingsContainer/LanguageContainer/LanguageLabel.text = tr("language")
|
|
$BackButtonContainer/BackButton.text = tr("back")
|
|
|
|
|
|
func _on_reset_setting_button_pressed() -> void:
|
|
AudioManager.play_ui_click()
|
|
DebugManager.log_info("Resetting settings", "Settings")
|
|
settings_manager.reset_settings_to_defaults()
|
|
_update_controls_from_settings()
|
|
localization_manager.change_language(settings_manager.get_setting("language"))
|
|
|
|
func _setup_navigation_system():
|
|
navigable_controls.clear()
|
|
original_control_scales.clear()
|
|
original_control_modulates.clear()
|
|
|
|
# Add controls in navigation order
|
|
navigable_controls.append(master_slider)
|
|
navigable_controls.append(music_slider)
|
|
navigable_controls.append(sfx_slider)
|
|
navigable_controls.append(language_stepper) # Use the ValueStepper component
|
|
navigable_controls.append($BackButtonContainer/BackButton)
|
|
navigable_controls.append($ResetSettingsContainer/ResetSettingButton)
|
|
|
|
# Store original visual properties
|
|
for control in navigable_controls:
|
|
original_control_scales.append(control.scale)
|
|
original_control_modulates.append(control.modulate)
|
|
|
|
_update_visual_selection()
|
|
|
|
func _navigate_controls(direction: int):
|
|
AudioManager.play_ui_click()
|
|
current_control_index = (current_control_index + direction) % navigable_controls.size()
|
|
if current_control_index < 0:
|
|
current_control_index = navigable_controls.size() - 1
|
|
_update_visual_selection()
|
|
DebugManager.log_info("Settings navigation: index " + str(current_control_index), "Settings")
|
|
|
|
func _adjust_current_control(direction: int):
|
|
if current_control_index < 0 or current_control_index >= navigable_controls.size():
|
|
return
|
|
|
|
var control = navigable_controls[current_control_index]
|
|
|
|
# Handle sliders
|
|
if control is HSlider:
|
|
var slider = control as HSlider
|
|
var step = slider.step if slider.step > 0 else 0.1
|
|
var new_value = slider.value + (direction * step)
|
|
new_value = clamp(new_value, slider.min_value, slider.max_value)
|
|
slider.value = new_value
|
|
AudioManager.play_ui_click()
|
|
DebugManager.log_info("Slider adjusted: %s = %f" % [_get_control_name(control), new_value], "Settings")
|
|
|
|
# Handle language stepper with left/right
|
|
elif control == language_stepper:
|
|
if language_stepper.handle_input_action("move_left" if direction == -1 else "move_right"):
|
|
AudioManager.play_ui_click()
|
|
|
|
func _activate_current_control():
|
|
if current_control_index < 0 or current_control_index >= navigable_controls.size():
|
|
return
|
|
|
|
var control = navigable_controls[current_control_index]
|
|
|
|
# Handle buttons
|
|
if control is Button:
|
|
AudioManager.play_ui_click()
|
|
DebugManager.log_info("Activating button via keyboard/gamepad: " + control.text, "Settings")
|
|
control.pressed.emit()
|
|
|
|
# Handle language stepper (no action needed on activation, left/right handles it)
|
|
elif control == language_stepper:
|
|
DebugManager.log_info("Language stepper selected - use left/right to change", "Settings")
|
|
|
|
func _update_visual_selection():
|
|
for i in range(navigable_controls.size()):
|
|
var control = navigable_controls[i]
|
|
if i == current_control_index:
|
|
# Use the ValueStepper's built-in highlighting
|
|
if control == language_stepper:
|
|
language_stepper.set_highlighted(true)
|
|
else:
|
|
control.scale = original_control_scales[i] * 1.05
|
|
control.modulate = Color(1.1, 1.1, 0.9)
|
|
else:
|
|
# Reset highlighting
|
|
if control == language_stepper:
|
|
language_stepper.set_highlighted(false)
|
|
else:
|
|
control.scale = original_control_scales[i]
|
|
control.modulate = original_control_modulates[i]
|
|
|
|
func _get_control_name(control: Control) -> String:
|
|
if control == master_slider:
|
|
return "master_volume"
|
|
elif control == music_slider:
|
|
return "music_volume"
|
|
elif control == sfx_slider:
|
|
return "sfx_volume"
|
|
elif control == language_stepper:
|
|
return language_stepper.get_control_name()
|
|
else:
|
|
return "button"
|
|
|
|
func _on_language_stepper_value_changed(new_value: String, new_index: int):
|
|
DebugManager.log_info("Language changed via ValueStepper: " + new_value + " (index: " + str(new_index) + ")", "Settings")
|