class_name MainWindow extends Control ## The main window: the top bar, the popups opened from it, and below it the quiz or the ## statistics, depending on the chosen tab. ## ## Everything that is not part of a quiz lives here. ## How far a tab slides in from the side when it is chosen. const TAB_SLIDE: float = 60.0 ## Dims the window behind an open popup and keeps clicks from reaching the buttons under it. var popup_backdrop: PopupBackdrop @onready var top_bar: TopBar = $TopBar @onready var quiz: Quiz = $Quiz @onready var search_popup: SearchPopup = $SearchPopup @onready var sync_popup: SyncPopup = %SyncPopup @onready var shortcuts_popup: ShortcutsPopup = %ShortcutsPopup @onready var qr_popup: QRPopup = %QRPopup @onready var about_popup: AboutPopup = %AboutPopup @onready var log_popup: LogPopup = %LogPopup @onready var settings_popup: SettingsPopup = %SettingsPopup @onready var statistics_view: StatisticsView = $StatisticsView @onready var soundtrack_stats_popup: SoundtrackStatsPopup = $SoundtrackStatsPopup func _ready() -> void: popup_backdrop = PopupBackdrop.add_to(self, _popups()) # Every button grows a little under the mouse and shrinks when clicked ButtonBounce.add_to_every_button(get_tree()) if OS.has_feature("macos"): GameLog.debug("is_mac") quiz.search_pressed.connect(show_search) top_bar.sync_pressed.connect(sync_soundtracks) top_bar.tab_selected.connect(show_tab) top_bar.shortcuts_pressed.connect(show_shortcuts) top_bar.about_pressed.connect(show_about) top_bar.qr_pressed.connect(show_qr) top_bar.settings_pressed.connect(settings_popup.open) settings_popup.server_changed.connect(quiz.on_server_changed) settings_popup.characters_changed.connect(quiz.character_select_popup.load_characters) settings_popup.clear_cache_requested.connect(clear_cache) settings_popup.visibility_changed.connect(_on_settings_popup_visibility_changed) sync_popup.sync_started.connect(_on_sync_started) sync_popup.sync_finished.connect(_on_sync_finished) quiz.server_changed.connect(search_popup.get_list_of_soundtracks) quiz.server_changed.connect(_on_music_source_changed) quiz.event_logged.connect(log_popup.add_log_row) statistics_view.soundtrack_selected.connect(soundtrack_stats_popup.show_soundtrack) soundtrack_stats_popup.covers = statistics_view.covers quiz.now_playing.covers = statistics_view.covers search_popup.soundtracks_loaded.connect(_remember_cover_times) # New alternative names are found by the statistics search and the Search popup soundtrack_stats_popup.alternative_names_changed.connect( statistics_view.update_alternative_names) soundtrack_stats_popup.alternative_names_changed.connect( func(_soundtrack: Soundtrack) -> void: search_popup.get_list_of_soundtracks()) soundtrack_stats_popup.cover_changed.connect(statistics_view.update_cover) # A saved quiz may have been played from a music folder top_bar.update_offline_state() search_popup.get_list_of_soundtracks() show_about_if_new_version() ## Deletes the cached character pictures and covers. The characters are loaded again at ## once, so the character select has its pictures; covers come when they are shown. func clear_cache() -> void: quiz.character_select_popup.character_cache.clear() statistics_view.covers.clear() quiz.character_select_popup.load_characters() # The quiz finds a soundtrack's cover by the cover times in the soundtrack list func _remember_cover_times(soundtracks: Array[Soundtrack]) -> void: var times: Dictionary = {} for soundtrack: Soundtrack in soundtracks: times[soundtrack.uuid] = soundtrack.cover_modified statistics_view.covers.set_cover_times(times) # After another server or a music folder was picked. Statistics need the server. func _on_music_source_changed() -> void: top_bar.update_offline_state() top_bar.check_for_update() if Settings.is_offline() && statistics_view.visible: show_tab(&"quiz") ## Opens the About popup, with what is new, the first time this version starts. func show_about_if_new_version() -> void: if Settings.last_seen_version == Settings.version: return Settings.last_seen_version = Settings.version Settings.save_settings() show_about() func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed: if event.alt_pressed && event.keycode == KEY_ENTER: GameLog.debug("Alt + Enter pressed") Settings.set_fullscreen(!Settings.fullscreen) if event.alt_pressed && event.keycode == KEY_K: shortcuts_popup.toggle() if event.alt_pressed && event.keycode == KEY_L: log_popup.toggle() func _popups() -> Array[BasePopup]: return [search_popup, sync_popup, qr_popup, shortcuts_popup, about_popup, log_popup, soundtrack_stats_popup, settings_popup] # How many songs to download ahead can be changed in the settings. Waiting until the # settings are closed avoids starting downloads while the number is clicked up and down. func _on_settings_popup_visibility_changed() -> void: if !settings_popup.visible: quiz.song_loader.fill_cache() func show_search() -> void: GameLog.debug("show_search") search_popup.toggle() func show_about() -> void: GameLog.debug("show_about") about_popup.open() func show_shortcuts() -> void: GameLog.debug("show_shortcuts") shortcuts_popup.open() func show_qr() -> void: GameLog.debug("show_qr") qr_popup.open() ## Shows the quiz for [code]&"quiz"[/code] or the statistics for [code]&"statistics"[/code]. ## A hidden quiz keeps playing its song. func show_tab(tab: StringName) -> void: GameLog.debug("show_tab ", tab) top_bar.select_tab(tab) var was_statistics: bool = statistics_view.visible statistics_view.visible = tab == &"statistics" quiz.visible = !statistics_view.visible # The tab that comes in slides from its side: statistics from the right if statistics_view.visible && !was_statistics: Anim.slide_in(statistics_view, Vector2(TAB_SLIDE, 0)) elif quiz.visible && was_statistics: Anim.slide_in(quiz, Vector2(-TAB_SLIDE, 0)) if statistics_view.visible: statistics_view.refresh() func sync_soundtracks() -> void: GameLog.debug("sync_soundtracks") sync_popup.start_sync() func _on_sync_started() -> void: GameLog.debug("_on_sync_started") top_bar.sync_button.disabled = false quiz.lock_for_sync() func _on_sync_finished() -> void: GameLog.debug("_on_sync_finished") search_popup.get_list_of_soundtracks() quiz.on_sync_finished() if statistics_view.visible: statistics_view.refresh()