class_name SettingsPopup extends BasePopup ## The application settings: which MusicServer or music folder to play from, fullscreen, ## how many songs to download ahead, whether to prefer less played soundtracks and whether ## plays count in the statistics. Opened from the Settings button in the top bar. ## ## A music folder (see [MusicFolder]) is used instead of the server until Use server is ## pressed or the game is closed. The settings that need the server are off meanwhile. ## ## The quiz settings, such as the winning score, are in [QuizSettingsCard]. ## Emitted when another MusicServer or music folder is picked, or a prepared quiz's play ## order is changed. A new game starts. signal server_changed ## Space between the rows and the panel's edges. const PADDING: Vector2 = Vector2(20, 12) @onready var settings_panel: Panel = %SettingsPanel @onready var select_server_button: OptionButton = %SelectServerButton @onready var fullscreen_button: CheckButton = %FullscreenButton @onready var cache_label: Label = %CacheLabel @onready var lower_cache_button: Button = %LowerCacheButton @onready var increase_cache_button: Button = %IncreaseCacheButton @onready var low_played_button: CheckButton = %LowPlayedCheckButton @onready var add_to_database_button: CheckButton = %AddToDatabaseCheckButton @onready var rows: VBoxContainer = %VBoxContainer @onready var folder_label: Label = %FolderLabel @onready var choose_folder_button: Button = %ChooseFolderButton @onready var use_server_button: Button = %UseServerButton @onready var folder_error_label: Label = %FolderErrorLabel @onready var play_order_row: HBoxContainer = %PlayOrderRow @onready var play_order_button: OptionButton = %PlayOrderButton @onready var folder_dialog: FileDialog = %FolderDialog # Where the panel's middle is, so it stays centred when rows are shown or hidden var _panel_middle_y: float = 0.0 func _ready() -> void: for server: String in Settings.servers: select_server_button.add_item(server) fullscreen_button.button_pressed = Settings.fullscreen select_server_button.select(Settings.selected_server) cache_label.text = str(Playlist.number_of_tracks_to_preload) fullscreen_button.pressed.connect(fullscreen) choose_folder_button.pressed.connect(folder_dialog.popup_centered) folder_dialog.dir_selected.connect(use_music_folder) use_server_button.pressed.connect(use_server) play_order_button.item_selected.connect(_on_play_order_selected) lower_cache_button.pressed.connect(lower_cache) increase_cache_button.pressed.connect(increase_cache) select_server_button.item_selected.connect(select_server) low_played_button.toggled.connect( func(on: bool) -> void: Settings.use_low_played_mode = on) add_to_database_button.toggled.connect(func(on: bool) -> void: Settings.add_to_stats = on) visibility_changed.connect(_on_visibility_changed) # Alt+Enter switches fullscreen from the main window, which resizes the window get_window().size_changed.connect(_update_fullscreen_button) _panel_middle_y = settings_panel.position.y + settings_panel.size.y / 2 _show_music_source() func fullscreen() -> void: Settings.set_fullscreen(!Settings.fullscreen) ## Plays songs from the folder at [param path] instead of the server's. A folder with ## nothing to play is not used, and the popup says so. func use_music_folder(path: String) -> void: var folder: MusicFolder = MusicFolder.scan(path) if folder.kind == MusicFolder.Kind.EMPTY: folder_error_label.text = "No songs found in " + folder.display_name() folder_error_label.visible = true _fit_to_rows() return folder.set_play_order(play_order_button.selected as MusicFolder.PlayOrder) Settings.music_folder = folder _show_music_source() server_changed.emit() ## Plays from the server again instead of the music folder. func use_server() -> void: Settings.music_folder = null _show_music_source() server_changed.emit() func lower_cache() -> void: Playlist.number_of_tracks_to_preload = maxi(Playlist.number_of_tracks_to_preload - 1, 1) cache_label.text = str(Playlist.number_of_tracks_to_preload) func increase_cache() -> void: Playlist.number_of_tracks_to_preload += 1 cache_label.text = str(Playlist.number_of_tracks_to_preload) func select_server(new_server: int) -> void: GameLog.debug("select_server") _use_server(new_server) ## Picks [param new_server] in the list and uses it. func set_selected_server(new_server: int) -> void: GameLog.debug("set_selected_server") select_server_button.select(new_server) _use_server(new_server) func _use_server(new_server: int) -> void: Settings.default_path = Settings.servers[new_server] Settings.selected_server = new_server GameLog.debug("Settings.default_path: " + Settings.default_path) server_changed.emit() # Winning a game turns statistics off, so the toggles are refreshed every time this opens func _on_visibility_changed() -> void: if visible: _update_fullscreen_button() low_played_button.set_pressed_no_signal(Settings.use_low_played_mode) add_to_database_button.set_pressed_no_signal(Settings.add_to_stats) else: folder_error_label.visible = false _fit_to_rows() func _on_play_order_selected(order: int) -> void: if Settings.is_offline(): Settings.music_folder.set_play_order(order as MusicFolder.PlayOrder) server_changed.emit() # Shows where songs come from, and turns off what needs the server while offline func _show_music_source() -> void: var folder: MusicFolder = Settings.music_folder folder_error_label.visible = false use_server_button.visible = folder != null if folder == null: folder_label.text = "None, using the server" folder_label.tooltip_text = "" else: folder_label.text = folder.display_name() folder_label.tooltip_text = folder.path play_order_row.visible = folder != null && folder.kind == MusicFolder.Kind.PREPARED_QUIZ for control: BaseButton in [select_server_button, low_played_button, add_to_database_button]: control.disabled = folder != null _fit_to_rows() # Grows or shrinks the panel to fit the rows shown, keeping it centred func _fit_to_rows() -> void: var height: float = rows.get_combined_minimum_size().y + PADDING.y * 2 settings_panel.size.y = height settings_panel.position.y = floorf(_panel_middle_y - height / 2) rows.position = PADDING rows.size = Vector2(settings_panel.size.x - PADDING.x * 2, height - PADDING.y * 2) func _update_fullscreen_button() -> void: fullscreen_button.set_pressed_no_signal(Settings.fullscreen)