Files
tekton/scripts/ui/settings_menu.gd
T

177 lines
5.7 KiB
GDScript

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
@onready var resolution_btn = %ResolutionBtn
@onready var msaa_btn = %MSAABtn
@onready var shadow_btn = %ShadowBtn
@onready var fps_btn = %FPSCapBtn
# Audio Controls
@onready var master_slider = %MasterSlider
@onready var music_slider = %MusicSlider
@onready var sfx_slider = %SFXSlider
# Controls (Keybinds)
@onready var use_controller_btn = %UseControllerBtn
@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()
if SettingsManager:
_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
# Populate Resolution dropdown if not already populated
if resolution_btn.item_count == 0:
for i in range(SettingsManager.RESOLUTIONS.size()):
var res = SettingsManager.RESOLUTIONS[i]
resolution_btn.add_item("%dx%d" % [res.x, res.y])
resolution_btn.selected = s.video.resolution_idx
# MSAA
if msaa_btn.item_count == 0:
msaa_btn.add_item("Disabled")
msaa_btn.add_item("2x")
msaa_btn.add_item("4x")
msaa_btn.add_item("8x")
msaa_btn.selected = s.video.msaa
# Shadows
if shadow_btn.item_count == 0:
shadow_btn.add_item("Low")
shadow_btn.add_item("Medium")
shadow_btn.add_item("High")
shadow_btn.add_item("Ultra")
shadow_btn.selected = s.video.shadow_quality
# FPS Cap
if fps_btn.item_count == 0:
fps_btn.add_item("Unlimited")
fps_btn.add_item("30 FPS")
fps_btn.add_item("60 FPS")
fps_btn.add_item("120 FPS")
fps_btn.add_item("144 FPS")
fps_btn.selected = s.video.fps_cap
# Audio
master_slider.value = s.audio.master_volume
music_slider.value = s.audio.music_volume
sfx_slider.value = s.audio.sfx_volume
# Controls
use_controller_btn.button_pressed = s.controls.get("use_controller", false)
_update_all_key_labels()
func _connect_signals():
# Video
fullscreen_toggle.toggled.connect(_on_video_setting_changed)
vsync_toggle.toggled.connect(_on_video_setting_changed)
resolution_btn.item_selected.connect(_on_resolution_selected)
msaa_btn.item_selected.connect(_on_video_property_changed.bind("msaa"))
shadow_btn.item_selected.connect(_on_video_property_changed.bind("shadow_quality"))
fps_btn.item_selected.connect(_on_video_property_changed.bind("fps_cap"))
# 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"))
# Controls
use_controller_btn.toggled.connect(_on_control_setting_changed.bind("use_controller"))
# Close
close_button.pressed.connect(func(): visible = false)
# Connect remapping buttons (exclude non-keybinds like use_controller)
for action_name in SettingsManager.settings.controls.keys():
if action_name == "use_controller":
continue
var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn")
if btn:
if btn.pressed.is_connected(_on_remap_button_pressed):
btn.pressed.disconnect(_on_remap_button_pressed)
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_resolution_selected(idx: int):
SettingsManager.settings.video.resolution_idx = idx
SettingsManager.save_settings()
SettingsManager.apply_video_settings()
func _on_video_property_changed(idx: int, property_name: String):
SettingsManager.settings.video[property_name] = idx
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_control_setting_changed(value: bool, key: String):
SettingsManager.settings.controls[key] = value
SettingsManager.save_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 and SettingsManager:
btn.text = SettingsManager.get_control_text(action_name)
btn.modulate = Color.WHITE
func open():
_load_ui_values()
visible = true