Add a Nord theme and give the player bar room around it (#43)
Build / test (push) Successful in 1m31s
Build / build (push) Successful in 1m14s

Nord (themes/nord_theme.tres) uses the app icon's blues, darkened, with Nord's
Snow Storm text, Frost and Aurora accents and the playing song in Aurora
yellow. Its shapes are round: pill buttons and tabs, 14-16 px corners, soft
shadows on popups, cards and the player bar, rounded scroll bars, sliders and
text fields, and seven Aurora/Frost colours for the score graph. Classic stays
the default.

The player bar now has 16 px to the song buttons, the player list, Quiz
settings and the window's bottom edge, and the right edges line up at 1856.

The volume icon is a flat button with a PlayerIcon style, so each theme colours
it; it was nearly invisible on Original web's light grey bar.

Closes #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SansanandClaude Opus 5.5 committed 2026-10-12 21:06:39 +02:00
1 parent 94e8dfb602
commit de94691073
10 files changed
+2424 -847

No files matched your search

+1
View File
@@ -36,6 +36,7 @@ const SAVED_SETTINGS: Dictionary[String, Array] = {
const THEMES: Array[Dictionary] = [ const THEMES: Array[Dictionary] = [
{"id": "classic", "name": "Classic", "path": "res://themes/main_theme.tres"}, {"id": "classic", "name": "Classic", "path": "res://themes/main_theme.tres"},
{"id": "original_web", "name": "Original web", "path": "res://themes/original_web_theme.tres"}, {"id": "original_web", "name": "Original web", "path": "res://themes/original_web_theme.tres"},
{"id": "nord", "name": "Nord", "path": "res://themes/nord_theme.tres"},
] ]
## When this environment variable is set, the settings files are kept in that folder ## When this environment variable is set, the settings files are kept in that folder
## instead of the user's config folder. The tests set it so they never touch the real files. ## instead of the user's config folder. The tests set it so they never touch the real files.
+6 -4
View File
@@ -109,14 +109,16 @@ theme_type_variation = &"PlayerTime"
text = "00:00 / 00:00" text = "00:00 / 00:00"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="VolumeIcon" type="TextureRect" parent="PlayerBar/MusicPlayerContainer"] [node name="VolumeIcon" type="Button" parent="PlayerBar/MusicPlayerContainer"]
custom_minimum_size = Vector2(22, 22) custom_minimum_size = Vector2(22, 22)
layout_mode = 2 layout_mode = 2
size_flags_vertical = 4 size_flags_vertical = 4
mouse_filter = 2 mouse_filter = 2
texture = ExtResource("6_volume") focus_mode = 0
expand_mode = 1 theme_type_variation = &"PlayerIcon"
stretch_mode = 5 icon = ExtResource("6_volume")
icon_alignment = 1
expand_icon = true
[node name="VolumeSlider" parent="PlayerBar/MusicPlayerContainer" instance=ExtResource("5_iifuj")] [node name="VolumeSlider" parent="PlayerBar/MusicPlayerContainer" instance=ExtResource("5_iifuj")]
unique_name_in_owner = true unique_name_in_owner = true
+13 -13
View File
@@ -29,13 +29,13 @@ layout_mode = 0
offset_left = 64.0 offset_left = 64.0
offset_top = 384.0 offset_top = 384.0
offset_right = 1152.0 offset_right = 1152.0
offset_bottom = 896.0 offset_bottom = 894.0
[node name="InspirationList" parent="." unique_id=498283761 instance=ExtResource("scene_InspirationList")] [node name="InspirationList" parent="." unique_id=498283761 instance=ExtResource("scene_InspirationList")]
layout_mode = 0 layout_mode = 0
offset_left = 1216.0 offset_left = 1216.0
offset_top = 128.0 offset_top = 128.0
offset_right = 1857.0 offset_right = 1856.0
offset_bottom = 512.0 offset_bottom = 512.0
[node name="NowPlaying" parent="." unique_id=42468498 instance=ExtResource("scene_NowPlaying")] [node name="NowPlaying" parent="." unique_id=42468498 instance=ExtResource("scene_NowPlaying")]
@@ -48,16 +48,16 @@ offset_bottom = 384.0
[node name="MusicPlayer" parent="." unique_id=1990459832 instance=ExtResource("5_emn36")] [node name="MusicPlayer" parent="." unique_id=1990459832 instance=ExtResource("5_emn36")]
layout_mode = 0 layout_mode = 0
offset_left = 64.0 offset_left = 64.0
offset_top = 984.0 offset_top = 970.0
offset_right = 1856.0 offset_right = 1856.0
offset_bottom = 1026.0 offset_bottom = 1012.0
[node name="PlayersPanel" parent="." unique_id=1708375945 instance=ExtResource("scene_PlayersPanel")] [node name="PlayersPanel" parent="." unique_id=1708375945 instance=ExtResource("scene_PlayersPanel")]
layout_mode = 0 layout_mode = 0
offset_left = 1216.0 offset_left = 1216.0
offset_top = 576.0 offset_top = 544.0
offset_right = 1857.0 offset_right = 1856.0
offset_bottom = 977.0 offset_bottom = 954.0
[node name="QuizToolbar" parent="." unique_id=1873301941 instance=ExtResource("scene_QuizToolbar")] [node name="QuizToolbar" parent="." unique_id=1873301941 instance=ExtResource("scene_QuizToolbar")]
layout_mode = 0 layout_mode = 0
@@ -69,9 +69,9 @@ offset_bottom = 100.0
[node name="SongControls" parent="." unique_id=1640212773 instance=ExtResource("scene_SongControls")] [node name="SongControls" parent="." unique_id=1640212773 instance=ExtResource("scene_SongControls")]
layout_mode = 0 layout_mode = 0
offset_left = 64.0 offset_left = 64.0
offset_top = 940.0 offset_top = 918.0
offset_right = 704.0 offset_right = 704.0
offset_bottom = 976.0 offset_bottom = 954.0
[node name="CharacterSelectPopup" parent="." unique_id=1679856322 instance=ExtResource("6_dhrvg")] [node name="CharacterSelectPopup" parent="." unique_id=1679856322 instance=ExtResource("6_dhrvg")]
unique_name_in_owner = true unique_name_in_owner = true
@@ -94,9 +94,9 @@ offset_bottom = 80.0
[node name="QuizSettingsButton" type="Button" parent="." unique_id=1323246979] [node name="QuizSettingsButton" type="Button" parent="." unique_id=1323246979]
layout_mode = 0 layout_mode = 0
offset_left = 64.0 offset_left = 64.0
offset_top = 1030.0 offset_top = 1028.0
offset_right = 224.0 offset_right = 224.0
offset_bottom = 1066.0 offset_bottom = 1064.0
focus_mode = 0 focus_mode = 0
action_mode = 0 action_mode = 0
text = "Quiz settings" text = "Quiz settings"
@@ -107,9 +107,9 @@ expand_icon = true
visible = false visible = false
layout_mode = 0 layout_mode = 0
offset_left = 64.0 offset_left = 64.0
offset_top = 984.0 offset_top = 962.0
offset_right = 64.0 offset_right = 64.0
offset_bottom = 984.0 offset_bottom = 962.0
[node name="SongLoader" type="Node" parent="." unique_id=1520867349] [node name="SongLoader" type="Node" parent="." unique_id=1520867349]
script = ExtResource("song_loader_script") script = ExtResource("song_loader_script")
File diff suppressed because it is too large. Load diff
+1
View File
@@ -46,6 +46,7 @@ const STYLES: Dictionary = {
"PlayerButton": "Button", "PlayerButton": "Button",
"PlayerButtonPrimary": "Button", "PlayerButtonPrimary": "Button",
"PlayerTime": "Label", "PlayerTime": "Label",
"PlayerIcon": "Button",
"ProgressSlider": "HSlider", "ProgressSlider": "HSlider",
"VolumeBar": "HSlider", "VolumeBar": "HSlider",
"StatisticsCard": "PanelContainer", "StatisticsCard": "PanelContainer",
+1 -1
View File
@@ -27,7 +27,7 @@ func test_picker_lists_every_theme_and_shows_the_one_in_use() -> void:
for index: int in _settings.theme_button.item_count: for index: int in _settings.theme_button.item_count:
names.append(_settings.theme_button.get_item_text(index)) names.append(_settings.theme_button.get_item_text(index))
assert_array(names).contains_exactly(["Classic", "Original web"]) assert_array(names).contains_exactly(["Classic", "Original web", "Nord"])
assert_str(_settings.theme_button.get_item_text(_settings.theme_button.selected)) \ assert_str(_settings.theme_button.get_item_text(_settings.theme_button.selected)) \
.is_equal("Classic") .is_equal("Classic")
+2
View File
@@ -8,6 +8,7 @@ font sizes or style boxes themselves; they name one of the theme's styles instea
|---|---|---| |---|---|---|
| Classic | `main_theme.tres` | The default. Also the project theme (Project Settings → GUI → Theme → Custom), which the editor shows | | Classic | `main_theme.tres` | The default. Also the project theme (Project Settings → GUI → Theme → Custom), which the editor shows |
| Original web | `original_web_theme.tres` | Looks like MusicFrontend, the web version: orange-bordered buttons, `#333` header and popups, `#424242` panels, `#4e4e4e` alternating rows, a yellow playing song and a light grey player bar | | Original web | `original_web_theme.tres` | Looks like MusicFrontend, the web version: orange-bordered buttons, `#333` header and popups, `#424242` panels, `#4e4e4e` alternating rows, a yellow playing song and a light grey player bar |
| Nord | `nord_theme.tres` | Dark blues from the app icon (`#1e4a69` window, `#1a3e5a` panels, `#29577f` buttons) with Nord's Snow Storm text, Frost and Aurora accents: Aurora yellow `#EBCB8B` for the playing song and highlights. Round shapes: pill buttons and tabs, 14–16 px corners, soft shadows on popups, cards and the player bar, and rounded text fields |
## Picking a theme ## Picking a theme
@@ -77,6 +78,7 @@ inspector or `theme_type_variation` in code:
| `PlayerButtonPrimary`, `PlayerButton` | Button | The round play button, and the restart button; the icon's colour on hover comes from here | | `PlayerButtonPrimary`, `PlayerButton` | Button | The round play button, and the restart button; the icon's colour on hover comes from here |
| `ProgressSlider`, `VolumeBar` | HSlider | How far the song has played (orange), and the volume | | `ProgressSlider`, `VolumeBar` | HSlider | How far the song has played (orange), and the volume |
| `PlayerTime` | Label | The time played and the song's length | | `PlayerTime` | Label | The time played and the song's length |
| `PlayerIcon` | Button | The volume icon in the music player: a flat button that only shows its icon, in the theme's colour |
| `SongStatsHeader` | PanelContainer | The column titles above the statistics song list, spaced like its rows | | `SongStatsHeader` | PanelContainer | The column titles above the statistics song list, spaced like its rows |
| `SongStatsText`, `SongStatsSecondary` | RichTextLabel | A song's name and its soundtrack (dimmer) in the statistics song list | | `SongStatsText`, `SongStatsSecondary` | RichTextLabel | A song's name and its soundtrack (dimmer) in the statistics song list |
+10
View File
@@ -1046,6 +1046,8 @@ corner_radius_bottom_right = 3
corner_radius_bottom_left = 3 corner_radius_bottom_left = 3
corner_detail = 5 corner_detail = 5
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_playericon"]
[resource] [resource]
default_font = ExtResource("1_default_font") default_font = ExtResource("1_default_font")
Button/colors/font_color = Color(0.875, 0.875, 0.875, 1) Button/colors/font_color = Color(0.875, 0.875, 0.875, 1)
@@ -1195,6 +1197,14 @@ PlayerCharacter/base_type = &"PanelContainer"
PlayerCharacter/styles/panel = SubResource("StyleBoxEmpty_playerchar") PlayerCharacter/styles/panel = SubResource("StyleBoxEmpty_playerchar")
PlayerCharacterHover/base_type = &"PanelContainer" PlayerCharacterHover/base_type = &"PanelContainer"
PlayerCharacterHover/styles/panel = SubResource("StyleBoxFlat_playercharhover") PlayerCharacterHover/styles/panel = SubResource("StyleBoxFlat_playercharhover")
PlayerIcon/base_type = &"Button"
PlayerIcon/colors/icon_normal_color = Color(1, 1, 1, 1)
PlayerIcon/colors/icon_disabled_color = Color(1, 1, 1, 1)
PlayerIcon/styles/normal = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/disabled = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/hover = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/pressed = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/focus = SubResource("StyleBoxEmpty_playericon")
PlayerList/base_type = &"PanelContainer" PlayerList/base_type = &"PanelContainer"
PlayerList/styles/panel = SubResource("StyleBoxFlat_playerlist") PlayerList/styles/panel = SubResource("StyleBoxFlat_playerlist")
PlayerScore/base_type = &"Label" PlayerScore/base_type = &"Label"
File diff suppressed because it is too large. Load diff
+10
View File
@@ -1147,6 +1147,8 @@ corner_detail = 5
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_topbar"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_topbar"]
bg_color = Color(0.2, 0.2, 0.2, 1) bg_color = Color(0.2, 0.2, 0.2, 1)
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_playericon"]
[resource] [resource]
default_font = ExtResource("1_default_font") default_font = ExtResource("1_default_font")
Button/colors/font_color = Color(1, 0.612, 0, 1) Button/colors/font_color = Color(1, 0.612, 0, 1)
@@ -1296,6 +1298,14 @@ PlayerCharacter/base_type = &"PanelContainer"
PlayerCharacter/styles/panel = SubResource("StyleBoxEmpty_playerchar") PlayerCharacter/styles/panel = SubResource("StyleBoxEmpty_playerchar")
PlayerCharacterHover/base_type = &"PanelContainer" PlayerCharacterHover/base_type = &"PanelContainer"
PlayerCharacterHover/styles/panel = SubResource("StyleBoxFlat_playercharhover") PlayerCharacterHover/styles/panel = SubResource("StyleBoxFlat_playercharhover")
PlayerIcon/base_type = &"Button"
PlayerIcon/colors/icon_normal_color = Color(0.1, 0.1, 0.1, 1)
PlayerIcon/colors/icon_disabled_color = Color(0.1, 0.1, 0.1, 1)
PlayerIcon/styles/normal = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/disabled = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/hover = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/pressed = SubResource("StyleBoxEmpty_playericon")
PlayerIcon/styles/focus = SubResource("StyleBoxEmpty_playericon")
PlayerList/base_type = &"PanelContainer" PlayerList/base_type = &"PanelContainer"
PlayerList/styles/panel = SubResource("StyleBoxFlat_playerlist") PlayerList/styles/panel = SubResource("StyleBoxFlat_playerlist")
PlayerScore/base_type = &"Label" PlayerScore/base_type = &"Label"