Compare commits
10
Commits
05655cf81c
...
74fc28614f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74fc28614f | ||
|
|
9a5806c56f | ||
|
|
196a7abc35 | ||
|
|
212eda96e2 | ||
|
|
65b73e3570 | ||
|
|
7beaa7ee5c | ||
|
|
f8bc4c4b71 | ||
|
|
59fcb3cbe3 | ||
|
|
056ead47be | ||
|
|
d856e03c32 |
No files matched your search
@@ -83,6 +83,11 @@ jobs:
|
||||
godot --headless --path . --import
|
||||
godot --headless --path . --export-release "Windows Desktop" "build/${PROJECT_NAME}_${GAME_VERSION}.exe"
|
||||
godot --headless --path . --export-release "Linux" "build/${PROJECT_NAME}_${GAME_VERSION}.x86_64"
|
||||
|
||||
# Linux binaries can't hold an icon; the package adds it with a menu entry and installer
|
||||
- name: Package Linux
|
||||
run: |
|
||||
linux/package.sh "build/${PROJECT_NAME}_${GAME_VERSION}.x86_64" "$GAME_VERSION" build
|
||||
ls -la build
|
||||
|
||||
- name: Upload Artifacts
|
||||
|
||||
+3
-15
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var about_panel: Panel = %AboutPanel
|
||||
@@ -51,16 +51,8 @@ const WHATS_NEW: Dictionary = {
|
||||
}
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if self.visible == true:
|
||||
if event is InputEventMouseButton && event.is_pressed():
|
||||
var evLocal: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), about_panel.size).has_point(evLocal.position):
|
||||
self.visible = false
|
||||
|
||||
|
||||
func show_window() -> void:
|
||||
visible = true
|
||||
func open() -> void:
|
||||
super()
|
||||
version_label.text = Settings.version
|
||||
|
||||
# Build changelog text with version headers
|
||||
@@ -70,7 +62,3 @@ func show_window() -> void:
|
||||
changelog_text += WHATS_NEW[version] + "\n"
|
||||
|
||||
whats_new_label.text = changelog_text
|
||||
|
||||
|
||||
func hide_window() -> void:
|
||||
visible = false
|
||||
+7
-9
@@ -1,8 +1,10 @@
|
||||
[gd_scene format=3 uid="uid://cp54idaudb8dp"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b7bh0of7olbcb" path="res://AboutWindow.gd" id="1_about_script"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="AboutControl" type="Control" unique_id=1626010355]
|
||||
[node name="AboutControl" type="Control" unique_id=1626010355 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -10,6 +12,7 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_about_script")
|
||||
panel = NodePath("AboutPanel")
|
||||
|
||||
[node name="AboutPanel" type="Panel" parent="." unique_id=1907299275]
|
||||
unique_name_in_owner = true
|
||||
@@ -18,7 +21,6 @@ offset_right = 600.0
|
||||
offset_bottom = 640.0
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="AboutPanel" unique_id=200295721]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_right = 600.0
|
||||
offset_bottom = 50.0
|
||||
@@ -28,10 +30,11 @@ vertical_alignment = 1
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="AboutPanel" unique_id=417677913]
|
||||
layout_mode = 0
|
||||
offset_left = 10.0
|
||||
offset_left = 20.0
|
||||
offset_top = 50.0
|
||||
offset_right = 590.0
|
||||
offset_right = 580.0
|
||||
offset_bottom = 630.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="ContentVBox" type="VBoxContainer" parent="AboutPanel/ScrollContainer" unique_id=1746337912]
|
||||
layout_mode = 2
|
||||
@@ -40,14 +43,11 @@ size_flags_vertical = 3
|
||||
|
||||
[node name="VersionLabel" type="Label" parent="AboutPanel/ScrollContainer/ContentVBox" unique_id=352884126]
|
||||
unique_name_in_owner = true
|
||||
texture_filter = 1
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="DescriptionLabel" type="Label" parent="AboutPanel/ScrollContainer/ContentVBox" unique_id=543094263]
|
||||
texture_filter = 1
|
||||
custom_minimum_size = Vector2(560, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Try your video game music knowledge with this VGM randomizer, invite your friends and see who is the best."
|
||||
@@ -56,8 +56,6 @@ autowrap_mode = 2
|
||||
|
||||
[node name="WhatsNewLabel" type="Label" parent="AboutPanel/ScrollContainer/ContentVBox" unique_id=1363040291]
|
||||
unique_name_in_owner = true
|
||||
texture_filter = 1
|
||||
custom_minimum_size = Vector2(560, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
autowrap_mode = 2
|
||||
@@ -1,40 +0,0 @@
|
||||
extends Control
|
||||
|
||||
@onready
|
||||
var character_grid_container := $ScrollContainer2
|
||||
|
||||
@onready
|
||||
var character_grid := $ScrollContainer2/GridContainer
|
||||
|
||||
signal character_selected(file_name)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
var characters := DirAccess.open("res://characters/")
|
||||
if characters:
|
||||
characters.list_dir_begin()
|
||||
var file_name = characters.get_next()
|
||||
while file_name != "":
|
||||
file_name = file_name.replace('.import', '') # <--- remove the .import
|
||||
if file_name.ends_with(".png"):
|
||||
|
||||
var texture = load("res://characters/" + file_name)
|
||||
|
||||
var texture_btn := TextureButton.new()
|
||||
|
||||
character_grid.add_child(texture_btn)
|
||||
texture_btn.custom_minimum_size = Vector2(80, 40)
|
||||
texture_btn.ignore_texture_size = true
|
||||
texture_btn.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT
|
||||
texture_btn.texture_normal = texture
|
||||
|
||||
texture_btn.pressed.connect(select_character.bind(file_name))
|
||||
|
||||
file_name = characters.get_next()
|
||||
|
||||
func show_grid():
|
||||
character_grid_container.visible = true
|
||||
|
||||
func select_character(file_name: String):
|
||||
print("select_character")
|
||||
character_selected.emit(file_name)
|
||||
@@ -1 +0,0 @@
|
||||
uid://cmxl2w45vvmx6
|
||||
@@ -1,25 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://b16on0oscg1bv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cmxl2w45vvmx6" path="res://CharacterSelect.gd" id="1_4bba6"]
|
||||
|
||||
[node name="CharacterSelect" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
script = ExtResource("1_4bba6")
|
||||
|
||||
[node name="ScrollContainer2" type="ScrollContainer" parent="."]
|
||||
clip_contents = false
|
||||
custom_minimum_size = Vector2(100, 100)
|
||||
layout_mode = 0
|
||||
offset_left = 194.0
|
||||
offset_top = 152.0
|
||||
offset_right = 670.0
|
||||
offset_bottom = 375.0
|
||||
|
||||
[node name="GridContainer" type="GridContainer" parent="ScrollContainer2"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
columns = 3
|
||||
@@ -1,8 +1,10 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bijh5h5yrivm3"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cw41y87l64qo7" path="res://log.gd" id="1_q72ua"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
[node name="Control" type="Control" node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
@@ -11,23 +13,35 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_q72ua")
|
||||
panel = NodePath("LogPanel")
|
||||
|
||||
[node name="LogPanel" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visibility_layer = 513
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 700.0
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="LogPanel"]
|
||||
layout_mode = 0
|
||||
offset_top = 8.0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 48.0
|
||||
theme_override_font_sizes/font_size = 25
|
||||
text = "Log"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LogScrollContainer" type="ScrollContainer" parent="LogPanel"]
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
offset_left = 20.0
|
||||
offset_top = 56.0
|
||||
offset_right = 680.0
|
||||
offset_bottom = 684.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="LogVBoxContainer" type="VBoxContainer" parent="LogPanel/LogScrollContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 1
|
||||
+55
-39
@@ -109,9 +109,6 @@ var player_container: VBoxContainer = $Players/VBoxContainer
|
||||
@onready
|
||||
var players_list_container: VBoxContainer = $Players/VBoxContainer/ScrollContainer/PlayersListVBoxContainer
|
||||
|
||||
@onready
|
||||
var character_select: Control = $CharacterSelect
|
||||
|
||||
@onready
|
||||
var new_character_select: Control = %NewCharacterSelect
|
||||
|
||||
@@ -140,11 +137,18 @@ var songs: Array= []
|
||||
var soundtracks: Array = []
|
||||
var current_player: Node
|
||||
|
||||
## True while statistics are off because a player won, until points are reset.
|
||||
var stats_paused_by_win: bool = false
|
||||
|
||||
## Dims the window behind an open popup and keeps clicks from reaching the buttons under it.
|
||||
var popup_backdrop: ColorRect
|
||||
|
||||
## Seconds to wait before retrying a song download step that failed.
|
||||
var song_fetch_retry_seconds: float = 5.0
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
_setup_popup_backdrop()
|
||||
var debug: bool = OS.has_feature("debug")
|
||||
var is_mac: bool = OS.has_feature("macos")
|
||||
if debug:
|
||||
@@ -168,7 +172,6 @@ func _ready() -> void:
|
||||
reset_playlist_button.pressed.connect(reset_playlist)
|
||||
reset_points_button.pressed.connect(reset_points)
|
||||
|
||||
character_select.connect("character_selected", _on_character_selected)
|
||||
new_character_select.connect("new_new_character_selected", _on_new_character_selected)
|
||||
new_player_name_field.connect("enter_key_pressed", add_player)
|
||||
music_player_container.connect("play_next_song", play_next_song)
|
||||
@@ -186,7 +189,6 @@ func _ready() -> void:
|
||||
|
||||
get_suggestion_list()
|
||||
fetch_song_list_at_start()
|
||||
fetch_song()
|
||||
search_view.get_list_of_soundtracks()
|
||||
new_character_select.load_characters()
|
||||
|
||||
@@ -216,9 +218,9 @@ func _input(event: InputEvent) -> void:
|
||||
if Settings.fullscreen == false:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
|
||||
if event.alt_pressed && event.keycode == KEY_K:
|
||||
shortcuts_window.visible = !shortcuts_window.visible
|
||||
shortcuts_window.toggle()
|
||||
if event.alt_pressed && event.keycode == KEY_L:
|
||||
log_window.visible = !log_window.visible
|
||||
log_window.toggle()
|
||||
|
||||
func server_updated() -> void:
|
||||
print("server_updated")
|
||||
@@ -240,14 +242,12 @@ func show_answer_pressed() -> void:
|
||||
Playlist.song_is_answered()
|
||||
update_song_list()
|
||||
|
||||
# Loads the songs already in the server playlist, then starts preloading new ones.
|
||||
# Preloading waits for the list, because loading the list clears the playlist.
|
||||
func fetch_song_list_at_start() -> void:
|
||||
print("fetch_song_list_at_start")
|
||||
var fetch_song_list_at_start_done: Callable = func fetch_songs_at_start_done(data) -> void:
|
||||
Playlist.clear_song_list()
|
||||
if data == null:
|
||||
Playlist.update_last_played_song()
|
||||
update_song_list()
|
||||
return
|
||||
if typeof(data) == TYPE_ARRAY:
|
||||
for d: Dictionary in data:
|
||||
var new_song_object: SongObject = SongObject.new()
|
||||
@@ -257,11 +257,14 @@ func fetch_song_list_at_start() -> void:
|
||||
new_song_object.is_answered = true
|
||||
new_song_object.has_played = true
|
||||
Playlist.add_to_playlist(new_song_object)
|
||||
else:
|
||||
elif data != null:
|
||||
print("Unexpected data")
|
||||
Playlist.update_last_played_song()
|
||||
update_song_list()
|
||||
MusicServerClient.fetch_song_list(fetch_song_list_at_start_done)
|
||||
if !Playlist.is_song_downloading:
|
||||
fetch_song()
|
||||
MusicServerClient.fetch_song_list(fetch_song_list_at_start_done,
|
||||
_retry_later.bind(fetch_song_list_at_start))
|
||||
|
||||
func play_next_song() -> void:
|
||||
print("play_next_song ", Playlist.latest_played_song)
|
||||
@@ -278,6 +281,28 @@ func play_next_song() -> void:
|
||||
#"/music/rand"
|
||||
#"/music/addQue"
|
||||
#"/music/info"
|
||||
func _popups() -> Array[PopupWindow]:
|
||||
return [search_view, sync_window, settings_window, qr_window, new_character_select,
|
||||
shortcuts_window, about_window, winner_window, log_window]
|
||||
|
||||
# The backdrop sits above the main window and below every popup. Popups close
|
||||
# themselves when clicked outside, and the backdrop keeps that click from reaching
|
||||
# the buttons behind them.
|
||||
func _setup_popup_backdrop() -> void:
|
||||
popup_backdrop = ColorRect.new()
|
||||
popup_backdrop.name = "PopupBackdrop"
|
||||
popup_backdrop.color = Color(0, 0, 0, 0.55)
|
||||
popup_backdrop.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
add_child(popup_backdrop)
|
||||
popup_backdrop.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
for popup: PopupWindow in _popups():
|
||||
move_child(popup, -1)
|
||||
popup.visibility_changed.connect(_update_popup_backdrop)
|
||||
_update_popup_backdrop()
|
||||
|
||||
func _update_popup_backdrop() -> void:
|
||||
popup_backdrop.visible = _popups().any(func(popup: PopupWindow) -> bool: return popup.visible)
|
||||
|
||||
# The cache size can be changed in the settings. Waiting until the settings are closed
|
||||
# avoids starting downloads while the user is still clicking the number up and down.
|
||||
func _on_settings_window_visibility_changed() -> void:
|
||||
@@ -360,7 +385,6 @@ func reset_playlist() -> void:
|
||||
var playlist_reset_done: Callable = func playlist_reset_done() -> void:
|
||||
Playlist.reset_playlist()
|
||||
fetch_song_list_at_start()
|
||||
fetch_song()
|
||||
|
||||
MusicServerClient.reset_playlist(playlist_reset_done)
|
||||
|
||||
@@ -369,22 +393,26 @@ func reset_points() -> void:
|
||||
for player_objects: PlayerObject in Settings.player_array:
|
||||
player_objects.reset_points()
|
||||
load_players()
|
||||
# A new game starts, so turn statistics back on if winning turned them off
|
||||
if stats_paused_by_win:
|
||||
Settings.add_to_stats = true
|
||||
stats_paused_by_win = false
|
||||
|
||||
func show_about() -> void:
|
||||
print("show_about")
|
||||
about_window.show_window()
|
||||
about_window.open()
|
||||
|
||||
func show_shortcuts() -> void:
|
||||
print("show_shortcuts")
|
||||
shortcuts_window.visible = true
|
||||
shortcuts_window.open()
|
||||
|
||||
func show_settings() -> void:
|
||||
print("show_settings")
|
||||
settings_window.visible = true
|
||||
settings_window.open()
|
||||
|
||||
func show_qr() -> void:
|
||||
print("show_qr")
|
||||
qr_window.show_window()
|
||||
qr_window.open()
|
||||
|
||||
func get_statistics() -> void:
|
||||
print("get_statistics")
|
||||
@@ -418,13 +446,8 @@ func get_suggestion_list() -> void:
|
||||
soundtracks = []
|
||||
Settings.delete_children(inspiration_list)
|
||||
soundtracks.append_array(array)
|
||||
for soundtrack: String in soundtracks:
|
||||
var inspiration_label: Label = Label.new()
|
||||
inspiration_label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
|
||||
inspiration_label.add_theme_font_size_override("font_size", 20)
|
||||
inspiration_label.text = soundtrack
|
||||
inspiration_label.autowrap_mode = TextServer.AUTOWRAP_WORD
|
||||
inspiration_list.add_child(inspiration_label)
|
||||
for i: int in soundtracks.size():
|
||||
inspiration_list.add_child(ListRow.create(soundtracks[i], i, 20))
|
||||
else:
|
||||
print("Unexpected data")
|
||||
MusicServerClient.fetch_all_soundtracks(populate_list)
|
||||
@@ -451,7 +474,7 @@ func add_player() -> void:
|
||||
|
||||
func load_players() -> void:
|
||||
print("load_players")
|
||||
Settings.delete_player_children(players_list_container)
|
||||
Settings.delete_children(players_list_container)
|
||||
var counter: int = 0
|
||||
for player_object: PlayerObject in Settings.player_array:
|
||||
print(player_object.player_name)
|
||||
@@ -488,7 +511,10 @@ func _on_player_won(player_object: PlayerObject) -> void:
|
||||
print("_on_player_won")
|
||||
winner_window.show_winner(player_object)
|
||||
music_player_container.play_song(preload("res://sounds/winning.mp3"))
|
||||
# Songs played after the game is won don't count towards the statistics
|
||||
if Settings.add_to_stats:
|
||||
Settings.add_to_stats = false
|
||||
stats_paused_by_win = true
|
||||
|
||||
func _on_player_removed(player_object: PlayerObject) -> void:
|
||||
print("_on_player_removed ", player_object.player_name)
|
||||
@@ -503,21 +529,13 @@ func _on_player_change_character_clicked(new_player: Player, player_name: String
|
||||
print("Change character for: " + player_name)
|
||||
new_character_select.show_grid(player_name)
|
||||
|
||||
func _on_character_selected(file_name: String) -> void:
|
||||
print("_on_character_selected")
|
||||
character_select.visible = false
|
||||
current_player.character_selected(file_name)
|
||||
|
||||
func _on_new_character_selected(character_texture: ImageTexture) -> void:
|
||||
print("_on_new_character_selected")
|
||||
current_player.new_character_selected(character_texture)
|
||||
|
||||
func show_search() -> void:
|
||||
print("show_search")
|
||||
if search_view.visible == false:
|
||||
search_view.visible = true
|
||||
else:
|
||||
search_view.visible = false
|
||||
search_view.toggle()
|
||||
|
||||
|
||||
###Local
|
||||
@@ -550,7 +568,5 @@ func dir_contents(path: String) -> void:
|
||||
else:
|
||||
print("An error occurred when trying to access the path.")
|
||||
|
||||
for soundtrack: String in soundtracks:
|
||||
var local_inspiration_label: Label = Label.new()
|
||||
local_inspiration_label.text = soundtrack
|
||||
inspiration_list.add_child(local_inspiration_label)
|
||||
for i: int in soundtracks.size():
|
||||
inspiration_list.add_child(ListRow.create(soundtracks[i], i, 20))
|
||||
+13
-38
@@ -1,7 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://xwq863o6uvsu"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b8f4g15cas2j2" path="res://MainWindow.gd" id="1_eu0t5"]
|
||||
[ext_resource type="PackedScene" uid="uid://b16on0oscg1bv" path="res://CharacterSelect.tscn" id="2_76kf4"]
|
||||
[ext_resource type="Script" uid="uid://elgn7gkxgagq" path="res://InsperationScrollContainer.gd" id="2_gxtxm"]
|
||||
[ext_resource type="Texture2D" uid="uid://bcfmpd7h512ef" path="res://icons/person_add_light.svg" id="5_31tjv"]
|
||||
[ext_resource type="PackedScene" uid="uid://ds15cgsf8vpvc" path="res://MusicPlayer.tscn" id="5_emn36"]
|
||||
@@ -17,6 +16,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://btupbowehiyyu" path="res://QRWindow.tscn" id="15_qr_window"]
|
||||
[ext_resource type="PackedScene" uid="uid://cp54idaudb8dp" path="res://AboutWindow.tscn" id="16_about_window"]
|
||||
[ext_resource type="PackedScene" uid="uid://cxlsmxnrp0agh" path="res://WinnerWindow.tscn" id="17_winner_window"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_ychxr"]
|
||||
font_size = 25
|
||||
@@ -70,7 +70,11 @@ events = [SubResource("InputEventKey_ujjlu")]
|
||||
|
||||
[node name="Control" type="Control" unique_id=407149696]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_eu0t5")
|
||||
|
||||
[node name="TopPanelContainer" type="PanelContainer" parent="." unique_id=663404711]
|
||||
@@ -79,7 +83,6 @@ offset_right = 1920.0
|
||||
offset_bottom = 56.0
|
||||
|
||||
[node name="Title" type="Label" parent="." unique_id=1187907861]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 64.0
|
||||
offset_top = 12.0
|
||||
@@ -121,14 +124,12 @@ follow_focus = true
|
||||
script = ExtResource("7_dj026")
|
||||
|
||||
[node name="MusicList" type="VBoxContainer" parent="MusicListPanel/ScrollContainer" unique_id=373398568]
|
||||
texture_filter = 1
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="." unique_id=498283761]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1216.0
|
||||
offset_top = 128.0
|
||||
@@ -139,7 +140,6 @@ vertical_scroll_mode = 3
|
||||
script = ExtResource("2_gxtxm")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer" unique_id=1215162949]
|
||||
texture_filter = 1
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
@@ -152,7 +152,6 @@ offset_right = 1152.0
|
||||
offset_bottom = 384.0
|
||||
|
||||
[node name="SoundtrackLabel" type="Label" parent="VBoxContainer" unique_id=173147793]
|
||||
texture_filter = 1
|
||||
custom_minimum_size = Vector2(1, 1)
|
||||
layout_mode = 2
|
||||
label_settings = SubResource("LabelSettings_qspbu")
|
||||
@@ -160,22 +159,12 @@ horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="SongLabel" type="Label" parent="VBoxContainer" unique_id=1687490027]
|
||||
texture_filter = 1
|
||||
custom_minimum_size = Vector2(1, 1)
|
||||
layout_mode = 2
|
||||
label_settings = SubResource("LabelSettings_3m52w")
|
||||
horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="CharacterSelect" parent="." unique_id=2079506802 instance=ExtResource("2_76kf4")]
|
||||
visible = false
|
||||
top_level = true
|
||||
layout_mode = 0
|
||||
offset_left = 616.0
|
||||
offset_top = 264.0
|
||||
offset_right = 776.0
|
||||
offset_bottom = 424.0
|
||||
|
||||
[node name="MusicPlayer" parent="." unique_id=1990459832 instance=ExtResource("5_emn36")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
@@ -205,7 +194,6 @@ custom_minimum_size = Vector2(2.08165e-12, 40)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Players/VBoxContainer/HBoxContainer" unique_id=1331357386]
|
||||
texture_filter = 1
|
||||
custom_minimum_size = Vector2(2.08165e-12, 40)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
@@ -215,7 +203,6 @@ horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="AddPlayersButton" type="TextureButton" parent="Players/VBoxContainer/HBoxContainer" unique_id=634410148]
|
||||
texture_filter = 1
|
||||
custom_minimum_size = Vector2(2.08165e-12, 40)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
@@ -242,7 +229,6 @@ placeholder_text = "Player name"
|
||||
script = ExtResource("7_qsdfy")
|
||||
|
||||
[node name="AddPlayerButton" type="Button" parent="Players/VBoxContainer/AddPlayerContainer" unique_id=245001313]
|
||||
texture_filter = 1
|
||||
custom_minimum_size = Vector2(2.08165e-12, 40)
|
||||
layout_mode = 2
|
||||
text = "Add"
|
||||
@@ -256,13 +242,14 @@ theme_override_styles/panel = SubResource("StyleBoxFlat_k1ygi")
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="Players/VBoxContainer" unique_id=1000000001]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 15
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="PlayersListVBoxContainer" type="VBoxContainer" parent="Players/VBoxContainer/ScrollContainer" unique_id=1000000002]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 15
|
||||
|
||||
[node name="ResetPlaylistButton" type="Button" parent="." unique_id=1754155620]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1360.0
|
||||
offset_top = 64.0
|
||||
@@ -273,7 +260,6 @@ action_mode = 0
|
||||
text = "Reset playlist"
|
||||
|
||||
[node name="ResetPointsButton" type="Button" parent="." unique_id=942880776]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1488.0
|
||||
offset_top = 64.0
|
||||
@@ -284,7 +270,6 @@ action_mode = 0
|
||||
text = "Reset points"
|
||||
|
||||
[node name="SyncButton" type="Button" parent="." unique_id=1228313556]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1616.0
|
||||
offset_top = 64.0
|
||||
@@ -295,7 +280,6 @@ action_mode = 0
|
||||
text = "Sync soundtracks"
|
||||
|
||||
[node name="SoundTestButton" type="Button" parent="." unique_id=1332971879]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1776.0
|
||||
offset_top = 64.0
|
||||
@@ -306,7 +290,6 @@ action_mode = 0
|
||||
text = "Sound test"
|
||||
|
||||
[node name="ShowAnswerButton" type="Button" parent="." unique_id=415388039]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 65.0
|
||||
offset_top = 944.0
|
||||
@@ -318,7 +301,6 @@ shortcut = SubResource("Shortcut_a7fvb")
|
||||
text = "Show answer"
|
||||
|
||||
[node name="NextButton" type="Button" parent="." unique_id=1744703488]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 193.0
|
||||
offset_top = 944.0
|
||||
@@ -331,7 +313,6 @@ shortcut = SubResource("Shortcut_d6fml")
|
||||
text = "Randomize new track"
|
||||
|
||||
[node name="SearchButton" type="Button" parent="." unique_id=1782453581]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1354.0
|
||||
offset_top = 8.0
|
||||
@@ -343,7 +324,6 @@ shortcut = SubResource("Shortcut_fbju4")
|
||||
text = "Search"
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="." unique_id=1193400323]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1442.0
|
||||
offset_top = 8.0
|
||||
@@ -354,7 +334,6 @@ action_mode = 0
|
||||
text = "Settings"
|
||||
|
||||
[node name="StatisticsButton" type="Button" parent="." unique_id=2045021269]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1530.0
|
||||
offset_top = 8.0
|
||||
@@ -365,7 +344,6 @@ action_mode = 0
|
||||
text = "Statistics"
|
||||
|
||||
[node name="ShortcutsButton" type="Button" parent="." unique_id=2066498226]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1626.0
|
||||
offset_top = 8.0
|
||||
@@ -376,7 +354,6 @@ action_mode = 0
|
||||
text = "Shortcuts"
|
||||
|
||||
[node name="AboutButton" type="Button" parent="." unique_id=1057035253]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1722.0
|
||||
offset_top = 8.0
|
||||
@@ -387,7 +364,6 @@ action_mode = 0
|
||||
text = "About"
|
||||
|
||||
[node name="QRButton" type="Button" parent="." unique_id=2021908559]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 1802.0
|
||||
offset_top = 8.0
|
||||
@@ -409,9 +385,9 @@ offset_bottom = 96.0
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
offset_left = 401.0
|
||||
offset_left = 210.0
|
||||
offset_top = 153.0
|
||||
offset_right = 401.0
|
||||
offset_right = 210.0
|
||||
offset_bottom = 153.0
|
||||
|
||||
[node name="SettingsWindow" parent="." unique_id=1323246978 instance=ExtResource("11_k62u5")]
|
||||
@@ -435,9 +411,9 @@ offset_bottom = 153.0
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
offset_left = 420.0
|
||||
offset_left = 405.0
|
||||
offset_top = 165.0
|
||||
offset_right = 1572.0
|
||||
offset_right = 1557.0
|
||||
offset_bottom = 805.0
|
||||
|
||||
[node name="ShortcutsWindow" parent="." unique_id=1513416242 instance=ExtResource("13_8eebo")]
|
||||
@@ -450,12 +426,12 @@ offset_right = 1262.0
|
||||
offset_bottom = 860.0
|
||||
|
||||
[node name="StatisticsPopupPanel" type="PopupPanel" parent="." unique_id=298311407]
|
||||
theme = ExtResource("popup_theme")
|
||||
oversampling_override = 1.0
|
||||
initial_position = 2
|
||||
size = Vector2i(450, 100)
|
||||
|
||||
[node name="Label" type="Label" parent="StatisticsPopupPanel" unique_id=548316493]
|
||||
texture_filter = 1
|
||||
offset_left = 4.0
|
||||
offset_top = 4.0
|
||||
offset_right = 446.0
|
||||
@@ -464,7 +440,6 @@ text = "Statistics"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="StatisticsLabel" type="Label" parent="StatisticsPopupPanel" unique_id=58226477]
|
||||
texture_filter = 1
|
||||
offset_left = 4.0
|
||||
offset_top = 4.0
|
||||
offset_right = 446.0
|
||||
|
||||
@@ -28,9 +28,6 @@ var volume_slider: HSlider = $MusicPlayerContainer/VolumeSlider
|
||||
@onready
|
||||
var music_time_label: Label = $MusicPlayerContainer/MusicTimeLabel
|
||||
|
||||
@onready
|
||||
var path: String = '/Users/sebastian/ResilioSync/Sorterat_test/Metal Gear Solid 4 - Guns of the Patriots/2-16 Metal Gear Saga.mp3'
|
||||
|
||||
var play_icon: Texture = preload("res://icons/play_icon_light.svg")
|
||||
var pause_icon: Texture = preload("res://icons/pause_icon_light.svg")
|
||||
|
||||
|
||||
@@ -60,11 +60,6 @@ func minus_point() -> void:
|
||||
func change_character() -> void:
|
||||
change_character_clicked.emit()
|
||||
|
||||
func character_selected(file_name: String) -> void:
|
||||
print("Back in player list with: " + file_name)
|
||||
player_object.character = load("res://characters/" + file_name)
|
||||
set_player_character()
|
||||
|
||||
func new_character_selected(character_texture: ImageTexture) -> void:
|
||||
print("Back in player list with new")
|
||||
player_object.character = character_texture
|
||||
|
||||
+10
-5
@@ -29,9 +29,12 @@ script = ExtResource("1_if4kc")
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
custom_minimum_size = Vector2(2.08165e-12, 40)
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Panel4" type="Panel" parent="HBoxContainer"]
|
||||
custom_minimum_size = Vector2(5, 40)
|
||||
@@ -41,12 +44,15 @@ theme_override_styles/panel = SubResource("StyleBoxFlat_821k2")
|
||||
[node name="Name" type="Label" parent="HBoxContainer"]
|
||||
custom_minimum_size = Vector2(130, 40)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = ": 0"
|
||||
vertical_alignment = 1
|
||||
clip_text = true
|
||||
text_overrun_behavior = 3
|
||||
|
||||
[node name="Panel3" type="Panel" parent="HBoxContainer"]
|
||||
custom_minimum_size = Vector2(80, 2.08165e-12)
|
||||
custom_minimum_size = Vector2(16, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_w10e8")
|
||||
|
||||
@@ -91,7 +97,6 @@ theme_override_styles/panel = SubResource("StyleBoxFlat_b2crt")
|
||||
[node name="RemovePlayer" type="TextureButton" parent="HBoxContainer"]
|
||||
custom_minimum_size = Vector2(40, 40)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
texture_normal = ExtResource("3_j3uxe")
|
||||
|
||||
+12
-5
@@ -19,7 +19,10 @@ var player_score: int
|
||||
|
||||
var is_first_point: bool = true
|
||||
|
||||
var character: Texture = load("res://noCharacter.png")
|
||||
## Picture shown until the player picks a character.
|
||||
const NO_CHARACTER_PATH: String = "res://noCharacter.png"
|
||||
|
||||
var character: Texture = load(NO_CHARACTER_PATH)
|
||||
|
||||
func _init(new_name: String) -> void:
|
||||
player_name = new_name
|
||||
@@ -37,13 +40,17 @@ func add_point() -> void:
|
||||
if player_score < Settings.winning_score:
|
||||
player_score += 1
|
||||
player_point_given.emit()
|
||||
if player_score == 1 && is_first_point:
|
||||
var first_point: bool = player_score == 1 && is_first_point
|
||||
if player_score == 1:
|
||||
is_first_point = false
|
||||
first_point_triggerd.emit()
|
||||
# With a low winning score the first point can also be match point or the win,
|
||||
# so the more important event is checked first
|
||||
if player_score == Settings.winning_score:
|
||||
winner_triggerd.emit()
|
||||
elif player_score == Settings.winning_score - 1:
|
||||
match_point_triggerd.emit()
|
||||
elif player_score == Settings.winning_score:
|
||||
winner_triggerd.emit()
|
||||
elif first_point:
|
||||
first_point_triggerd.emit()
|
||||
else:
|
||||
point_given_sound.emit()
|
||||
|
||||
|
||||
+3
-14
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var qr_panel: Panel = $QRPanel
|
||||
@@ -21,21 +21,10 @@ func _ready() -> void:
|
||||
url_label.text = qr_code_rect.data
|
||||
print("QR code generated for: ", url)
|
||||
|
||||
func show_window() -> void:
|
||||
visible = true
|
||||
func open() -> void:
|
||||
super()
|
||||
# Regenerate QR code in case settings changed
|
||||
var url: String = Settings.default_path + "/search"
|
||||
qr_code_rect.data = url
|
||||
url_label.text = qr_code_rect.data
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if self.visible == true:
|
||||
if event is InputEventMouseButton && event.is_pressed():
|
||||
var evLocal: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), qr_panel.size).has_point(evLocal.position):
|
||||
self.visible = false
|
||||
|
||||
|
||||
func hide_window() -> void:
|
||||
visible = false
|
||||
+4
-1
@@ -2,8 +2,10 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://bsa6xg5xos6h7" path="res://QRWindow.gd" id="1_qr_script"]
|
||||
[ext_resource type="Script" uid="uid://dynulhnyq5hpq" path="res://addons/kenyoni/qr_code/qr_code_rect.gd" id="2_jpsxt"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="QRControl" type="Control" unique_id=1996957585]
|
||||
[node name="QRControl" type="Control" unique_id=1996957585 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -11,6 +13,7 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_qr_script")
|
||||
panel = NodePath("QRPanel")
|
||||
|
||||
[node name="QRPanel" type="Panel" parent="." unique_id=1021365843]
|
||||
unique_name_in_owner = true
|
||||
|
||||
+10
-1
@@ -11,10 +11,19 @@ same version in the About window.
|
||||
The `Build` workflow (`.gitea/workflows/gitea-build.yaml`) then:
|
||||
|
||||
1. runs the tests,
|
||||
2. exports the Windows and Linux builds,
|
||||
2. exports the Windows and Linux builds, and packages Linux as
|
||||
`MusicPlayer_<version>_linux.tar.gz` with the icon, an app menu entry and `install.sh`
|
||||
(Linux programs can't carry their own icon the way a Windows .exe does),
|
||||
3. if no tag exists for the version yet: uploads the builds to the package registry
|
||||
under `MusicPlayer/<version>/`, and creates the `<version>` tag and Gitea release
|
||||
with the builds attached.
|
||||
|
||||
Pushes that don't change the version, and pushes to `develop`, only test and export.
|
||||
Don't create tags or `1.x.y` branches by hand; the workflow makes the tag.
|
||||
|
||||
## Installing on Linux
|
||||
|
||||
Unpack `MusicPlayer_<version>_linux.tar.gz` and run `./install.sh` inside the
|
||||
`MusicPlayer` folder. It installs the game to `~/.local/bin` and adds it, with its icon,
|
||||
to the app menu. The bare `MusicPlayer_<version>.x86_64` is still published for anyone
|
||||
who just wants to run the file.
|
||||
+2
-9
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var search_list: VBoxContainer = $ScrollContainer/VBoxContainer
|
||||
@@ -36,7 +36,7 @@ func focus() -> void:
|
||||
|
||||
func close() -> void:
|
||||
clear()
|
||||
self.visible = false
|
||||
super()
|
||||
|
||||
func search() -> void:
|
||||
print(search_bar.text)
|
||||
@@ -179,13 +179,6 @@ func set_soundtracks(list: Array) -> void:
|
||||
"cleaned": clean_term(soundtrack)
|
||||
})
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if self.visible == true:
|
||||
if event is InputEventMouseButton && event.is_pressed():
|
||||
var evLocal: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), search_panel.size).has_point(evLocal.position):
|
||||
self.visible = false
|
||||
|
||||
func clear() -> void:
|
||||
search_bar.text = ""
|
||||
show_all_soundtracks()
|
||||
|
||||
+4
-3
@@ -1,8 +1,10 @@
|
||||
[gd_scene format=3 uid="uid://bxydgil1yifps"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bg5yo08638600" path="res://SearchWindow.gd" id="1_m7bij"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="Control" type="Control" unique_id=616238617]
|
||||
[node name="Control" type="Control" unique_id=616238617 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -10,6 +12,7 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_m7bij")
|
||||
panel = NodePath("SearchPanel")
|
||||
|
||||
[node name="SearchPanel" type="Panel" parent="." unique_id=1262945994]
|
||||
unique_name_in_owner = true
|
||||
@@ -18,7 +21,6 @@ offset_right = 1152.0
|
||||
offset_bottom = 640.0
|
||||
|
||||
[node name="ClearButton" type="Button" parent="." unique_id=1549439398]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 936.0
|
||||
offset_top = 16.0
|
||||
@@ -30,7 +32,6 @@ action_mode = 0
|
||||
text = "Clear"
|
||||
|
||||
[node name="Searchbar" type="TextEdit" parent="." unique_id=2112669372]
|
||||
texture_filter = 1
|
||||
layout_mode = 0
|
||||
offset_left = 32.0
|
||||
offset_top = 16.0
|
||||
|
||||
@@ -36,8 +36,3 @@ func delete_children(node: Node) -> void:
|
||||
for n: Node in node.get_children():
|
||||
node.remove_child(n)
|
||||
n.queue_free()
|
||||
|
||||
func delete_player_children(node: Node) -> void:
|
||||
for n: Node in node.get_children():
|
||||
node.remove_child(n)
|
||||
n.queue_free()
|
||||
+7
-8
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var settings_panel: Panel = %SettingsPanel
|
||||
@@ -109,13 +109,12 @@ func _ready() -> void:
|
||||
update_hide_for_seconds_enabled()
|
||||
select_server_button.select(Settings.selected_server)
|
||||
select_server_button.item_selected.connect(select_server)
|
||||
visibility_changed.connect(_on_visibility_changed)
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if self.visible == true:
|
||||
if event is InputEventMouseButton && event.is_pressed():
|
||||
var evLocal: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), settings_panel.size).has_point(evLocal.position):
|
||||
self.visible = false
|
||||
# Settings can change outside this window, e.g. winning turns statistics off
|
||||
func _on_visibility_changed() -> void:
|
||||
if visible:
|
||||
add_to_database_button.button_pressed = Settings.add_to_stats
|
||||
|
||||
func fullscreen() -> void:
|
||||
Settings.fullscreen = !Settings.fullscreen
|
||||
@@ -154,7 +153,7 @@ func hide_ticks() -> void:
|
||||
Settings.hide_ticks = !Settings.hide_ticks
|
||||
|
||||
func lower_winning_score() -> void:
|
||||
Settings.winning_score -= 1
|
||||
Settings.winning_score = max(Settings.winning_score - 1, 1)
|
||||
score_label.text = str(Settings.winning_score)
|
||||
|
||||
func increase_winning_score() -> void:
|
||||
|
||||
+31
-13
@@ -1,11 +1,13 @@
|
||||
[gd_scene format=3 uid="uid://dldpeo5y3l5hq"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dukqyjoduf1af" path="res://SettingsWindow.gd" id="1_bt55j"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_3xrlm"]
|
||||
font_size = 25
|
||||
|
||||
[node name="SettingsControl" type="Control" unique_id=1298840328]
|
||||
[node name="SettingsControl" type="Control" unique_id=1298840328 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -13,6 +15,7 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_bt55j")
|
||||
panel = NodePath("SettingsPanel")
|
||||
|
||||
[node name="SettingsPanel" type="Panel" parent="." unique_id=45537159]
|
||||
unique_name_in_owner = true
|
||||
@@ -22,8 +25,11 @@ offset_bottom = 640.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="SettingsPanel" unique_id=1325795358]
|
||||
layout_mode = 0
|
||||
offset_right = 500.0
|
||||
offset_bottom = 640.0
|
||||
offset_left = 20.0
|
||||
offset_top = 8.0
|
||||
offset_right = 480.0
|
||||
offset_bottom = 632.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="SettingsPanel/ScrollContainer" unique_id=1796635163]
|
||||
clip_contents = true
|
||||
@@ -40,7 +46,7 @@ horizontal_alignment = 1
|
||||
[node name="StopAfterCurrentCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=508305575]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Stop after current"
|
||||
@@ -48,7 +54,7 @@ text = "Stop after current"
|
||||
[node name="HideNextTrackCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1568244599]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Hide next track"
|
||||
@@ -56,21 +62,21 @@ text = "Hide next track"
|
||||
[node name="AddToDatabaseCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1673750542]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Turn on played to database"
|
||||
|
||||
[node name="LowPlayedCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1672657048]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Use low played mode"
|
||||
|
||||
[node name="HideBeginningCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=1370617867]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Hide beginning of songs"
|
||||
|
||||
@@ -81,12 +87,15 @@ layout_mode = 2
|
||||
[node name="HideForSecondsTitle" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HideForSecondsHBoxContainer" unique_id=1822369383]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Hide Start Seconds: "
|
||||
|
||||
[node name="HideForSecondsLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HideForSecondsHBoxContainer" unique_id=1580108945]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "5.0"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerHideForSecondsButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HideForSecondsHBoxContainer" unique_id=180643442]
|
||||
unique_name_in_owner = true
|
||||
@@ -107,14 +116,14 @@ text = "+1"
|
||||
[node name="HideLengthCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=67806372]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Hide length of songs"
|
||||
|
||||
[node name="HideTicksCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=706322752]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
action_mode = 0
|
||||
text = "Hide ticks in playbar"
|
||||
|
||||
@@ -123,12 +132,15 @@ layout_mode = 2
|
||||
|
||||
[node name="Label2" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer" unique_id=1892907487]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Winning Score: "
|
||||
|
||||
[node name="ScoreLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer" unique_id=444542662]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "20"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer" unique_id=614806355]
|
||||
unique_name_in_owner = true
|
||||
@@ -151,12 +163,15 @@ layout_mode = 2
|
||||
|
||||
[node name="CacheTitleLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer" unique_id=365012193]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Predownload songs: "
|
||||
|
||||
[node name="CacheLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer" unique_id=1558370172]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "1"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerCacheButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer" unique_id=1990385038]
|
||||
unique_name_in_owner = true
|
||||
@@ -179,12 +194,15 @@ layout_mode = 2
|
||||
|
||||
[node name="InspirationListSpeedTitle" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer" unique_id=1397861506]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Inspiration List Speed: "
|
||||
|
||||
[node name="InspirationListSpeedLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer" unique_id=867387668]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(48, 0)
|
||||
layout_mode = 2
|
||||
text = "1"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LowerInspirationSpeedButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer" unique_id=845209534]
|
||||
unique_name_in_owner = true
|
||||
@@ -221,13 +239,13 @@ popup/item_4/id = 5
|
||||
[node name="FullscreenButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=400304684]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
text = "Fullscreen"
|
||||
|
||||
[node name="QuickSyncButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer" unique_id=49497448]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Quick sync"
|
||||
@@ -236,6 +254,6 @@ text = "Quick sync"
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
disabled = true
|
||||
text = "Local"
|
||||
+21
-17
@@ -1,11 +1,13 @@
|
||||
[gd_scene format=3 uid="uid://dpdem7pdxweb5"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3ejukwth512a" path="res://sync_window.gd" id="1_8ba47"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_anbfi"]
|
||||
font_size = 25
|
||||
|
||||
[node name="Control2" type="Control" unique_id=1302914356]
|
||||
[node name="Control2" type="Control" unique_id=1302914356 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -13,21 +15,26 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_8ba47")
|
||||
panel = NodePath("SyncPanel")
|
||||
|
||||
[node name="SyncPanel" type="Panel" parent="." unique_id=1714634204]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 1152.0
|
||||
offset_right = 1500.0
|
||||
offset_bottom = 640.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="SyncPanel" unique_id=1289116349]
|
||||
layout_mode = 0
|
||||
offset_right = 1152.0
|
||||
offset_bottom = 640.0
|
||||
offset_left = 20.0
|
||||
offset_top = 8.0
|
||||
offset_right = 1480.0
|
||||
offset_bottom = 632.0
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="SyncVBoxContainer" type="VBoxContainer" parent="SyncPanel/ScrollContainer" unique_id=1594735567]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="SyncTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=2125198054]
|
||||
unique_name_in_owner = true
|
||||
@@ -59,7 +66,7 @@ layout_mode = 2
|
||||
|
||||
[node name="SyncProgressBar" type="ProgressBar" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/ProgressHBoxContainer" unique_id=719135231]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(1000, 0)
|
||||
custom_minimum_size = Vector2(1300, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
step = 1.0
|
||||
@@ -69,17 +76,13 @@ rounded = true
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
theme_override_constants/separation = 30
|
||||
|
||||
[node name="VSeparator6" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1432793432]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 16
|
||||
|
||||
[node name="SoundtracksAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=897546696]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksAddedVBox" unique_id=535797768]
|
||||
layout_mode = 2
|
||||
@@ -93,7 +96,7 @@ layout_mode = 2
|
||||
[node name="SoundtracksReAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=995736806]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksReAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksReAddedVBox" unique_id=1142636525]
|
||||
layout_mode = 2
|
||||
@@ -106,7 +109,7 @@ layout_mode = 2
|
||||
[node name="SoundtracksChangedTitleVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=294212033]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksChangedTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksChangedTitleVBox" unique_id=696960827]
|
||||
layout_mode = 2
|
||||
@@ -119,7 +122,7 @@ layout_mode = 2
|
||||
[node name="SoundtracksChangedContentVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1470922281]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksChangedContentLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksChangedContentVBox" unique_id=1209639099]
|
||||
layout_mode = 2
|
||||
@@ -132,7 +135,7 @@ layout_mode = 2
|
||||
[node name="SoundtracksRemovedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1174594338]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SoundtracksRemovedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksRemovedVBox" unique_id=877713862]
|
||||
layout_mode = 2
|
||||
@@ -146,6 +149,7 @@ layout_mode = 2
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CatchedErrorsLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/CatchedErrorsVBox" unique_id=1784389644]
|
||||
layout_mode = 2
|
||||
|
||||
+4
-2
@@ -2,11 +2,13 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://dxpb22xbwf3t1" path="res://winner_window.gd" id="1_winner_script"]
|
||||
[ext_resource type="Texture2D" uid="uid://r4as0nmtoa7p" path="res://noCharacter.png" id="2_no_character"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_hr75l"]
|
||||
font_size = 35
|
||||
|
||||
[node name="WinnerControl" type="Control" unique_id=1111111111]
|
||||
[node name="WinnerControl" type="Control" unique_id=1111111111 node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -14,6 +16,7 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_winner_script")
|
||||
panel = NodePath("WinnerPanel")
|
||||
|
||||
[node name="WinnerPanel" type="Panel" parent="." unique_id=89212869]
|
||||
unique_name_in_owner = true
|
||||
@@ -40,7 +43,6 @@ stretch_mode = 5
|
||||
|
||||
[node name="WinnerLabel" type="Label" parent="WinnerPanel/VBoxContainer" unique_id=1437597286]
|
||||
unique_name_in_owner = true
|
||||
texture_filter = 1
|
||||
layout_mode = 2
|
||||
text = "Winner!"
|
||||
label_settings = SubResource("LabelSettings_hr75l")
|
||||
|
||||
+4
-4
@@ -8,7 +8,7 @@ dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter="tests/*, addons/gdUnit4/*"
|
||||
exclude_filter="tests/*, addons/gdUnit4/*, linux/*"
|
||||
export_path="../../MusicPlayer_1.5.1.exe"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
@@ -83,7 +83,7 @@ dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter="tests/*, addons/gdUnit4/*"
|
||||
exclude_filter="tests/*, addons/gdUnit4/*, linux/*"
|
||||
export_path="./MusicPlayer_0.9_Beta.dmg"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
@@ -343,7 +343,7 @@ dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter="tests/*, addons/gdUnit4/*"
|
||||
exclude_filter="tests/*, addons/gdUnit4/*, linux/*"
|
||||
export_path="web/index.html"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
@@ -390,7 +390,7 @@ dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter="tests/*, addons/gdUnit4/*"
|
||||
exclude_filter="tests/*, addons/gdUnit4/*, linux/*"
|
||||
export_path="./MusicPlayer_1.5.1.x86_64"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
|
||||
@@ -1 +1,116 @@
|
||||
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><g transform="translate(32 32)"><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99z" fill="#363d52"/><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99zm0 4h96c6.64 0 12 5.35 12 11.99v95.98c0 6.64-5.35 11.99-12 11.99h-96c-6.64 0-12-5.35-12-11.99v-95.98c0-6.64 5.36-11.99 12-11.99z" fill-opacity=".4"/></g><g stroke-width="9.92746" transform="matrix(.10073078 0 0 .10073078 12.425923 2.256365)"><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 919.24059 771.67186)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 104.69892 525.90697)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 784.07144 817.24284)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 389.21484 625.67104)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 367.36686 631.05679)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 511.99336 724.73954)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 634.78706 625.67104)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 656.64056 631.05679)"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
|
||||
<defs>
|
||||
<linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#6fb1d6"/>
|
||||
<stop offset="1" stop-color="#2e6a94"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="plate" cx="0.42" cy="0.38" r="0.7">
|
||||
<stop offset="0" stop-color="#ffffff"/>
|
||||
<stop offset="1" stop-color="#e3ded6"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="well" cx="0.45" cy="0.4" r="0.7">
|
||||
<stop offset="0" stop-color="#fbf9f5"/>
|
||||
<stop offset="1" stop-color="#e9e3d9"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="band" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#4a4a4a"/>
|
||||
<stop offset="1" stop-color="#1f1f1f"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="cup" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#3d3d3d"/>
|
||||
<stop offset="1" stop-color="#151515"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="cookie" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#d99a52"/>
|
||||
<stop offset="1" stop-color="#b8742f"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="falu" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#c63b2f"/>
|
||||
<stop offset="1" stop-color="#9e2a21"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect x="16" y="16" width="480" height="480" rx="108" fill="url(#sky)"/>
|
||||
|
||||
<!-- Plate shadow, plate, rim band and well -->
|
||||
<ellipse cx="262" cy="306" rx="178" ry="174" fill="#1d4a6b" opacity="0.35"/>
|
||||
<circle cx="256" cy="294" r="172" fill="url(#plate)" stroke="#d6d0c6" stroke-width="3"/>
|
||||
<circle cx="256" cy="294" r="150" fill="none" stroke="#3b6ea5" stroke-width="7"/>
|
||||
<circle cx="256" cy="294" r="139" fill="none" stroke="#3b6ea5" stroke-width="2"/>
|
||||
<circle cx="256" cy="294" r="116" fill="url(#well)" stroke="#ddd6cb" stroke-width="2"/>
|
||||
|
||||
<!-- Headphone band arching over the plate -->
|
||||
<path d="M 92 286 A 164 164 0 0 1 420 286" fill="none" stroke="url(#band)" stroke-width="26" stroke-linecap="round"/>
|
||||
<path d="M 104 262 A 152 152 0 0 1 408 262" fill="none" stroke="#6a6a6a" stroke-width="4" stroke-linecap="round" opacity="0.6"/>
|
||||
|
||||
<!-- Ear cups on the plate's edges -->
|
||||
<g>
|
||||
<rect x="58" y="232" width="62" height="118" rx="28" fill="url(#cup)"/>
|
||||
<rect x="104" y="246" width="28" height="90" rx="14" fill="#2c2c2c" stroke="#ff8c1a" stroke-width="4"/>
|
||||
<rect x="70" y="252" width="10" height="56" rx="5" fill="#ffffff" opacity="0.15"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="392" y="232" width="62" height="118" rx="28" fill="url(#cup)"/>
|
||||
<rect x="380" y="246" width="28" height="90" rx="14" fill="#2c2c2c" stroke="#ff8c1a" stroke-width="4"/>
|
||||
<rect x="404" y="252" width="10" height="56" rx="5" fill="#ffffff" opacity="0.15"/>
|
||||
</g>
|
||||
|
||||
<!-- Crumbs -->
|
||||
<g fill="#c98a45">
|
||||
<circle cx="178" cy="370" r="4"/>
|
||||
<circle cx="190" cy="381" r="2.5"/>
|
||||
<circle cx="336" cy="378" r="3.5"/>
|
||||
<circle cx="326" cy="214" r="2.5"/>
|
||||
<circle cx="184" cy="226" r="3"/>
|
||||
</g>
|
||||
|
||||
<!-- House-shaped cookie: thick baked edge, then falu red icing -->
|
||||
<g transform="translate(256 288) scale(1.12) translate(-256 -288)">
|
||||
<!-- shadow -->
|
||||
<path d="M 256 192 L 344 270 L 334 270 L 334 368 L 178 368 L 178 270 L 168 270 Z"
|
||||
fill="#7a4a1e" opacity="0.28" stroke="#7a4a1e" stroke-width="16" stroke-linejoin="round"
|
||||
transform="translate(5 7)"/>
|
||||
<!-- chimney, baked -->
|
||||
<rect x="290" y="206" width="22" height="40" rx="6" fill="#c98a45" stroke="#c98a45" stroke-width="10" stroke-linejoin="round"/>
|
||||
<!-- cookie body with a thick, rounded baked edge -->
|
||||
<path d="M 256 192 L 344 270 L 334 270 L 334 368 L 178 368 L 178 270 L 168 270 Z"
|
||||
fill="url(#cookie)" stroke="#c98a45" stroke-width="16" stroke-linejoin="round"/>
|
||||
<path d="M 256 192 L 344 270 L 334 270 L 334 368 L 178 368 L 178 270 L 168 270 Z"
|
||||
fill="none" stroke="#a8682a" stroke-width="2" stroke-linejoin="round" transform="translate(0 0)" opacity="0.6"/>
|
||||
<rect x="295" y="214" width="12" height="26" rx="2" fill="#3a3a3a"/>
|
||||
|
||||
<!-- roof icing -->
|
||||
<path d="M 256 210 L 324 270 L 188 270 Z" fill="#3e3e46"/>
|
||||
<!-- walls icing, falu red -->
|
||||
<rect x="190" y="272" width="132" height="86" rx="4" fill="url(#falu)"/>
|
||||
<!-- white roof edge piping -->
|
||||
<path d="M 182 274 L 256 208 L 330 274" fill="none" stroke="#fdfbf7" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<!-- white corner boards -->
|
||||
<rect x="190" y="272" width="8" height="86" fill="#fdfbf7"/>
|
||||
<rect x="314" y="272" width="8" height="86" fill="#fdfbf7"/>
|
||||
|
||||
<!-- windows with white frames and crosses -->
|
||||
<rect x="210" y="288" width="30" height="30" rx="2" fill="#2f5d86" stroke="#fdfbf7" stroke-width="5"/>
|
||||
<path d="M 225 288 V 318 M 210 303 H 240" stroke="#fdfbf7" stroke-width="3"/>
|
||||
<rect x="272" y="288" width="30" height="30" rx="2" fill="#2f5d86" stroke="#fdfbf7" stroke-width="5"/>
|
||||
<path d="M 287 288 V 318 M 272 303 H 302" stroke="#fdfbf7" stroke-width="3"/>
|
||||
<!-- door with white frame -->
|
||||
<rect x="242" y="320" width="28" height="38" rx="2" fill="#7e1f18" stroke="#fdfbf7" stroke-width="4"/>
|
||||
<circle cx="264" cy="340" r="2.5" fill="#f2c14e"/>
|
||||
<!-- gable window in the roof -->
|
||||
<circle cx="256" cy="246" r="8" fill="#f2c14e" stroke="#fdfbf7" stroke-width="3"/>
|
||||
|
||||
<!-- dotted icing along the cookie's bottom edge -->
|
||||
<g fill="#fdfbf7">
|
||||
<circle cx="196" cy="368" r="3"/>
|
||||
<circle cx="214" cy="368" r="3"/>
|
||||
<circle cx="232" cy="368" r="3"/>
|
||||
<circle cx="250" cy="368" r="3"/>
|
||||
<circle cx="268" cy="368" r="3"/>
|
||||
<circle cx="286" cy="368" r="3"/>
|
||||
<circle cx="304" cy="368" r="3"/>
|
||||
<circle cx="322" cy="368" r="3"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 5.7 KiB |
@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.cte
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
# Installs Music Player Randomizer for the current user, with an app menu entry and icon.
|
||||
# Run it from the unpacked release folder: ./install.sh
|
||||
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
bin_dir="${XDG_BIN_HOME:-$HOME/.local/bin}"
|
||||
data_dir="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
binary="$bin_dir/music-player-randomizer"
|
||||
|
||||
icon_dir="$data_dir/icons/hicolor/256x256/apps"
|
||||
mkdir -p "$bin_dir" "$icon_dir" "$data_dir/applications"
|
||||
install -m755 MusicPlayer.x86_64 "$binary"
|
||||
install -m644 music-player-randomizer.png "$icon_dir/music-player-randomizer.png"
|
||||
# The menu entry needs the full path, since ~/.local/bin is not always on PATH
|
||||
sed "s|^Exec=.*|Exec=$binary|" music-player-randomizer.desktop \
|
||||
> "$data_dir/applications/music-player-randomizer.desktop"
|
||||
|
||||
# Refresh menu and icon caches where the tools exist; most desktops also notice on their own
|
||||
command -v update-desktop-database > /dev/null \
|
||||
&& update-desktop-database "$data_dir/applications" || true
|
||||
command -v gtk-update-icon-cache > /dev/null \
|
||||
&& gtk-update-icon-cache -q "$data_dir/icons/hicolor" || true
|
||||
|
||||
echo "Installed. Start it from your app menu, or run: $binary"
|
||||
echo "To uninstall, delete:"
|
||||
echo " $binary"
|
||||
echo " $data_dir/applications/music-player-randomizer.desktop"
|
||||
echo " $icon_dir/music-player-randomizer.png"
|
||||
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Music Player Randomizer
|
||||
Comment=Guess the video game soundtrack with your friends
|
||||
Exec=music-player-randomizer
|
||||
Icon=music-player-randomizer
|
||||
Terminal=false
|
||||
Categories=Game;Audio;
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Packages an exported Linux build with its icon, app menu entry and install script.
|
||||
#
|
||||
# Usage: linux/package.sh <exported binary> <version> <output dir>
|
||||
# Creates <output dir>/MusicPlayer_<version>_linux.tar.gz. Godot is taken from $GODOT,
|
||||
# or `godot` on PATH, to render the icon.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -ne 3 ]]; then
|
||||
echo "Usage: $0 <exported binary> <version> <output dir>" >&2
|
||||
exit 1
|
||||
fi
|
||||
binary="$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
|
||||
version="$2"
|
||||
out_dir="$(mkdir -p "$3" && cd "$3" && pwd)"
|
||||
linux_dir="$(cd "$(dirname "$0")" && pwd)"
|
||||
project_dir="$(dirname "$linux_dir")"
|
||||
godot_bin="${GODOT:-godot}"
|
||||
|
||||
staging="$(mktemp -d)"
|
||||
trap 'rm -rf "$staging"' EXIT
|
||||
package_dir="$staging/MusicPlayer"
|
||||
mkdir -p "$package_dir"
|
||||
|
||||
install -m755 "$binary" "$package_dir/MusicPlayer.x86_64"
|
||||
install -m755 "$linux_dir/install.sh" "$package_dir/install.sh"
|
||||
install -m644 "$linux_dir/music-player-randomizer.desktop" "$package_dir/"
|
||||
# Run outside the project so Godot only renders the icon
|
||||
(cd "$staging" && "$godot_bin" --headless -s "$linux_dir/render_icon.gd" -- \
|
||||
"$project_dir/icon.svg" "$package_dir/music-player-randomizer.png" 256)
|
||||
|
||||
archive="$out_dir/MusicPlayer_${version}_linux.tar.gz"
|
||||
tar -czf "$archive" -C "$staging" MusicPlayer
|
||||
echo "Created $archive"
|
||||
@@ -0,0 +1,24 @@
|
||||
extends SceneTree
|
||||
## Renders an SVG to a square PNG, used to package the icon for Linux.
|
||||
##
|
||||
## Usage: godot --headless -s render_icon.gd -- <input.svg> <output.png> <size>
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var args: PackedStringArray = OS.get_cmdline_user_args()
|
||||
if args.size() != 3:
|
||||
printerr("Usage: godot --headless -s render_icon.gd -- <input.svg> <output.png> <size>")
|
||||
quit(1)
|
||||
return
|
||||
var svg: String = FileAccess.get_file_as_string(args[0])
|
||||
var source: Image = Image.new()
|
||||
# Load at 1x to read the SVG's own size, then scale so the result is <size> pixels
|
||||
var error: int = source.load_svg_from_string(svg)
|
||||
if error == OK:
|
||||
var image: Image = Image.new()
|
||||
error = image.load_svg_from_string(svg, float(args[2]) / source.get_width())
|
||||
if error == OK:
|
||||
error = image.save_png(args[1])
|
||||
if error != OK:
|
||||
printerr("Could not render %s to %s (error %d)" % [args[0], args[1], error])
|
||||
quit(error)
|
||||
@@ -0,0 +1 @@
|
||||
uid://b51oybupn7ns7
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
class_name ListRow
|
||||
extends PanelContainer
|
||||
## One item in a list of names, such as the inspiration list or a sync result column.
|
||||
##
|
||||
## Every row has its own background, alternating between two shades, so it is clear
|
||||
## where an item starts even when its text wraps over several lines.
|
||||
|
||||
const EVEN_BACKGROUND: Color = Color(1, 1, 1, 0.05)
|
||||
const ODD_BACKGROUND: Color = Color(1, 1, 1, 0.11)
|
||||
|
||||
static var _even_style: StyleBoxFlat
|
||||
static var _odd_style: StyleBoxFlat
|
||||
|
||||
## The label showing the item's text.
|
||||
var label: Label
|
||||
|
||||
## The item's text.
|
||||
var text: String:
|
||||
get:
|
||||
return label.text
|
||||
|
||||
|
||||
## Creates the row for item number [param row] (counting from 0) in a list.
|
||||
static func create(
|
||||
item_text: String,
|
||||
row: int,
|
||||
font_size: int,
|
||||
alignment: HorizontalAlignment = HORIZONTAL_ALIGNMENT_LEFT,
|
||||
) -> ListRow:
|
||||
var list_row: ListRow = ListRow.new()
|
||||
list_row.add_theme_stylebox_override("panel", _style(row % 2 != 0))
|
||||
list_row.label = Label.new()
|
||||
list_row.label.add_theme_font_size_override("font_size", font_size)
|
||||
list_row.label.text = item_text
|
||||
list_row.label.horizontal_alignment = alignment
|
||||
list_row.label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
list_row.add_child(list_row.label)
|
||||
return list_row
|
||||
|
||||
|
||||
# Rows share two styles instead of each creating its own
|
||||
static func _style(odd: bool) -> StyleBoxFlat:
|
||||
if _even_style == null:
|
||||
_even_style = _make_style(EVEN_BACKGROUND)
|
||||
_odd_style = _make_style(ODD_BACKGROUND)
|
||||
return _odd_style if odd else _even_style
|
||||
|
||||
|
||||
static func _make_style(background: Color) -> StyleBoxFlat:
|
||||
var style: StyleBoxFlat = StyleBoxFlat.new()
|
||||
style.bg_color = background
|
||||
style.set_corner_radius_all(4)
|
||||
style.content_margin_left = 8
|
||||
style.content_margin_right = 8
|
||||
style.content_margin_top = 2
|
||||
style.content_margin_bottom = 2
|
||||
return style
|
||||
@@ -0,0 +1 @@
|
||||
uid://c2o2qunso5n8l
|
||||
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var log_panel: Panel = %LogPanel
|
||||
@@ -11,19 +11,15 @@ var log_rows: Array
|
||||
func add_log_row(text: String) -> void:
|
||||
var log_row: String = get_time() + text
|
||||
log_rows.append(log_row)
|
||||
update_log()
|
||||
log_box.add_child(make_log_label(log_row))
|
||||
|
||||
func update_log() -> void:
|
||||
print("update_log")
|
||||
Settings.delete_children(log_box)
|
||||
for row: String in log_rows:
|
||||
func make_log_label(row: String) -> Label:
|
||||
var log_label: Label = Label.new()
|
||||
log_label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
|
||||
log_label.add_theme_font_size_override("font_size", 20)
|
||||
log_label.text = row
|
||||
log_label.autowrap_mode = TextServer.AUTOWRAP_WORD
|
||||
log_box.add_child(log_label)
|
||||
return log_label
|
||||
|
||||
func get_time() -> String:
|
||||
var dateTime: Dictionary = Time.get_datetime_dict_from_system()
|
||||
return "" + str(dateTime.hour) + ":" + str(dateTime.minute) + ":" + str(dateTime.second) + " "
|
||||
var time: Dictionary = Time.get_time_dict_from_system()
|
||||
return "%02d:%02d:%02d " % [time.hour, time.minute, time.second]
|
||||
+8
-33
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var character_panel: Panel = %CharacterPanel
|
||||
@@ -14,7 +14,6 @@ var close_timer: Timer = %CloseTimer
|
||||
|
||||
var can_select_character: bool = false
|
||||
|
||||
signal character_selected(file_name: String)
|
||||
signal new_new_character_selected(file_name: String)
|
||||
|
||||
var character: PackedScene = preload("res://character.tscn")
|
||||
@@ -22,10 +21,6 @@ var character: PackedScene = preload("res://character.tscn")
|
||||
func _ready() -> void:
|
||||
close_timer.timeout.connect(_on_close_timeout)
|
||||
|
||||
func select_character(file_name: String) -> void:
|
||||
print("select_character")
|
||||
character_selected.emit(file_name)
|
||||
|
||||
func _on_close_timeout() -> void:
|
||||
print("_on_close_timeout!")
|
||||
Settings.character_select_open = false
|
||||
@@ -51,40 +46,20 @@ func show_grid(player_name: String) -> void:
|
||||
print("show_grid")
|
||||
title_label.text = "Select character for " + player_name
|
||||
close_timer.stop()
|
||||
self.visible = true
|
||||
open()
|
||||
can_select_character = true
|
||||
Settings.character_select_open = true
|
||||
|
||||
func close() -> void:
|
||||
super()
|
||||
Settings.character_select_open = false
|
||||
|
||||
func _on_character_selected(texture: ImageTexture) -> void:
|
||||
print("_on_character_selected")
|
||||
# Not close(): character_select_open stays true until close_timer fires, so the click
|
||||
# that picked the character does not also select a song behind it
|
||||
self.visible = false
|
||||
if can_select_character:
|
||||
new_new_character_selected.emit(texture)
|
||||
close_timer.start()
|
||||
can_select_character = false
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if self.visible == true:
|
||||
if event is InputEventMouseButton && event.is_pressed():
|
||||
var evLocal: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), character_panel.size).has_point(evLocal.position):
|
||||
self.visible = false
|
||||
Settings.character_select_open = false
|
||||
|
||||
func load_characters_local() -> void:
|
||||
var characters: DirAccess = DirAccess.open("res://characters/")
|
||||
if characters:
|
||||
characters.list_dir_begin()
|
||||
var file_name: String = characters.get_next()
|
||||
while file_name != "":
|
||||
file_name = file_name.replace('.import', '') # <--- remove the .import
|
||||
if file_name.ends_with(".png"):
|
||||
var texture: Resource = load("res://characters/" + file_name)
|
||||
var texture_btn: TextureButton = TextureButton.new()
|
||||
character_grid.add_child(texture_btn)
|
||||
texture_btn.custom_minimum_size = Vector2(80, 40)
|
||||
texture_btn.ignore_texture_size = true
|
||||
texture_btn.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT
|
||||
texture_btn.texture_normal = texture
|
||||
texture_btn.pressed.connect(select_character.bind(file_name))
|
||||
file_name = characters.get_next()
|
||||
@@ -1,24 +1,27 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cdy4kvemwaiom"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cvffg87wr6r3y" path="res://new_character_select.gd" id="1_h4tdp"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_p4iny"]
|
||||
font_size = 25
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
[node name="Control" type="Control" node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
script = ExtResource("1_h4tdp")
|
||||
panel = NodePath("CharacterPanel")
|
||||
|
||||
[node name="CharacterPanel" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 1260.0
|
||||
offset_right = 1290.0
|
||||
offset_bottom = 665.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CharacterPanel"]
|
||||
layout_mode = 0
|
||||
offset_right = 1263.0
|
||||
offset_right = 1290.0
|
||||
offset_bottom = 659.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
|
||||
@@ -31,10 +31,6 @@ func get_preloaded_songs() -> int:
|
||||
func should_preload_more_songs() -> bool:
|
||||
return number_of_tracks_to_preload > get_preloaded_songs()
|
||||
|
||||
func set_last_played_answered() -> void:
|
||||
if song_object_array[latest_played_song].has_played && !song_object_array[latest_played_song].is_answered:
|
||||
song_object_array[latest_played_song].is_answered = true
|
||||
|
||||
func song_is_answered(song_no: int = currently_playing_song) -> void:
|
||||
# Nothing is playing yet (-1); a negative index would answer the last, unplayed song
|
||||
if song_no < 0 || song_no >= song_object_array.size():
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
[gd_resource type="Theme" format=3]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_popup"]
|
||||
bg_color = Color(0.180392, 0.180392, 0.180392, 1)
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color(0.36, 0.36, 0.36, 1)
|
||||
corner_radius_top_left = 6
|
||||
corner_radius_top_right = 6
|
||||
corner_radius_bottom_right = 6
|
||||
corner_radius_bottom_left = 6
|
||||
content_margin_left = 12.0
|
||||
content_margin_top = 12.0
|
||||
content_margin_right = 12.0
|
||||
content_margin_bottom = 12.0
|
||||
|
||||
[resource]
|
||||
Panel/styles/panel = SubResource("StyleBoxFlat_popup")
|
||||
PopupPanel/styles/panel = SubResource("StyleBoxFlat_popup")
|
||||
@@ -0,0 +1,37 @@
|
||||
class_name PopupWindow
|
||||
extends Control
|
||||
## A window shown on top of the main window, such as Settings or About.
|
||||
##
|
||||
## Clicking outside [member panel] closes it. Popups that need to prepare or clean up
|
||||
## override [method open] or [method close] and call [code]super()[/code].
|
||||
|
||||
## The visible part of the popup. Clicks outside it close the popup.
|
||||
@export var panel: Control
|
||||
|
||||
|
||||
## Shows the popup.
|
||||
func open() -> void:
|
||||
visible = true
|
||||
|
||||
|
||||
## Hides the popup.
|
||||
func close() -> void:
|
||||
visible = false
|
||||
|
||||
|
||||
## Opens the popup if it is closed and closes it if it is open.
|
||||
func toggle() -> void:
|
||||
if visible:
|
||||
close()
|
||||
else:
|
||||
open()
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if !visible || !(event is InputEventMouseButton) || !event.pressed:
|
||||
return
|
||||
var click: InputEventMouseButton = panel.make_input_local(event)
|
||||
if !Rect2(Vector2.ZERO, panel.size).has_point(click.position):
|
||||
close()
|
||||
# The click only closes the popup; it must not also press what is behind it
|
||||
get_viewport().set_input_as_handled()
|
||||
@@ -0,0 +1 @@
|
||||
uid://dwd4dcbujpv6p
|
||||
@@ -1,5 +0,0 @@
|
||||
class_name ProgressResponse
|
||||
extends Node
|
||||
|
||||
var progress: String
|
||||
var total_time: String
|
||||
@@ -1 +0,0 @@
|
||||
uid://e74iuu78stc3
|
||||
+4
-1
@@ -17,7 +17,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
||||
config/name="MusicPlayer"
|
||||
config/version="1.9.0"
|
||||
run/main_scene="res://MainWindow.tscn"
|
||||
config/features=PackedStringArray("4.7", "Forward Plus")
|
||||
config/features=PackedStringArray("4.7", "GL Compatibility")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[autoload]
|
||||
@@ -61,6 +61,9 @@ ui_select={
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
|
||||
textures/vram_compression/import_s3tc_bptc=true
|
||||
textures/vram_compression/import_etc2_astc=true
|
||||
textures/default_filters/use_nearest_mipmap_filter=true
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bd1by80q1v27e"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://rolypd0cqd6h" path="res://shortcuts_window.gd" id="1_12pxi"]
|
||||
[ext_resource type="Theme" path="res://popup_theme.tres" id="popup_theme"]
|
||||
|
||||
[node name="ShorcutsControl" type="Control"]
|
||||
[node name="ShorcutsControl" type="Control" node_paths=PackedStringArray("panel")]
|
||||
theme = ExtResource("popup_theme")
|
||||
custom_minimum_size = Vector2(700, 700)
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
@@ -11,6 +13,7 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_12pxi")
|
||||
panel = NodePath("ShortcutsPanel")
|
||||
|
||||
[node name="ShortcutsPanel" type="Panel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
+1
-14
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var shortcuts_vbox: VBoxContainer = %shortcutsVBox
|
||||
@@ -29,22 +29,11 @@ var shortcuts_dic: Dictionary = {
|
||||
#Color(0.302, 0.302, 0.302)
|
||||
#Color(0.259, 0.259, 0.259)
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if self.visible == true:
|
||||
if shortcuts_panel == null:
|
||||
return
|
||||
if event is InputEventMouseButton && event.is_pressed():
|
||||
var evLocal: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), shortcuts_panel.size).has_point(evLocal.position):
|
||||
self.visible = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
shortcuts_dic.sort()
|
||||
Settings.delete_children(shortcuts_vbox)
|
||||
|
||||
var title: Label = Label.new()
|
||||
title.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
|
||||
title.add_theme_font_size_override("font_size", 20)
|
||||
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
title.text = "Shortcuts"
|
||||
@@ -57,7 +46,6 @@ func _ready() -> void:
|
||||
hbox.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
|
||||
var label: Label = Label.new()
|
||||
label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
|
||||
label.add_theme_font_size_override("font_size", 20)
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
label.text = shortcut
|
||||
@@ -65,7 +53,6 @@ func _ready() -> void:
|
||||
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
|
||||
var label2: Label = Label.new()
|
||||
label2.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
|
||||
label2.add_theme_font_size_override("font_size", 20)
|
||||
label2.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
label2.text = shortcuts_dic[shortcut]
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
class_name SyncResponse
|
||||
extends Node
|
||||
|
||||
var soundtracks_added: Array
|
||||
var soundtracks_re_added: Array
|
||||
var soundtracks_changed_title: Array
|
||||
var soundtracks_changed_content: Array
|
||||
var soundtracks_removed: Array
|
||||
var catched_errors: Array
|
||||
var total_time: String
|
||||
@@ -1 +0,0 @@
|
||||
uid://dtfsuob2aidl7
|
||||
+15
-39
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var sync_panel: Panel = %SyncPanel
|
||||
@@ -60,9 +60,6 @@ var sync_timer: Timer = %SyncTimer
|
||||
@onready
|
||||
var restart_sync_button: Button = %RestartSyncButton
|
||||
|
||||
@onready
|
||||
var first_separator: VSeparator = %VSeparator6
|
||||
|
||||
var changes: bool = false
|
||||
|
||||
var has_synced: bool = false
|
||||
@@ -75,13 +72,6 @@ func _ready() -> void:
|
||||
restart_sync_button.pressed.connect(start_sync)
|
||||
restart_sync_button.visible = false
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if self.visible == true:
|
||||
if event is InputEventMouseButton && event.is_pressed():
|
||||
var evLocal: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), sync_panel.size).has_point(evLocal.position):
|
||||
self.visible = false
|
||||
|
||||
func show_section_if_has_data(data: Variant, vbox: VBoxContainer, separator: VSeparator, header_text: String) -> bool:
|
||||
if data != null && data.size() > 0:
|
||||
vbox.visible = true
|
||||
@@ -127,7 +117,7 @@ func on_sync_finished(data_received: Dictionary) -> void:
|
||||
if show_section_if_has_data(data_received.soundtracks_added, soundtracks_added_vbox, soundtracks_added_separator, "Added"):
|
||||
changes = true
|
||||
|
||||
if show_section_if_has_data(data_received.soundtracks_re_added, soundtracks_readded_vbox, soundtracks_readded_separator, "ReAdded"):
|
||||
if show_section_if_has_data(data_received.soundtracks_re_added, soundtracks_readded_vbox, soundtracks_readded_separator, "Re-added"):
|
||||
changes = true
|
||||
|
||||
if data_received.soundtracks_changed_title != null && data_received.soundtracks_changed_title.size() > 0:
|
||||
@@ -136,10 +126,9 @@ func on_sync_finished(data_received: Dictionary) -> void:
|
||||
make_header_label(soundtracks_changed_title_vbox, "Changed Title")
|
||||
var row: int = 0
|
||||
for old_soundtrack_title: String in data_received.soundtracks_changed_title:
|
||||
var label: Label = make_soundtrack_label(old_soundtrack_title + "\nchanged title to\n" + data_received.soundtracks_changed_title[old_soundtrack_title])
|
||||
if row % 2 != 0:
|
||||
label.add_theme_color_override("font_color", Color(1, 0.5, 0))
|
||||
soundtracks_changed_title_vbox.add_child(label)
|
||||
var new_soundtrack_title: String = data_received.soundtracks_changed_title[old_soundtrack_title]
|
||||
soundtracks_changed_title_vbox.add_child(make_soundtrack_row(
|
||||
old_soundtrack_title + "\nchanged title to\n" + new_soundtrack_title, row))
|
||||
row += 1
|
||||
soundtracks_changed_title_vbox.visible = true
|
||||
|
||||
@@ -151,11 +140,9 @@ func on_sync_finished(data_received: Dictionary) -> void:
|
||||
|
||||
if data_received.catched_errors != null && data_received.catched_errors.size() > 0:
|
||||
catched_errors_vbox.visible = true
|
||||
make_list(data_received.catched_errors, catched_errors_vbox, "CatchedErrors")
|
||||
make_list(data_received.catched_errors, catched_errors_vbox, "Errors")
|
||||
|
||||
# Hide separators that don't have a visible section after them
|
||||
# The structure is: RestartSyncButton -> VSeparator6 -> VBox -> Separator -> VBox -> Separator -> ...
|
||||
# Hide VSeparator6 if there are no visible sections
|
||||
# Separators go only between visible columns, not after the last one
|
||||
var visible_sections: Array = []
|
||||
if soundtracks_added_vbox.visible:
|
||||
visible_sections.append("added")
|
||||
@@ -168,8 +155,6 @@ func on_sync_finished(data_received: Dictionary) -> void:
|
||||
if soundtracks_removed_vbox.visible:
|
||||
visible_sections.append("removed")
|
||||
|
||||
first_separator.visible = visible_sections.size() > 1
|
||||
|
||||
# Show section separators only if there's a visible section after them
|
||||
for i in range(visible_sections.size()):
|
||||
var section = visible_sections[i]
|
||||
@@ -202,20 +187,18 @@ func list_visible(vbox: VBoxContainer, seperator: VSeparator) -> void:
|
||||
|
||||
func make_header_label(vbox: VBoxContainer, text: String) -> void:
|
||||
var label: Label = Label.new()
|
||||
label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
|
||||
label.add_theme_font_size_override("font_size", 20)
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
label.add_theme_color_override("font_color", Color(1, 0.5, 0))
|
||||
label.text = text
|
||||
vbox.add_child(label)
|
||||
|
||||
func make_soundtrack_label(text: String) -> Label:
|
||||
var label: Label = Label.new()
|
||||
label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
|
||||
label.add_theme_font_size_override("font_size", 18)
|
||||
label.text = text
|
||||
label.autowrap_mode = TextServer.AUTOWRAP_OFF
|
||||
return label
|
||||
# Items alternate between white and orange text as well as background shade
|
||||
func make_soundtrack_row(text: String, row: int) -> ListRow:
|
||||
var list_row: ListRow = ListRow.create(text, row, 18, HORIZONTAL_ALIGNMENT_CENTER)
|
||||
if row % 2 != 0:
|
||||
list_row.label.add_theme_color_override("font_color", Color(1, 0.5, 0))
|
||||
return list_row
|
||||
|
||||
func reset_sync_result() -> void:
|
||||
sync_progress_bar.value = 0
|
||||
@@ -233,18 +216,12 @@ func reset_sync_result() -> void:
|
||||
soundtracks_removed_vbox.visible = false
|
||||
soundtracks_removed_separator.visible = false
|
||||
catched_errors_vbox.visible = false
|
||||
first_separator.visible = false
|
||||
|
||||
func make_list(list: Array, vbox: VBoxContainer, text: String) -> void:
|
||||
Settings.delete_children(vbox)
|
||||
make_header_label(vbox, text)
|
||||
var row: int = 0
|
||||
for soundtrack: String in list:
|
||||
var label: Label = make_soundtrack_label(soundtrack)
|
||||
if row % 2 != 0:
|
||||
label.add_theme_color_override("font_color", Color(1, 0.5, 0))
|
||||
vbox.add_child(label)
|
||||
row += 1
|
||||
for row: int in list.size():
|
||||
vbox.add_child(make_soundtrack_row(list[row], row))
|
||||
|
||||
func show_sync_result() -> void:
|
||||
sync_title_label.text = "Sync Result"
|
||||
@@ -259,4 +236,3 @@ func show_sync_progress() -> void:
|
||||
sync_hbox.visible = false
|
||||
catched_errors_vbox.visible = false
|
||||
restart_sync_button.visible = false
|
||||
first_separator.visible = false
|
||||
@@ -13,6 +13,7 @@ var requested_methods: Array[int] = []
|
||||
|
||||
var _responses: Dictionary = {}
|
||||
var _successes_left: Dictionary = {}
|
||||
var _held_paths: Dictionary = {}
|
||||
var _previous_transport: HttpTransport
|
||||
|
||||
|
||||
@@ -49,6 +50,20 @@ func fail_after(path: String, successes: int) -> void:
|
||||
_successes_left[path] = successes
|
||||
|
||||
|
||||
## Holds back responses to [param path] until [method release] is called, like a slow
|
||||
## server.
|
||||
func hold(path: String) -> void:
|
||||
_held_paths[path] = []
|
||||
|
||||
|
||||
## Delivers the responses held back for [param path] and stops holding it.
|
||||
func release(path: String) -> void:
|
||||
var waiting: Array = _held_paths.get(path, [])
|
||||
_held_paths.erase(path)
|
||||
for pending: Callable in waiting:
|
||||
pending.call()
|
||||
|
||||
|
||||
## Returns how many times [param path] has been requested.
|
||||
func count(path: String) -> int:
|
||||
return requested_paths.count(path)
|
||||
@@ -58,6 +73,13 @@ func request(url: String, method: int, on_complete: Callable) -> void:
|
||||
var path: String = url.trim_prefix(Settings.default_path)
|
||||
requested_paths.append(path)
|
||||
requested_methods.append(method)
|
||||
if _held_paths.has(path):
|
||||
_held_paths[path].append(_answer.bind(path, on_complete))
|
||||
return
|
||||
_answer(path, on_complete)
|
||||
|
||||
|
||||
func _answer(path: String, on_complete: Callable) -> void:
|
||||
if _successes_left.has(path):
|
||||
if _successes_left[path] == 0:
|
||||
on_complete.call(503, PackedByteArray())
|
||||
|
||||
@@ -36,12 +36,19 @@ func before_test() -> void:
|
||||
_server.respond_bytes("/music/reset", PackedByteArray())
|
||||
_server.respond_bytes("/music/played?song=0", PackedByteArray())
|
||||
|
||||
_before_window_starts()
|
||||
_runner = scene_runner("res://MainWindow.tscn")
|
||||
_window = _runner.scene()
|
||||
# The debug build lowers the winning score on startup; keep it out of reach
|
||||
Settings.winning_score = 20
|
||||
|
||||
|
||||
## Override to change the fake server before the window starts and sends its first
|
||||
## requests.
|
||||
func _before_window_starts() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func after_test() -> void:
|
||||
# Let nodes queued for deletion by the window be freed before orphans are counted
|
||||
await await_idle_frame()
|
||||
|
||||
@@ -226,3 +226,26 @@ func test_show_answer_before_first_song_does_not_reveal_next_song() -> void:
|
||||
|
||||
assert_str((_window.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 crono: PlayerObject = _add_player("Crono")
|
||||
await _play_first_song()
|
||||
|
||||
crono.add_point()
|
||||
crono.minus_point()
|
||||
|
||||
assert_int(log_box.get_child_count()).is_equal(2)
|
||||
var time_pattern: RegEx = RegEx.create_from_string("^\\d\\d:\\d\\d:\\d\\d Crono got a point$")
|
||||
assert_object(time_pattern.search((log_box.get_child(0) as Label).text)).is_not_null()
|
||||
assert_str((log_box.get_child(1) as Label).text).ends_with("Crono lost a point")
|
||||
|
||||
|
||||
func test_inspiration_list_alternates_row_backgrounds() -> void:
|
||||
var rows: Array[Node] = _window.get_node("ScrollContainer/VBoxContainer").get_children()
|
||||
|
||||
assert_int(rows.size()).is_equal(2)
|
||||
assert_str((rows[0] as ListRow).text).is_equal("Chrono Trigger")
|
||||
assert_that((rows[0] as ListRow).get_theme_stylebox("panel")) \
|
||||
.is_not_equal((rows[1] as ListRow).get_theme_stylebox("panel"))
|
||||
@@ -0,0 +1,41 @@
|
||||
extends MainWindowTestSuite
|
||||
## Startup with a slow /music/list response.
|
||||
|
||||
|
||||
func _before_window_starts() -> void:
|
||||
_server.respond_json("/music/list", [
|
||||
{"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"},
|
||||
])
|
||||
_next_song_is({"SongNo": 1, "Soundtrack": "Final Fantasy VI", "Song": "Dancing Mad"})
|
||||
_server.hold("/music/list")
|
||||
|
||||
|
||||
func test_preloaded_song_survives_a_slow_song_list() -> void:
|
||||
_server.release("/music/list")
|
||||
|
||||
# The song already on the server, then the preloaded one
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(2)
|
||||
assert_str(Playlist.song_object_array[1].song_title).is_equal("Dancing Mad")
|
||||
assert_int(Playlist.get_preloaded_songs()).is_equal(1)
|
||||
|
||||
|
||||
func test_next_plays_the_preloaded_song_after_a_slow_song_list() -> void:
|
||||
_server.release("/music/list")
|
||||
|
||||
await _play_first_song()
|
||||
|
||||
assert_int(Playlist.currently_playing_song).is_equal(1)
|
||||
|
||||
|
||||
func test_failed_song_list_is_retried_before_preloading() -> void:
|
||||
_window.song_fetch_retry_seconds = 0.05
|
||||
_server.respond_json("/music/list", [], 503)
|
||||
_server.release("/music/list")
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(0)
|
||||
|
||||
_server.respond_json("/music/list", [])
|
||||
await await_millis(200)
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(1)
|
||||
assert_int(Playlist.get_preloaded_songs()).is_equal(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://sfwrqidmuj04
|
||||
@@ -0,0 +1,126 @@
|
||||
extends MainWindowTestSuite
|
||||
## All popups share PopupWindow: clicking outside the panel closes them, the backdrop
|
||||
## dims the window behind them, and the closing click does not reach the main window.
|
||||
|
||||
const POPUP_NODES: Array[String] = [
|
||||
"Search", "SyncWindow", "SettingsWindow", "QRWindow", "NewCharacterSelect",
|
||||
"ShortcutsWindow", "AboutWindow", "WinnerWindow", "Log",
|
||||
]
|
||||
|
||||
|
||||
func _popup(node_name: String) -> PopupWindow:
|
||||
return _window.get_node(node_name)
|
||||
|
||||
|
||||
func _backdrop() -> ColorRect:
|
||||
return _window.get_node("PopupBackdrop")
|
||||
|
||||
|
||||
## Clicks at [param position], given in the window's 1920x1080 layout coordinates.
|
||||
func _click_at(position: Vector2) -> void:
|
||||
# The runner takes window pixels; the headless test window is much smaller than the
|
||||
# layout, so convert like a real mouse position would be
|
||||
_runner.set_mouse_position(_window.get_viewport().get_final_transform() * position)
|
||||
await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
## A point on screen outside the popup's panel.
|
||||
func _outside(popup: PopupWindow) -> Vector2:
|
||||
var rect: Rect2 = popup.panel.get_global_rect()
|
||||
return Vector2(rect.end.x + 5, rect.end.y + 5) if rect.end.x < 1900 \
|
||||
else Vector2(rect.position.x - 5, rect.position.y - 5)
|
||||
|
||||
|
||||
func test_backdrop_is_hidden_without_popups() -> void:
|
||||
assert_bool(_backdrop().visible).is_false()
|
||||
|
||||
|
||||
func test_backdrop_covers_the_whole_window() -> void:
|
||||
_popup("SettingsWindow").open()
|
||||
|
||||
assert_vector(_backdrop().get_global_rect().size).is_equal(_window.get_viewport_rect().size)
|
||||
|
||||
|
||||
func test_every_popup_is_a_popup_window() -> void:
|
||||
for node_name: String in POPUP_NODES:
|
||||
assert_object(_window.get_node(node_name)).is_instanceof(PopupWindow)
|
||||
|
||||
|
||||
func test_every_popup_shows_backdrop_and_closes_on_outside_click() -> void:
|
||||
for node_name: String in POPUP_NODES:
|
||||
var popup: PopupWindow = _popup(node_name)
|
||||
popup.open()
|
||||
await _runner.simulate_frames(1)
|
||||
assert_bool(_backdrop().visible).override_failure_message(
|
||||
"%s: backdrop not shown" % node_name).is_true()
|
||||
|
||||
await _click_at(_outside(popup))
|
||||
|
||||
assert_bool(popup.visible).override_failure_message(
|
||||
"%s: not closed by outside click" % node_name).is_false()
|
||||
assert_bool(_backdrop().visible).override_failure_message(
|
||||
"%s: backdrop still shown" % node_name).is_false()
|
||||
|
||||
|
||||
func test_click_inside_popup_keeps_it_open() -> void:
|
||||
var settings: PopupWindow = _popup("SettingsWindow")
|
||||
settings.open()
|
||||
await _runner.simulate_frames(1)
|
||||
|
||||
await _click_at(settings.panel.get_global_rect().get_center())
|
||||
|
||||
assert_bool(settings.visible).is_true()
|
||||
|
||||
|
||||
func test_closing_click_does_not_press_button_behind_popup() -> void:
|
||||
var settings: PopupWindow = _popup("SettingsWindow")
|
||||
var reset_button: Button = _window.get_node("ResetPlaylistButton")
|
||||
settings.open()
|
||||
await _runner.simulate_frames(1)
|
||||
assert_bool(settings.panel.get_global_rect().intersects(reset_button.get_global_rect())) \
|
||||
.is_false()
|
||||
|
||||
await _click_at(reset_button.get_global_rect().get_center())
|
||||
|
||||
assert_bool(settings.visible).is_false()
|
||||
assert_int(_server.count("/music/reset")).is_equal(0)
|
||||
|
||||
|
||||
func test_button_works_again_after_popup_closed() -> void:
|
||||
var reset_button: Button = _window.get_node("ResetPlaylistButton")
|
||||
|
||||
await _click_at(reset_button.get_global_rect().get_center())
|
||||
|
||||
assert_int(_server.count("/music/reset")).is_equal(1)
|
||||
|
||||
|
||||
func test_closing_search_clears_the_search() -> void:
|
||||
var search: PopupWindow = _popup("Search")
|
||||
search.open()
|
||||
var search_bar: TextEdit = search.get_node("Searchbar")
|
||||
search_bar.text = "mario"
|
||||
|
||||
search.close()
|
||||
|
||||
assert_str(search_bar.text).is_empty()
|
||||
|
||||
|
||||
func test_closing_character_select_allows_song_clicks_again() -> void:
|
||||
var character_select: PopupWindow = _popup("NewCharacterSelect")
|
||||
character_select.show_grid("Crono")
|
||||
assert_bool(Settings.character_select_open).is_true()
|
||||
|
||||
character_select.close()
|
||||
|
||||
assert_bool(Settings.character_select_open).is_false()
|
||||
|
||||
|
||||
func test_toggle_opens_and_closes() -> void:
|
||||
var shortcuts: PopupWindow = _popup("ShortcutsWindow")
|
||||
|
||||
shortcuts.toggle()
|
||||
assert_bool(shortcuts.visible).is_true()
|
||||
|
||||
shortcuts.toggle()
|
||||
assert_bool(shortcuts.visible).is_false()
|
||||
@@ -0,0 +1 @@
|
||||
uid://kcnjdw4ke7hd
|
||||
@@ -0,0 +1,65 @@
|
||||
extends MainWindowTestSuite
|
||||
## Winning turns statistics off until a new game starts.
|
||||
|
||||
var _crono: PlayerObject
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
super()
|
||||
_crono = _add_player("Crono")
|
||||
await _play_first_song()
|
||||
Settings.winning_score = 1
|
||||
|
||||
|
||||
func _stats_checkbox() -> CheckButton:
|
||||
return _window.get_node("SettingsWindow").get_node("%AddToDatabaseCheckButton")
|
||||
|
||||
|
||||
func test_winning_turns_statistics_off() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
assert_bool(Settings.add_to_stats).is_false()
|
||||
|
||||
|
||||
func test_resetting_points_turns_statistics_back_on() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("ResetPointsButton")
|
||||
|
||||
assert_bool(Settings.add_to_stats).is_true()
|
||||
|
||||
|
||||
func test_statistics_turned_off_by_hand_stay_off_after_reset() -> void:
|
||||
Settings.add_to_stats = false
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("ResetPointsButton")
|
||||
|
||||
assert_bool(Settings.add_to_stats).is_false()
|
||||
|
||||
|
||||
func test_settings_checkbox_shows_statistics_off_after_win() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("SettingsButton")
|
||||
|
||||
assert_bool(_stats_checkbox().button_pressed).is_false()
|
||||
|
||||
|
||||
func test_songs_after_a_win_are_not_counted() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
var played_before: int = _server.count("/music/played?song=0")
|
||||
|
||||
_press("ShowAnswerButton")
|
||||
|
||||
assert_int(_server.count("/music/played?song=0")).is_equal(played_before)
|
||||
|
||||
|
||||
func test_winning_score_cannot_go_below_one() -> void:
|
||||
_press("SettingsButton")
|
||||
var lower_button: Button = _window.get_node("SettingsWindow").get_node("%LowerButton")
|
||||
|
||||
for i: int in 3:
|
||||
lower_button.pressed.emit()
|
||||
|
||||
assert_int(Settings.winning_score).is_equal(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://d20y2gtespbou
|
||||
@@ -113,7 +113,7 @@ func test_changed_titles_list_old_and_new_title() -> void:
|
||||
|
||||
var vbox: Control = _node("SoundtracksChangedTitleVBox")
|
||||
assert_bool(vbox.visible).is_true()
|
||||
assert_str((vbox.get_child(1) as Label).text).is_equal(
|
||||
assert_str((vbox.get_child(1) as ListRow).text).is_equal(
|
||||
"FF7\nchanged title to\nFinal Fantasy VII")
|
||||
|
||||
|
||||
@@ -143,3 +143,58 @@ func test_reopening_after_sync_shows_result_without_syncing_again() -> void:
|
||||
|
||||
assert_int(_server.count("/sync")).is_equal(1)
|
||||
assert_str(_node("SyncTitleLabel").text).is_equal("Sync Result")
|
||||
|
||||
|
||||
func test_errors_section_has_errors_header() -> void:
|
||||
_runner.invoke("start_sync")
|
||||
var result: Dictionary = _empty_result()
|
||||
result.catched_errors = ["Could not read tags in broken.mp3"]
|
||||
|
||||
_finish_sync(result)
|
||||
|
||||
assert_str((_node("CatchedErrorsVBox").get_child(0) as Label).text).is_equal("Errors")
|
||||
|
||||
|
||||
func test_long_names_wrap_instead_of_widening_the_window() -> void:
|
||||
_runner.invoke("start_sync")
|
||||
var long_name: String = "The Legend of Zelda: Breath of the Wild Original Soundtrack"
|
||||
var result: Dictionary = _empty_result()
|
||||
result.soundtracks_added = [long_name]
|
||||
result.soundtracks_re_added = [long_name]
|
||||
result.soundtracks_changed_content = [long_name]
|
||||
result.soundtracks_removed = [long_name]
|
||||
result.soundtracks_changed_title = {long_name: long_name}
|
||||
result.catched_errors = [long_name + " could not be read"]
|
||||
|
||||
_finish_sync(result)
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
# The minimum width is what the content needs; wider than the panel it would stick out
|
||||
var panel_width: float = (_window.get_node("SyncPanel") as Control).size.x
|
||||
assert_float(_node("SyncHBoxContainer").get_combined_minimum_size().x) \
|
||||
.is_less(panel_width)
|
||||
assert_float(_node("CatchedErrorsVBox").get_combined_minimum_size().x) \
|
||||
.is_less(panel_width)
|
||||
|
||||
|
||||
func test_visible_columns_share_the_width_equally() -> void:
|
||||
_runner.invoke("start_sync")
|
||||
var result: Dictionary = _empty_result()
|
||||
result.soundtracks_added = ["Chrono Cross", "Xenoblade Chronicles X Original Soundtrack"]
|
||||
result.soundtracks_removed = ["Bad Rip"]
|
||||
|
||||
_finish_sync(result)
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
assert_float(_node("SoundtracksAddedVBox").size.x).is_equal_approx(
|
||||
_node("SoundtracksRemovedVBox").size.x, 1.0)
|
||||
|
||||
|
||||
func test_column_headers() -> void:
|
||||
_runner.invoke("start_sync")
|
||||
var result: Dictionary = _empty_result()
|
||||
result.soundtracks_re_added = ["Super Metroid"]
|
||||
|
||||
_finish_sync(result)
|
||||
|
||||
assert_str((_node("SoundtracksReAddedVBox").get_child(0) as Label).text).is_equal("Re-added")
|
||||
@@ -0,0 +1,26 @@
|
||||
extends GdUnitTestSuite
|
||||
|
||||
|
||||
func _background(list_row: ListRow) -> Color:
|
||||
return (list_row.get_theme_stylebox("panel") as StyleBoxFlat).bg_color
|
||||
|
||||
|
||||
func test_row_shows_text() -> void:
|
||||
var list_row: ListRow = auto_free(ListRow.create("Chrono Trigger", 0, 20))
|
||||
|
||||
assert_str(list_row.text).is_equal("Chrono Trigger")
|
||||
|
||||
|
||||
func test_neighbouring_rows_have_different_backgrounds() -> void:
|
||||
var first: ListRow = auto_free(ListRow.create("Chrono Trigger", 0, 20))
|
||||
var second: ListRow = auto_free(ListRow.create("Chrono Cross", 1, 20))
|
||||
var third: ListRow = auto_free(ListRow.create("Xenogears", 2, 20))
|
||||
|
||||
assert_that(_background(first)).is_not_equal(_background(second))
|
||||
assert_that(_background(first)).is_equal(_background(third))
|
||||
|
||||
|
||||
func test_long_text_wraps() -> void:
|
||||
var list_row: ListRow = auto_free(ListRow.create("Castlevania: Symphony of the Night", 0, 20))
|
||||
|
||||
assert_int(list_row.label.autowrap_mode).is_equal(TextServer.AUTOWRAP_WORD_SMART)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bouligcywd5se
|
||||
@@ -117,3 +117,22 @@ func test_every_player_gets_a_different_id() -> void:
|
||||
ids[PlayerObject.new("Player %d" % i).id] = true
|
||||
|
||||
assert_int(ids.size()).is_equal(100)
|
||||
|
||||
|
||||
func test_winning_score_of_one_is_won_with_first_point() -> void:
|
||||
Settings.winning_score = 1
|
||||
monitor_signals(_player, false)
|
||||
|
||||
_player.add_point()
|
||||
|
||||
await assert_signal(_player).is_emitted("winner_triggerd")
|
||||
|
||||
|
||||
func test_first_point_is_match_point_when_winning_score_is_two() -> void:
|
||||
Settings.winning_score = 2
|
||||
monitor_signals(_player, false)
|
||||
|
||||
_player.add_point()
|
||||
|
||||
await assert_signal(_player).is_emitted("match_point_triggerd")
|
||||
assert_bool(_player.is_first_point).is_false()
|
||||
+6
-10
@@ -1,4 +1,4 @@
|
||||
extends Control
|
||||
extends PopupWindow
|
||||
|
||||
@onready
|
||||
var winner_panel: Panel = %WinnerPanel
|
||||
@@ -23,6 +23,11 @@ func show_winner(winner: PlayerObject) -> void:
|
||||
winner_label.text = winner.player_name + " won with " + str(winner.player_score) + \
|
||||
" points!!"
|
||||
winner_picture.texture = winner.character
|
||||
# The "no character" placeholder is pixel art, which blurs when scaled up smoothly
|
||||
if winner.character.resource_path == PlayerObject.NO_CHARACTER_PATH:
|
||||
winner_picture.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
else:
|
||||
winner_picture.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
|
||||
winner_picture.custom_minimum_size = Vector2(480, 200)
|
||||
winner_picture.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
|
||||
winner_picture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
@@ -50,13 +55,4 @@ func show_winner(winner: PlayerObject) -> void:
|
||||
placing += 1
|
||||
|
||||
|
||||
func hide_window() -> void:
|
||||
visible = false
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if visible:
|
||||
if event is InputEventMouseButton and event.is_pressed():
|
||||
var ev_local: InputEvent = make_input_local(event)
|
||||
if !Rect2(Vector2(0, 0), winner_panel.size).has_point(ev_local.position):
|
||||
visible = false
|
||||
Reference in new issue
Block a user