Add offline mode: play from a music folder instead of the server
Settings has a Music folder row. A folder with subfolders is played as soundtracks: Next picks a random subfolder and a random song in it, the subfolder is the answer's soundtrack and the file name without its type the song. The inspiration list and Search show the subfolders. A folder with songs and no subfolders is a prepared quiz, played once in order (natural sort) or at random, showing only the song title. It has no winning score: after the last song Next becomes Show winner, and the players with the most points win, ties included. While a folder is used nothing but the characters is asked from the server: Sync, QR, Statistics, the update check and play counting are off. Characters fall back to the cached pictures when the server can't be reached. mp3, ogg and wav play; other files and broken ones are skipped. The old local playback code, the hidden Open button and the hidden Local toggle are removed. Next now waits for the song to start before preparing the next one.
This commit is contained in:
1 parent
b120440404
commit
222d231b1b
42 files changed
+8245
-474
No files matched your search
@@ -1,14 +1,21 @@
|
||||
class_name SettingsPopup
|
||||
extends BasePopup
|
||||
## The application settings: which MusicServer to use, 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.
|
||||
## 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 is picked.
|
||||
## 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
|
||||
@@ -17,7 +24,17 @@ signal server_changed
|
||||
@onready var increase_cache_button: Button = %IncreaseCacheButton
|
||||
@onready var low_played_button: CheckButton = %LowPlayedCheckButton
|
||||
@onready var add_to_database_button: CheckButton = %AddToDatabaseCheckButton
|
||||
@onready var local_button: CheckButton = %LocalButton
|
||||
@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:
|
||||
@@ -28,7 +45,10 @@ func _ready() -> void:
|
||||
cache_label.text = str(Playlist.number_of_tracks_to_preload)
|
||||
|
||||
fullscreen_button.pressed.connect(fullscreen)
|
||||
local_button.pressed.connect(local_play)
|
||||
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)
|
||||
@@ -38,14 +58,34 @@ func _ready() -> void:
|
||||
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)
|
||||
|
||||
|
||||
func local_play() -> void:
|
||||
Settings.play_local = !Settings.play_local
|
||||
## 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:
|
||||
@@ -83,6 +123,41 @@ func _on_visibility_changed() -> void:
|
||||
_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:
|
||||
|
||||
Reference in new issue
Block a user