Make the buttons consistent and rework the player list
Build / test (push) Successful in 1m30s
Build / build (push) Successful in 1m17s

Buttons get 12 px of side padding. The top bar buttons, the quiz toolbar and
Show answer/Next are laid out in rows with 12 px gaps and are all 36 px tall,
and the ±1 buttons use a compact StepButton style. "Randomize new track" is now
"Next song".

Player rows show the name and the score apart, alternate like the other lists
and highlight the character under the mouse. The name field is a LineEdit with
a 10-letter limit; blank and duplicate names are refused, and a full list says
"Up to 7 players". Remove buttons update when editing is switched instead of
every frame, and the spacer panels are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SansanandClaude Opus 5.5 committed 2026-10-11 21:35:24 +02:00
1 parent e4352a9f34
commit 70e970b24c
39 files changed
+2054 -2177

No files matched your search

+10 -6
View File
@@ -28,9 +28,12 @@ const LOCKED_BY_SYNC: Array[String] = [
]
const TOP_BAR_CHILDREN: Array[String] = [
"TopPanelContainer", "Title", "SyncButton", "SettingsButton", "ShortcutsButton",
"DebugLabel", "UpdateLabel", "OfflineLabel",
"AboutButton", "QRButton", "QuizTab", "StatisticsTab",
"TopPanelContainer", "Title", "DebugLabel", "UpdateLabel", "OfflineLabel", "Buttons",
"QuizTab", "StatisticsTab",
]
## The buttons in the top bar's row on the right, in order.
const TOP_BAR_BUTTONS: Array[String] = [
"SyncButton", "SettingsButton", "ShortcutsButton", "AboutButton", "QRButton",
]
## Each top bar button and the popup it opens in the main window.
@@ -44,7 +47,7 @@ const TOP_BAR_POPUPS: Dictionary = {
func _top_bar_button(button_name: String) -> Button:
return _window.get_node("TopBar/" + button_name)
return _window.get_node("TopBar/%" + button_name)
func _children(node: Node) -> Array[String]:
@@ -90,6 +93,7 @@ func test_quiz_settings_button_sits_under_the_player_bar() -> void:
func test_top_bar_holds_only_title_and_buttons() -> void:
assert_array(_children(_window.get_node("TopBar"))) \
.contains_exactly_in_any_order(TOP_BAR_CHILDREN)
assert_array(_children(_window.get_node("TopBar/Buttons"))).contains_exactly(TOP_BAR_BUTTONS)
func test_quiz_and_top_bar_let_clicks_through_where_they_are_empty() -> void:
@@ -148,7 +152,7 @@ func test_points_from_the_player_list_reach_the_song_and_log() -> void:
await _play_first_song()
var crono: PlayerObject = _add_player("Crono")
(_player_row(crono).get_node("HBoxContainer/AddPoint") as BaseButton).pressed.emit()
(_player_row(crono).get_node("%AddPoint") as BaseButton).pressed.emit()
assert_array(Playlist.song_object_array[0].players_given_point).contains_exactly([crono.id])
var log_rows: Node = _window.get_node("%LogPopup").get_node("%LogVBoxContainer")
@@ -160,7 +164,7 @@ func test_character_button_in_the_player_list_picks_a_new_character() -> void:
var crono: PlayerObject = _add_player("Crono")
var character_select: BasePopup = _quiz.get_node("CharacterSelectPopup")
(_player_row(crono).get_node("HBoxContainer/Character") as BaseButton).pressed.emit()
(_player_row(crono).get_node("%Character") as BaseButton).pressed.emit()
assert_bool(character_select.visible).is_true()
var texture: ImageTexture = ImageTexture.create_from_image(