Split settings into a quiz card and an application Settings popup
Build / test (push) Successful in 44s
Build / build (push) Successful in 1m13s

- A Quiz settings button under the player bar opens a small card above
  it with the quiz settings, including Auto repeat, which moves there
  from under the player bar. The card does not dim the quiz, so it can
  be changed during a song, and grows to fit its rows.
- A Settings button in the top bar opens the application settings:
  server, fullscreen and songs to download ahead. Quick sync is gone,
  as the server no longer has it, and the server list is in Settings.
- Labels use sentence case, and seconds to hide show as whole numbers.
- Debug builds switch to the local server and a low winning score in
  the Settings autoload, before any scene asks the server for anything.
  The DEBUG label moves to the top bar, so it shows on every tab.
- Search moves from the top bar back to the quiz toolbar, as the
  Statistics tab has its own search.
This commit is contained in:
Sansan committed 2026-10-07 16:05:13 +02:00
1 parent 8d21b0617d
commit b510aa47f2
34 files changed
+3074 -2525

No files matched your search

+44 -15
View File
@@ -7,6 +7,7 @@ extends MainWindowTestSuite
const MAIN_WINDOW_CHILDREN: Array[String] = [
"Background", "TopBar", "Quiz", "PopupBackdrop", "SearchPopup", "SyncPopup", "QRPopup",
"ShortcutsPopup", "StatisticsView", "AboutPopup", "LogPopup", "SoundtrackStatsPopup",
"SettingsPopup",
]
## The parts of the quiz and the scene each one comes from.
@@ -27,14 +28,15 @@ const LOCKED_BY_SYNC: Array[String] = [
]
const TOP_BAR_CHILDREN: Array[String] = [
"TopPanelContainer", "Title", "SyncButton", "SearchButton", "ShortcutsButton",
"TopPanelContainer", "Title", "SyncButton", "SettingsButton", "ShortcutsButton",
"DebugLabel",
"AboutButton", "QRButton", "QuizTab", "StatisticsTab",
]
## Each top bar button and the popup it opens in the main window.
const TOP_BAR_POPUPS: Dictionary = {
"SearchButton": "SearchPopup",
"SyncButton": "SyncPopup",
"SettingsButton": "SettingsPopup",
"ShortcutsButton": "ShortcutsPopup",
"AboutButton": "AboutPopup",
"QRButton": "QRPopup",
@@ -76,9 +78,13 @@ func test_quiz_downloads_songs_with_a_song_loader() -> void:
assert_object(_quiz.song_loader).is_instanceof(SongLoader)
func test_auto_repeat_is_part_of_the_music_player() -> void:
assert_object(_quiz.get_node("MusicPlayer/RepeatSongCheckButton")).is_instanceof(CheckButton)
assert_object(_quiz.get_node_or_null("RepeatSongCheckButton")).is_null()
func test_quiz_settings_button_sits_under_the_player_bar() -> void:
var player: Control = _quiz.get_node("MusicPlayer")
var bar: Rect2 = (player.get_node("PlayerBar") as Control).get_global_rect()
var button: Rect2 = (_quiz.get_node("QuizSettingsButton") as Control).get_global_rect()
assert_float(button.position.y).is_greater_equal(bar.end.y)
assert_float(button.position.x).is_equal(player.get_global_rect().position.x)
func test_top_bar_holds_only_title_and_buttons() -> void:
@@ -190,8 +196,8 @@ func test_loaded_song_list_shows_in_the_music_list() -> void:
func test_quiz_popup_backdrop_covers_the_top_bar() -> void:
var settings: BasePopup = _quiz.get_node("SettingsPopup")
settings.open()
var character_select: CharacterSelectPopup = _quiz.get_node("CharacterSelectPopup")
character_select.show_grid("Crono")
await _runner.simulate_frames(1)
var backdrop: Control = _quiz.get_node("PopupBackdrop")
@@ -202,15 +208,15 @@ func test_quiz_popup_backdrop_covers_the_top_bar() -> void:
func test_click_on_top_bar_while_quiz_popup_is_open_only_closes_it() -> void:
var settings: BasePopup = _quiz.get_node("SettingsPopup")
var search: BasePopup = _window.get_node("SearchPopup")
settings.open()
var character_select: CharacterSelectPopup = _quiz.get_node("CharacterSelectPopup")
var about: BasePopup = _window.get_node("AboutPopup")
character_select.show_grid("Crono")
await _runner.simulate_frames(1)
await _click_at(_center(_top_bar_button("SearchButton")))
await _click_at(_center(_top_bar_button("AboutButton")))
assert_bool(settings.visible).is_false()
assert_bool(search.visible).is_false()
assert_bool(character_select.visible).is_false()
assert_bool(about.visible).is_false()
func test_sync_disables_quiz_buttons_until_finished() -> void:
@@ -245,7 +251,7 @@ func test_changing_server_reloads_search_and_quiz() -> void:
var player: PlayerObject = _add_player("Crono")
player.add_point()
_quiz.get_node("SettingsPopup").server_changed.emit()
_window.get_node("SettingsPopup").server_changed.emit()
assert_int(_server.count("/music/all/order")).is_equal(search_loads + 1)
assert_int(_server.count("/music/all")).is_equal(inspiration_loads + 1)
@@ -274,7 +280,7 @@ func test_alt_down_lowers_the_volume() -> void:
func test_alt_enter_switches_fullscreen_and_settings_shows_it() -> void:
var settings: BasePopup = _quiz.get_node("SettingsPopup")
var settings: BasePopup = _window.get_node("SettingsPopup")
var was_fullscreen: bool = Settings.fullscreen
await _press_keys([KEY_ALT, KEY_ENTER])
@@ -284,3 +290,26 @@ func test_alt_enter_switches_fullscreen_and_settings_shows_it() -> void:
assert_bool(settings.fullscreen_button.button_pressed).is_equal(!was_fullscreen)
await _press_keys([KEY_ALT, KEY_ENTER])
assert_bool(Settings.fullscreen).is_equal(was_fullscreen)
func test_debug_label_is_in_the_top_bar_and_stays_on_the_statistics_tab() -> void:
var label: Label = _window.get_node("TopBar/DebugLabel")
assert_bool(label.visible).is_equal(Settings.is_debug)
_top_bar_button("StatisticsTab").pressed.emit()
assert_bool(label.is_visible_in_tree()).is_equal(Settings.is_debug)
func test_search_is_in_the_quiz_toolbar_and_opens_the_search_popup() -> void:
assert_object(_window.get_node_or_null("TopBar/SearchButton")).is_null()
await _click_at(_center(_quiz.get_node("QuizToolbar/SearchButton")))
assert_bool((_window.get_node("SearchPopup") as Control).visible).is_true()
func test_alt_s_opens_search() -> void:
await _press_keys([KEY_ALT, KEY_S])
assert_bool((_window.get_node("SearchPopup") as Control).visible).is_true()