Split the main window into TopBar and Quiz scenes

The quiz (song, playlist, players, music player and the popups opened from
it) moves into Quiz.tscn and the top panel into TopBar.tscn. The main window
keeps only the top bar, the quiz and the popups opened from the top bar, so
other views can be added next to the quiz later. Every node keeps its place
on screen.

Screenshots of every UI state before and after are pixel-identical, and a
layout test checks each node against a baseline taken before the split.
This commit is contained in:
Sansan committed 2026-10-06 10:02:22 +02:00
1 parent 75c59eb223
commit 3c7b4e5c9d
27 files changed
+3432 -980

No files matched your search

+16 -16
View File
@@ -7,7 +7,7 @@ func test_startup_loads_soundtracks_and_preloads_a_song() -> void:
assert_int(_server.count("/music/all")).is_equal(1)
assert_array(_server.requested_paths).contains(["/music/rand", "/music/addQue", "/music/info"])
assert_int(Playlist.song_object_array.size()).is_equal(1)
assert_bool((_window.get_node("NextButton") as Button).disabled).is_false()
assert_bool((_quiz.get_node("NextButton") as Button).disabled).is_false()
func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
@@ -15,7 +15,7 @@ func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
_server.respond_bytes(
"/music/rand/low", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
_runner.invoke("fetch_song")
_quiz.fetch_song()
assert_int(_server.count("/music/rand/low")).is_equal(1)
@@ -33,7 +33,7 @@ func test_next_plays_preloaded_song_and_fetches_another() -> void:
func test_title_is_hidden_until_answer_is_shown() -> void:
var soundtrack_label: Label = _window.get_node("VBoxContainer/SoundtrackLabel")
var soundtrack_label: Label = _quiz.get_node("VBoxContainer/SoundtrackLabel")
_press("NextButton")
await _runner.simulate_frames(2)
@@ -81,13 +81,13 @@ func test_cannot_add_player_without_name() -> void:
func test_failed_song_download_is_retried_until_the_server_answers() -> void:
_window.song_fetch_retry_seconds = 0.05
_quiz.song_fetch_retry_seconds = 0.05
var songs_before: int = Playlist.song_object_array.size()
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
_server.respond_bytes("/music/rand", PackedByteArray(), 503)
var rand_requests_before: int = _server.count("/music/rand")
_runner.invoke("fetch_song")
_quiz.fetch_song()
await await_millis(200)
assert_int(_server.count("/music/rand") - rand_requests_before).is_greater(1)
@@ -102,13 +102,13 @@ func test_failed_song_download_is_retried_until_the_server_answers() -> void:
func test_failed_song_info_retries_only_that_step() -> void:
_window.song_fetch_retry_seconds = 0.05
_quiz.song_fetch_retry_seconds = 0.05
var songs_before: int = Playlist.song_object_array.size()
_server.respond_bytes("/music/info", PackedByteArray(), 503)
var rand_before: int = _server.count("/music/rand")
var queue_before: int = _server.count("/music/addQue")
_runner.invoke("fetch_song")
_quiz.fetch_song()
await await_millis(200)
_next_song_is(SONG_INFO[1])
await await_millis(200)
@@ -124,7 +124,7 @@ func test_failed_song_info_retries_only_that_step() -> void:
func test_preloads_as_many_songs_as_the_cache_setting() -> void:
Playlist.number_of_tracks_to_preload = 3
_runner.invoke("fetch_song")
_quiz.fetch_song()
assert_int(Playlist.get_preloaded_songs()).is_equal(3)
assert_bool(Playlist.is_song_downloading).is_false()
@@ -132,7 +132,7 @@ func test_preloads_as_many_songs_as_the_cache_setting() -> void:
func test_playing_a_song_tops_the_cache_up_again() -> void:
Playlist.number_of_tracks_to_preload = 3
_runner.invoke("fetch_song")
_quiz.fetch_song()
await _play_first_song()
@@ -141,13 +141,13 @@ func test_playing_a_song_tops_the_cache_up_again() -> void:
func test_cache_keeps_filling_after_a_failed_download() -> void:
_window.song_fetch_retry_seconds = 0.05
_quiz.song_fetch_retry_seconds = 0.05
Playlist.number_of_tracks_to_preload = 3
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
# One more download works, then the server stops answering
_server.fail_after("/music/rand", 1)
_runner.invoke("fetch_song")
_quiz.fetch_song()
await await_millis(150)
assert_int(Playlist.get_preloaded_songs()).is_equal(2)
@@ -165,11 +165,11 @@ func _open_settings() -> void:
func _close_settings() -> void:
(_window.get_node("SettingsWindow") as Control).visible = false
(_quiz.get_node("SettingsWindow") as Control).visible = false
func _press_settings_button(unique_name: String) -> void:
(_window.get_node("SettingsWindow").get_node("%" + unique_name) as Button).pressed.emit()
(_quiz.get_node("SettingsWindow").get_node("%" + unique_name) as Button).pressed.emit()
func test_raising_cache_size_does_not_download_while_settings_are_open() -> void:
@@ -224,12 +224,12 @@ func test_show_answer_before_first_song_does_not_reveal_next_song() -> void:
await _play_first_song()
assert_str((_window.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
assert_str((_quiz.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
.is_equal("????????")
func test_log_adds_one_row_per_point_with_padded_time() -> void:
var log_box: VBoxContainer = _window.get_node("%Log").get_node("%LogVBoxContainer")
var log_box: VBoxContainer = _quiz.get_node("%Log").get_node("%LogVBoxContainer")
var crono: PlayerObject = _add_player("Crono")
await _play_first_song()
@@ -243,7 +243,7 @@ func test_log_adds_one_row_per_point_with_padded_time() -> void:
func test_inspiration_list_alternates_row_backgrounds() -> void:
var rows: Array[Node] = _window.get_node("ScrollContainer/VBoxContainer").get_children()
var rows: Array[Node] = _quiz.get_node("ScrollContainer/VBoxContainer").get_children()
assert_int(rows.size()).is_equal(2)
assert_str((rows[0] as ListRow).text).is_equal("Chrono Trigger")