diff --git a/.gitea/workflows/gitea-build.yaml b/.gitea/workflows/gitea-build.yaml index 4279ea6..3c512e0 100644 --- a/.gitea/workflows/gitea-build.yaml +++ b/.gitea/workflows/gitea-build.yaml @@ -9,7 +9,7 @@ on: branches: [main, develop] env: - GODOT_VERSION: 4.6 + GODOT_VERSION: 4.7 PROJECT_PATH: . EXPORT_NAME: MusicPlayer diff --git a/.gitea/workflows/gitea-release.yaml b/.gitea/workflows/gitea-release.yaml index f32d5d2..084ea63 100644 --- a/.gitea/workflows/gitea-release.yaml +++ b/.gitea/workflows/gitea-release.yaml @@ -10,7 +10,7 @@ on: - '*.*' env: - GODOT_VERSION: 4.6 + GODOT_VERSION: 4.7 PROJECT_PATH: . PROJECT_NAME: MusicPlayer GAME_VERSION: ${{gitea.ref_name}} diff --git a/AboutWindow.gd b/AboutWindow.gd index 909de14..ef74e11 100644 --- a/AboutWindow.gd +++ b/AboutWindow.gd @@ -13,7 +13,12 @@ var whats_new_label: Label = %WhatsNewLabel # Changelog as Dictionary with version as key and description as value const WHATS_NEW: Dictionary = { - "1.x.x": "#34: Fixed bug in Character Select when clicking or scrolling", + "1.9.0": "Made improvements to the Search window + Made small changes to the inspiration list scrolling + Made small changes to the player list + Changed the term game to soundtrack + #28: Made changes to the sync window + #34: Fixed bug in Character Select when clicking or scrolling", "1.8.5": "#9: New winner screen with positions of all players #32: New setting for how long to hide the beginning #33: Fixed bug with hiding beginning when song restarts", diff --git a/InsperationScrollContainer.gd b/InsperationScrollContainer.gd index d3d43b0..aa83b8b 100644 --- a/InsperationScrollContainer.gd +++ b/InsperationScrollContainer.gd @@ -1,34 +1,38 @@ extends ScrollContainer -var SCROLL: float = 0 -var delay: float = 0.02 #seconds -var wait: float = 0 +# Scroll direction: 1 = down, -1 = up +var scroll_direction: int = 1 # Called when the node enters the scene tree for the first time. func _ready() -> void: - wait = delay + scroll_direction = 1 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: - wait -= delta - if wait < 0: - wait = delay - #SCROLL DOWN - if SCROLL == 1: - if (scroll_vertical + get_v_scroll_bar().page) < get_v_scroll_bar().max_value: - scroll_vertical += Settings.inspiration_list_speed - else: - scroll_back_up() - #SCROLL UP - elif SCROLL == -1: - if scroll_vertical != 0: - scroll_vertical -= Settings.inspiration_list_speed - else: - scroll_to_bottom() + var speed_pixels_per_second: float = float(Settings.inspiration_list_speed) * 60.0 + var scroll_amount: float = speed_pixels_per_second * delta * float(scroll_direction) + + var scroll_bar = get_v_scroll_bar() + + # Don't scroll if list is empty or too short + if scroll_bar.max_value <= 0: + return -func scroll_back_up() -> void: - SCROLL = -1 + var current_pos = scroll_bar.value -func scroll_to_bottom() -> void: - scroll_vertical = 0 #Reset to top first. - SCROLL = 1 + if scroll_direction == 1: + # Scrolling down + if current_pos + scroll_bar.page < scroll_bar.max_value: + scroll_bar.value = min(current_pos + scroll_amount, scroll_bar.max_value - scroll_bar.page) + else: + # Reached bottom, reverse direction + scroll_direction = -1 + scroll_bar.value = scroll_bar.max_value - scroll_bar.page + else: + # Scrolling up + if current_pos > 0: + scroll_bar.value = max(current_pos + scroll_amount, 0) + else: + # Reached top, reverse direction + scroll_direction = 1 + scroll_bar.value = 0 diff --git a/MainWindow.gd b/MainWindow.gd index fcc7216..e5a53d0 100644 --- a/MainWindow.gd +++ b/MainWindow.gd @@ -23,7 +23,7 @@ var inspiration_scroll: ScrollContainer = $ScrollContainer var inspiration_list: VBoxContainer = $ScrollContainer/VBoxContainer @onready -var game_label: Label = $VBoxContainer/GameLabel +var soundtrack_label: Label = $VBoxContainer/SoundtrackLabel @onready var song_label: Label = $VBoxContainer/SongLabel @@ -106,6 +106,9 @@ var music_list: VBoxContainer = $MusicListPanel/ScrollContainer/MusicList @onready var player_container: VBoxContainer = $Players/VBoxContainer +@onready +var players_list_container: VBoxContainer = $Players/VBoxContainer/ScrollContainer/PlayersListVBoxContainer + @onready var character_select: Control = $CharacterSelect @@ -134,7 +137,7 @@ var player: PackedScene = preload("res://Player.tscn") var song_list_object: PackedScene = preload("res://song_list_object.tscn") var songs: Array= [] -var games: Array = [] +var soundtracks: Array = [] var current_player: Node # Called when the node enters the scene tree for the first time. @@ -152,7 +155,7 @@ func _ready() -> void: next_button.pressed.connect(play_next_song) show_answer_button.pressed.connect(show_answer_pressed) search_button.pressed.connect(show_search) - sync_button.pressed.connect(sync_games) + sync_button.pressed.connect(sync_soundtracks) sound_test_button.pressed.connect(music_player_container.get_sound_test_song) statistics_button.pressed.connect(get_statistics) shortcuts_button.pressed.connect(show_shortcuts) @@ -180,7 +183,7 @@ func _ready() -> void: get_suggestion_list() fetch_song_list_at_start() fetch_song() - search_view.get_list_of_games() + search_view.get_list_of_soundtracks() new_character_select.load_characters() func _input(event: InputEvent) -> void: @@ -220,7 +223,7 @@ func server_updated() -> void: func update_from_server() -> void: print("update_from_server") - search_view.get_list_of_games() + search_view.get_list_of_soundtracks() get_suggestion_list() reset_playlist() new_character_select.load_characters() @@ -245,7 +248,7 @@ func fetch_song_list_at_start() -> void: for d: Dictionary in data: var new_song_object: SongObject = SongObject.new() new_song_object.song_number = d.SongNo - new_song_object.game_title = d.Game + new_song_object.soundtrack_title = d.Soundtrack new_song_object.song_title = d.Song new_song_object.is_answered = true new_song_object.has_played = true @@ -291,7 +294,7 @@ func fetch_song() -> void: var fetch_song_info_done: Callable = func fetch_song_info_done(data_received: Dictionary) -> void: print("fetch_song_info_done") new_song_object.song_number = data_received.SongNo - new_song_object.game_title = data_received.Game + new_song_object.soundtrack_title = data_received.Soundtrack new_song_object.song_title = data_received.Song print("new_song_object: ", new_song_object.to_string()) @@ -312,7 +315,7 @@ func fetch_song() -> void: func update_song_list() -> void: print("update_song_list") if Playlist.currently_playing_song >= 0: - game_label.text = Playlist.get_current_game_title() + soundtrack_label.text = Playlist.get_current_soundtrack_title() song_label.text = Playlist.get_current_song_title() Settings.delete_children(music_list) for s: SongObject in Playlist.get_playlist(): @@ -371,10 +374,10 @@ func show_qr() -> void: func get_statistics() -> void: print("get_statistics") statistic_popup.visible = true - statistic_label.text = "Total amount of games in the playlist: " + str(games.size()) + statistic_label.text = "Total amount of soundtracks in the playlist: " + str(soundtracks.size()) -func sync_games() -> void: - print("sync_games") +func sync_soundtracks() -> void: + print("sync_soundtracks") sync_window.start_sync() func _on_sync_started() -> void: @@ -397,17 +400,16 @@ func get_suggestion_list() -> void: print("get_suggestion_list") var populate_list: Callable = func populate_list(array) -> void: if typeof(array) == TYPE_ARRAY: - games = [] + soundtracks = [] Settings.delete_children(inspiration_list) - games.append_array(array) - for game: String in games: + 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 = game + inspiration_label.text = soundtrack inspiration_label.autowrap_mode = TextServer.AUTOWRAP_WORD inspiration_list.add_child(inspiration_label) - inspiration_scroll.scroll_to_bottom() else: print("Unexpected data") Settings.make_request2("/music/all", populate_list, true) @@ -434,7 +436,7 @@ func add_player() -> void: func load_players() -> void: print("load_players") - Settings.delete_player_children(player_container) + Settings.delete_player_children(players_list_container) var counter: int = 0 for player_object: PlayerObject in Settings.player_array: print(player_object.player_name) @@ -445,7 +447,7 @@ func load_players() -> void: new_player.connect("change_character_clicked", _on_player_change_character_clicked.bind(new_player, player_object.player_name)) new_player.connect("player_removed", _on_player_removed.bind(counter)) - player_container.add_child(new_player) + players_list_container.add_child(new_player) counter += 1 func _on_point_given(player_given_point: int) -> void: @@ -519,11 +521,11 @@ func dir_contents(path: String) -> void: dir.list_dir_begin() var file_name: String = dir.get_next() songs.clear() - games = [] + soundtracks = [] while file_name != "": if dir.current_is_dir(): #print("Found directory: " + file_name) - games.append(file_name) + soundtracks.append(file_name) else: #print("Found file: " + file_name) if file_name.ends_with(".mp3"): @@ -532,7 +534,7 @@ func dir_contents(path: String) -> void: else: print("An error occurred when trying to access the path.") - for game: String in games: + for soundtrack: String in soundtracks: var local_inspiration_label: Label = Label.new() - local_inspiration_label.text = game + local_inspiration_label.text = soundtrack inspiration_list.add_child(local_inspiration_label) diff --git a/MainWindow.tscn b/MainWindow.tscn index 9256b90..e4bfec1 100644 --- a/MainWindow.tscn +++ b/MainWindow.tscn @@ -151,7 +151,7 @@ offset_top = 64.0 offset_right = 1152.0 offset_bottom = 384.0 -[node name="GameLabel" type="Label" parent="VBoxContainer" unique_id=173147793] +[node name="SoundtrackLabel" type="Label" parent="VBoxContainer" unique_id=173147793] texture_filter = 1 custom_minimum_size = Vector2(1, 1) layout_mode = 2 @@ -253,13 +253,21 @@ layout_mode = 2 size_flags_horizontal = 3 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 + +[node name="PlayersListVBoxContainer" type="VBoxContainer" parent="Players/VBoxContainer/ScrollContainer" unique_id=1000000002] +layout_mode = 2 +size_flags_vertical = 15 + [node name="ResetPlaylistButton" type="Button" parent="." unique_id=1754155620] texture_filter = 1 layout_mode = 0 -offset_left = 1359.0 -offset_top = 66.0 -offset_right = 1470.0 -offset_bottom = 97.0 +offset_left = 1360.0 +offset_top = 64.0 +offset_right = 1471.0 +offset_bottom = 95.0 focus_mode = 0 action_mode = 0 text = "Reset playlist" @@ -267,10 +275,10 @@ text = "Reset playlist" [node name="ResetPointsButton" type="Button" parent="." unique_id=942880776] texture_filter = 1 layout_mode = 0 -offset_left = 1487.0 -offset_top = 66.0 -offset_right = 1598.0 -offset_bottom = 97.0 +offset_left = 1488.0 +offset_top = 64.0 +offset_right = 1599.0 +offset_bottom = 95.0 focus_mode = 0 action_mode = 0 text = "Reset points" @@ -278,21 +286,21 @@ text = "Reset points" [node name="SyncButton" type="Button" parent="." unique_id=1228313556] texture_filter = 1 layout_mode = 0 -offset_left = 1615.0 -offset_top = 66.0 -offset_right = 1726.0 -offset_bottom = 97.0 +offset_left = 1616.0 +offset_top = 64.0 +offset_right = 1759.0 +offset_bottom = 95.0 focus_mode = 0 action_mode = 0 -text = "Sync games" +text = "Sync soundtracks" [node name="SoundTestButton" type="Button" parent="." unique_id=1332971879] texture_filter = 1 layout_mode = 0 -offset_left = 1743.0 -offset_top = 66.0 -offset_right = 1854.0 -offset_bottom = 97.0 +offset_left = 1776.0 +offset_top = 64.0 +offset_right = 1887.0 +offset_bottom = 95.0 focus_mode = 0 action_mode = 0 text = "Sound test" @@ -461,7 +469,7 @@ offset_left = 4.0 offset_top = 4.0 offset_right = 446.0 offset_bottom = 96.0 -text = "Total amount of games in the playlist: 9000" +text = "Total amount of soundtracks in the playlist: 9000" horizontal_alignment = 1 vertical_alignment = 1 diff --git a/SearchWindow.gd b/SearchWindow.gd index 3fa96e2..497307c 100644 --- a/SearchWindow.gd +++ b/SearchWindow.gd @@ -9,24 +9,26 @@ var search_panel: Panel = %SearchPanel @onready var clear_button: Button = $ClearButton -@onready -var close_button: Button = $CloseButton - @onready var search_bar: TextEdit = $Searchbar -var games: Array = [] -var regex: RegEx +var soundtracks: Array = [] + +# Precomputed soundtrack data: array of dicts with original, lowercase, and cleaned fields +var precomputed_soundtracks: Array = [] + +# Regex cache: maps cleaned search terms to compiled RegEx objects +var regex_cache: Dictionary = {} + +var label_pool: Array[Label] = [] # Called when the node enters the scene tree for the first time. func _ready() -> void: clear_button.pressed.connect(clear) - close_button.pressed.connect(close) search_bar.grab_focus() search_bar.text_changed.connect(search) visibility_changed.connect(focus) - regex = RegEx.new() - + func focus() -> void: if self.visible == true: search_bar.grab_focus() @@ -38,88 +40,135 @@ func close() -> void: func search() -> void: print(search_bar.text) - Settings.delete_children(search_list) - var search_text: String = search_bar.text.to_lower() - for game: String in games: - if is_match_exact(search_text, game): - add_game(game) - var clean_search_text: String = clean_search_term(search_text) - for game: String in games: - if is_match_contains(clean_search_text, clean_game(game)): - add_game(game) - for game: String in games: - if is_match_regex(clean_search_text, clean_game(game)): - add_game(game) + var search_text: String = search_bar.text + + if search_text == "": + show_all_soundtracks() + return + + perform_search(search_text) -func clean_search_term(term: String) -> String: - return term.replace(" ", "").replace("é", "e").replace("+", "plus").replace("&", "and").replace("'n", "and") +func show_all_soundtracks() -> void: + # Hide all visible labels and add to pool + for child: Label in search_list.get_children(): + if child.visible: + child.visible = false + label_pool.append(child) + + # Show all soundtracks in order + for soundtrack: String in soundtracks: + add_soundtrack_reuse(soundtrack) -func clean_game(term: String) -> String: +func perform_search(search_text: String) -> void: + # Hide all visible labels and add to pool + for child: Label in search_list.get_children(): + if child.visible: + child.visible = false + label_pool.append(child) + + var seen: Dictionary = {} + var search_text_lower: String = search_text.to_lower() + var clean_search_text: String = clean_term(search_text) + + # Collect all matches first, then display in order + var matches: Array = [] + + # Pass 1: Exact case-insensitive contains match on lowercase versions + for i in range(precomputed_soundtracks.size()): + var st_data = precomputed_soundtracks[i] + if st_data["lowercase"].contains(search_text_lower): + if not st_data["original"] in seen: + seen[st_data["original"]] = true + matches.append(st_data["original"]) + + # Pass 2: Contains match on cleaned terms + for i in range(precomputed_soundtracks.size()): + var st_data = precomputed_soundtracks[i] + if st_data["cleaned"].contains(clean_search_text): + if not st_data["original"] in seen: + seen[st_data["original"]] = true + matches.append(st_data["original"]) + + # Pass 3: Regex match on cleaned terms + var regex = compile_regex_cached(clean_search_text) + for i in range(precomputed_soundtracks.size()): + var st_data = precomputed_soundtracks[i] + if regex.search(st_data["cleaned"]): + if not st_data["original"] in seen: + seen[st_data["original"]] = true + matches.append(st_data["original"]) + + # Display all matches in the order they appear in soundtracks + for soundtrack: String in matches: + add_soundtrack_reuse(soundtrack) + +# Cleans a term by removing spaces and replacing special characters. +# Matches MusicServer's clean_term() function. +func clean_term(term: String) -> String: return term.replace(" ", "").replace("é", "e").replace("+", "plus").replace("&", "and").replace("'n", "and").to_lower() -func is_match_exact(search_term: String, game_name: String) -> bool: - game_name = game_name.to_lower() - - if search_term == "": - return true - elif game_name.contains(search_term): - return true - else: - return false +# Compiles a regex pattern with caching to avoid recompiling the same pattern multiple times. +func compile_regex_cached(search_term: String) -> RegEx: + if not search_term in regex_cache: + var regex = RegEx.new() + var regText: String = ".*" + for letter: String in search_term: + regText += letter + ".*" + regex.compile(regText) + regex_cache[search_term] = regex + return regex_cache[search_term] -func is_match_contains(search_term: String, game_name: String) -> bool: - if search_term == "": - return true - elif game_name.contains(search_term): - return true +func add_soundtrack(soundtrack: String) -> void: + # Backward compatibility - delegates to reuse version + add_soundtrack_reuse(soundtrack) + +# Optimized version that reuses label nodes from pool instead of creating new ones +func add_soundtrack_reuse(soundtrack: String) -> void: + var label: Label + if label_pool.size() > 0: + label = label_pool.pop_front() + label.text = soundtrack + label.visible = true + # Move to end to maintain display order + search_list.move_child(label, search_list.get_child_count() - 1) else: - return false - -func is_match_regex(search_term: String, game_name: String) -> bool: - if search_term == "": - return true - elif compile_regex(search_term).search(game_name): - return true - else: - return false - -func add_game(game: String) -> void: - var label: Label = Label.new() - label.text = game - print("game: " + game) - label.autowrap_mode = TextServer.AUTOWRAP_WORD - if !check_if_game_exists(game): + label = Label.new() + label.text = soundtrack + label.autowrap_mode = TextServer.AUTOWRAP_WORD search_list.add_child(label) + label.visible = true -func check_if_game_exists(game: String) -> bool: - var game_exists: bool = false +func check_if_soundtrack_exists(soundtrack: String) -> bool: + var soundtrack_exists: bool = false for child: Label in search_list.get_children(): - if child.text == game: - game_exists = true - return game_exists + if child.text == soundtrack and child.visible: + soundtrack_exists = true + return soundtrack_exists -func compile_regex(search_term: String) -> RegEx: - var regText: String = ".*" - for letter: String in search_term: - regText += letter + ".*" - regex.compile(regText) - return regex - -func get_list_of_games() -> void: - print("get_list_of_games") - var handle_games: Callable = func handle_games(array: Array) -> void: +func get_list_of_soundtracks() -> void: + print("get_list_of_soundtracks") + var handle_soundtracks: Callable = func handle_soundtracks(array) -> void: if typeof(array) == TYPE_ARRAY: - games = [] - Settings.delete_children(search_list) - games.append_array(array) - for game: String in games: - var label: Label = Label.new() - label.text = game - label.autowrap_mode = TextServer.AUTOWRAP_WORD - search_list.add_child(label) + soundtracks = [] + precomputed_soundtracks = [] + # Reuse existing labels: hide all and add to pool + for child: Label in search_list.get_children(): + child.visible = false + label_pool.append(child) + + soundtracks.append_array(array) + # Precompute cleaned versions for all soundtracks + for soundtrack: String in soundtracks: + var cleaned = clean_term(soundtrack) + precomputed_soundtracks.append({ + "original": soundtrack, + "lowercase": soundtrack.to_lower(), + "cleaned": cleaned + }) + add_soundtrack_reuse(soundtrack) else: print("Unexpected data") - Settings.make_request2("/music/all/order", handle_games, true) + Settings.make_request2("/music/all/order", handle_soundtracks, true) func _input(event: InputEvent) -> void: if self.visible == true: @@ -130,49 +179,5 @@ func _input(event: InputEvent) -> void: func clear() -> void: search_bar.text = "" - search() + show_all_soundtracks() search_bar.grab_focus() - -func old_search() -> void: - print(search_bar.text) - Settings.delete_children(search_list) - for game: String in games: - if old_is_match_exact(search_bar.text, game): - add_game(game) - for game: String in games: - if is_match_contains(clean_term(search_bar.text), clean_term(game)): - add_game(game) - for game: String in games: - if old_is_match_regex(clean_term(search_bar.text), clean_term(game)): - add_game(game) - -func clean_term(term: String) -> String: - return term.replace(" ", "").replace("é", "e").replace("+", "plus").replace("&", "and").replace("'n", "and").to_lower() - - -func old_is_match_exact(search_term: String, game_name: String) -> bool: - search_term = search_term.to_lower() - game_name = game_name.to_lower() - - if search_term == "": - return true - elif game_name.contains(search_term): - return true - else: - return false - -func old_is_match_regex(search_term: String, game_name: String) -> bool: - if search_term == "": - return true - elif compile_regex(search_term).search(game_name): - return true - else: - return false - -func old_compile_regex(search_term: String) -> RegEx: - var regex = RegEx.new() - var regText: String = ".*" - for letter in search_term: - regText += letter + ".*" - regex.compile(regText) - return regex diff --git a/SearchWindow.tscn b/SearchWindow.tscn index 0066e12..02b3fef 100644 --- a/SearchWindow.tscn +++ b/SearchWindow.tscn @@ -1,8 +1,8 @@ -[gd_scene load_steps=2 format=3 uid="uid://bxydgil1yifps"] +[gd_scene format=3 uid="uid://bxydgil1yifps"] [ext_resource type="Script" uid="uid://bg5yo08638600" path="res://SearchWindow.gd" id="1_m7bij"] -[node name="Control" type="Control"] +[node name="Control" type="Control" unique_id=616238617] layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -11,53 +11,41 @@ grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_m7bij") -[node name="SearchPanel" type="Panel" parent="."] +[node name="SearchPanel" type="Panel" parent="." unique_id=1262945994] unique_name_in_owner = true layout_mode = 0 offset_right = 1152.0 offset_bottom = 640.0 -[node name="ClearButton" type="Button" parent="."] +[node name="ClearButton" type="Button" parent="." unique_id=1549439398] texture_filter = 1 layout_mode = 0 -offset_left = 880.0 -offset_top = 24.0 -offset_right = 944.0 -offset_bottom = 64.0 +offset_left = 936.0 +offset_top = 16.0 +offset_right = 1027.0 +offset_bottom = 56.0 scale = Vector2(2, 2) focus_mode = 0 action_mode = 0 text = "Clear" -[node name="CloseButton" type="Button" parent="."] +[node name="Searchbar" type="TextEdit" parent="." unique_id=2112669372] texture_filter = 1 layout_mode = 0 -offset_left = 1032.0 -offset_top = 24.0 -offset_right = 1082.0 -offset_bottom = 64.0 -scale = Vector2(2, 2) -focus_mode = 0 -action_mode = 0 -text = "Close" - -[node name="Searchbar" type="TextEdit" parent="."] -texture_filter = 1 -layout_mode = 0 -offset_left = 64.0 -offset_top = 24.0 -offset_right = 448.0 -offset_bottom = 64.0 +offset_left = 32.0 +offset_top = 16.0 +offset_right = 468.0 +offset_bottom = 56.0 scale = Vector2(2, 2) placeholder_text = "Search" -[node name="ScrollContainer" type="ScrollContainer" parent="."] +[node name="ScrollContainer" type="ScrollContainer" parent="." unique_id=213733486] layout_mode = 0 offset_top = 128.0 offset_right = 576.0 offset_bottom = 384.0 scale = Vector2(2, 2) -[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer" unique_id=1567403144] layout_mode = 2 size_flags_horizontal = 3 diff --git a/Settings.gd b/Settings.gd index 08f125a..8b28d29 100644 --- a/Settings.gd +++ b/Settings.gd @@ -28,11 +28,11 @@ var edit_players: bool = false var currently_syncing: bool = false var character_select_open: bool = false -var version: String = "1.8.5" +var version: String = "1.9.0" func make_request2(address: String, func_name: Callable, expect_data: bool) -> void: var error_handling: Callable = func(_result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void: - print("request done to address: ", default_path + address) + print("request done to address: ", default_path + address + " response_code: ", response_code) if response_code == 200: print("func_name: ", func_name.get_method()) if !expect_data: @@ -63,7 +63,7 @@ func make_request2(address: String, func_name: Callable, expect_data: bool) -> v func make_request3(address: String) -> void: var error_handling: Callable = func(_result: int, response_code: int, _headers: PackedStringArray, _body: PackedByteArray) -> void: - print("request done to address: ", default_path + address) + print("request done to address: ", default_path + address + " response_code: ", response_code) if response_code != 200: print("Error: " + str(response_code)) @@ -77,7 +77,7 @@ func make_request3(address: String) -> void: func make_put_request(address: String) -> void: var error_handling: Callable = func(_result: int, response_code: int, _headers: PackedStringArray, _body: PackedByteArray) -> void: - print("request done to address: ", default_path + address) + print("request done to address: ", default_path + address + " response_code: ", response_code) if response_code != 200: print("Error: " + str(response_code)) @@ -97,12 +97,5 @@ func delete_children(node: Node) -> void: func delete_player_children(node: Node) -> void: for n: Node in node.get_children(): - print(n) - print(n.name) - if n.name == "HBoxContainer": - pass - elif n.name == "AddPlayerContainer": - pass - else: - node.remove_child(n) - n.queue_free() + node.remove_child(n) + n.queue_free() diff --git a/SongObject.gd b/SongObject.gd index f1d80e8..69b41bf 100644 --- a/SongObject.gd +++ b/SongObject.gd @@ -6,7 +6,7 @@ var song_number: int var song_title: String -var game_title: String +var soundtrack_title: String var players_given_point: Array[int] = [] @@ -18,9 +18,9 @@ var is_playing: bool = false var song: AudioStream -func get_game_title() -> String: +func get_soundtrack_title() -> String: if is_answered: - return game_title + return soundtrack_title else: return "????????" @@ -33,10 +33,10 @@ func get_song_title() -> String: func get_song_info() -> String: if Settings.is_debug: var format_string: String = "%d. %s - %s | played: %s | answered: %s" - return format_string % [(song_number + 1), game_title, song_title, has_played, is_answered] + return format_string % [(song_number + 1), soundtrack_title, song_title, has_played, is_answered] elif is_answered: var format_string: String = "%d. %s - %s" - return format_string % [(song_number + 1), game_title, song_title] + return format_string % [(song_number + 1), soundtrack_title, song_title] else: return "??? - ???" @@ -52,5 +52,5 @@ func remove_point(id: int) -> void: players_given_point.sort() func _to_string() -> String: - var format_string: String = "song_number: %d | game_title: %s | song_title: %s | is_answered: %s | has_played: %s | is_playing: %s" - return format_string % [(song_number), game_title, song_title, is_answered, has_played, is_playing] + var format_string: String = "song_number: %d | soundtrack_title: %s | song_title: %s | is_answered: %s | has_played: %s | is_playing: %s" + return format_string % [(song_number), soundtrack_title, song_title, is_answered, has_played, is_playing] diff --git a/SyncWindow.tscn b/SyncWindow.tscn index 83b3af6..747fb45 100644 --- a/SyncWindow.tscn +++ b/SyncWindow.tscn @@ -1,11 +1,11 @@ -[gd_scene load_steps=3 format=3 uid="uid://dpdem7pdxweb5"] +[gd_scene format=3 uid="uid://dpdem7pdxweb5"] [ext_resource type="Script" uid="uid://c3ejukwth512a" path="res://sync_window.gd" id="1_8ba47"] [sub_resource type="LabelSettings" id="LabelSettings_anbfi"] font_size = 25 -[node name="Control" type="Control"] +[node name="Control2" type="Control" unique_id=1302914356] layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -14,22 +14,22 @@ grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_8ba47") -[node name="SyncPanel" type="Panel" parent="."] +[node name="SyncPanel" type="Panel" parent="." unique_id=1714634204] unique_name_in_owner = true layout_mode = 0 offset_right = 1152.0 offset_bottom = 640.0 -[node name="ScrollContainer" type="ScrollContainer" parent="SyncPanel"] +[node name="ScrollContainer" type="ScrollContainer" parent="SyncPanel" unique_id=1289116349] layout_mode = 0 offset_right = 1152.0 offset_bottom = 640.0 -[node name="SyncVBoxContainer" type="VBoxContainer" parent="SyncPanel/ScrollContainer"] +[node name="SyncVBoxContainer" type="VBoxContainer" parent="SyncPanel/ScrollContainer" unique_id=1594735567] layout_mode = 2 -size_flags_horizontal = 3 +size_flags_horizontal = 6 -[node name="SyncTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"] +[node name="SyncTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=2125198054] unique_name_in_owner = true layout_mode = 2 size_flags_vertical = 0 @@ -37,7 +37,13 @@ text = "Sync" label_settings = SubResource("LabelSettings_anbfi") horizontal_alignment = 1 -[node name="NoChangesLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"] +[node name="SyncTime" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=1344333200] +unique_name_in_owner = true +layout_mode = 2 +text = "Sync time: " +horizontal_alignment = 1 + +[node name="NoChangesLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=1059308183] unique_name_in_owner = true visible = false layout_mode = 2 @@ -46,12 +52,12 @@ text = "No changes since last sync" label_settings = SubResource("LabelSettings_anbfi") horizontal_alignment = 1 -[node name="ProgressHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"] +[node name="ProgressHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=196414805] unique_name_in_owner = true visible = false layout_mode = 2 -[node name="SyncProgressBar" type="ProgressBar" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/ProgressHBoxContainer"] +[node name="SyncProgressBar" type="ProgressBar" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/ProgressHBoxContainer" unique_id=719135231] unique_name_in_owner = true custom_minimum_size = Vector2(1000, 0) layout_mode = 2 @@ -59,92 +65,100 @@ size_flags_horizontal = 6 step = 1.0 rounded = true -[node name="SyncHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"] +[node name="SyncHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=1156646398] unique_name_in_owner = true visible = false layout_mode = 2 -size_flags_horizontal = 4 +size_flags_horizontal = 6 theme_override_constants/separation = 30 -[node name="VSeparator6" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] -layout_mode = 2 - -[node name="GamesAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] +[node name="VSeparator6" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1432793432] unique_name_in_owner = true layout_mode = 2 -[node name="GamesAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesAddedVBox"] +[node name="SoundtracksAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=897546696] +unique_name_in_owner = true layout_mode = 2 -text = "GamesAdded" +size_flags_horizontal = 6 + +[node name="SoundtracksAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksAddedVBox" unique_id=535797768] +layout_mode = 2 +text = "SoundtracksAdded" horizontal_alignment = 1 -[node name="GamesAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] +[node name="SoundtracksAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=853642947] unique_name_in_owner = true layout_mode = 2 -[node name="GamesReAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] +[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 + +[node name="SoundtracksReAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksReAddedVBox" unique_id=1142636525] +layout_mode = 2 +text = "SoundtracksReAdded" + +[node name="SoundtracksReAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1872445446] unique_name_in_owner = true layout_mode = 2 -[node name="GamesReAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesReAddedVBox"] +[node name="SoundtracksChangedTitleVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=294212033] +unique_name_in_owner = true layout_mode = 2 -text = "GamesReAdded" +size_flags_horizontal = 6 -[node name="GamesReAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] +[node name="SoundtracksChangedTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksChangedTitleVBox" unique_id=696960827] +layout_mode = 2 +text = "SoundtracksChangedTitle" + +[node name="SoundtracksChangedTitleSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1730403036] unique_name_in_owner = true layout_mode = 2 -[node name="GamesChangedTitleVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] +[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 + +[node name="SoundtracksChangedContentLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksChangedContentVBox" unique_id=1209639099] +layout_mode = 2 +text = "SoundtracksChangedContent" + +[node name="SoundtracksChangedContentSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=626592535] unique_name_in_owner = true layout_mode = 2 -[node name="GamesChangedTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesChangedTitleVBox"] +[node name="SoundtracksRemovedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=1174594338] +unique_name_in_owner = true layout_mode = 2 -text = "GamesChangedTitle" +size_flags_horizontal = 6 -[node name="GamesChangedTitleSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] +[node name="SoundtracksRemovedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/SoundtracksRemovedVBox" unique_id=877713862] +layout_mode = 2 +text = "SoundtracksRemoved" + +[node name="SoundtracksRemovedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer" unique_id=839653516] unique_name_in_owner = true layout_mode = 2 -[node name="GamesChangedContentVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 - -[node name="GamesChangedContentLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesChangedContentVBox"] -layout_mode = 2 -text = "GamesChangedContent" - -[node name="GamesChangedContentSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 - -[node name="GamesRemovedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 - -[node name="GamesRemovedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesRemovedVBox"] -layout_mode = 2 -text = "GamesRemoved" - -[node name="GamesRemovedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 - -[node name="SyncTime" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -text = "Sync time: " -horizontal_alignment = 1 - -[node name="CatchedErrorsVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"] +[node name="CatchedErrorsVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=63733711] unique_name_in_owner = true visible = false layout_mode = 2 -[node name="CatchedErrorsLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/CatchedErrorsVBox"] +[node name="CatchedErrorsLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/CatchedErrorsVBox" unique_id=1784389644] layout_mode = 2 text = "CatchedErrors" horizontal_alignment = 1 -[node name="SyncTimer" type="Timer" parent="."] +[node name="RestartSyncButton" type="Button" parent="SyncPanel/ScrollContainer/SyncVBoxContainer" unique_id=372442237] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(200, 80) +layout_mode = 2 +size_flags_horizontal = 4 +text = "Restart Sync" + +[node name="SyncTimer" type="Timer" parent="." unique_id=1955169547] unique_name_in_owner = true diff --git a/character.gd b/character.gd index c1c652d..3cde46b 100644 --- a/character.gd +++ b/character.gd @@ -39,7 +39,7 @@ func set_character_name(character_name: String) -> void: func _input(event: InputEvent) -> void: if self.visible == true && Settings.character_select_open == true: - if event is InputEventMouseButton && event.is_pressed() && event.get_button_index(MOUSE_BUTTON_LEFT): + if event is InputEventMouseButton && event.is_pressed() && event.get_button_index() == MOUSE_BUTTON_LEFT: var evLocal: InputEvent = make_input_local(event) if Rect2(Vector2(0, 0), panel.size).has_point(evLocal.position): print(character_name_label.text) diff --git a/new_character_select.gd b/new_character_select.gd index f89896b..a7cbe94 100644 --- a/new_character_select.gd +++ b/new_character_select.gd @@ -12,6 +12,8 @@ var character_grid: GridContainer = %CharacterGridContainer @onready 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) @@ -50,13 +52,16 @@ func show_grid(player_name: String) -> void: title_label.text = "Select character for " + player_name close_timer.stop() self.visible = true + can_select_character = true Settings.character_select_open = true func _on_character_selected(texture: ImageTexture) -> void: print("_on_character_selected") self.visible = false - new_new_character_selected.emit(texture) - close_timer.start() + 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: diff --git a/playlist.gd b/playlist.gd index 42ac29c..735829d 100644 --- a/playlist.gd +++ b/playlist.gd @@ -70,8 +70,8 @@ func unset_is_playing() -> void: func set_currently_playing_song(value: int) -> void: currently_playing_song = value -func get_current_game_title() -> String: - return song_object_array[currently_playing_song].get_game_title() +func get_current_soundtrack_title() -> String: + return song_object_array[currently_playing_song].get_soundtrack_title() func get_current_song_title() -> String: return song_object_array[currently_playing_song].get_song_title() diff --git a/project.godot b/project.godot index 5ff8dde..0ecb1d1 100644 --- a/project.godot +++ b/project.godot @@ -16,7 +16,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true config/name="MusicPlayer" run/main_scene="res://MainWindow.tscn" -config/features=PackedStringArray("4.6", "Forward Plus") +config/features=PackedStringArray("4.7", "Forward Plus") config/icon="res://icon.svg" [autoload] diff --git a/sync_response.gd b/sync_response.gd index e558603..e765337 100644 --- a/sync_response.gd +++ b/sync_response.gd @@ -1,10 +1,10 @@ class_name SyncResponse extends Node -var games_added: Array -var games_re_added: Array -var games_changed_title: Array -var games_changed_content: Array -var games_removed: Array +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 diff --git a/sync_window.gd b/sync_window.gd index ae41ba1..382d3f4 100644 --- a/sync_window.gd +++ b/sync_window.gd @@ -19,34 +19,34 @@ var sync_hbox: HBoxContainer = %SyncHBoxContainer var sync_progress_bar: ProgressBar = %SyncProgressBar @onready -var games_added_vbox: VBoxContainer = %GamesAddedVBox +var soundtracks_added_vbox: VBoxContainer = %SoundtracksAddedVBox @onready -var games_added_separator: VSeparator = %GamesAddedSeparator +var soundtracks_added_separator: VSeparator = %SoundtracksAddedSeparator @onready -var games_readded_vbox: VBoxContainer = %GamesReAddedVBox +var soundtracks_readded_vbox: VBoxContainer = %SoundtracksReAddedVBox @onready -var games_readded_separator: VSeparator = %GamesReAddedSeparator +var soundtracks_readded_separator: VSeparator = %SoundtracksReAddedSeparator @onready -var games_changed_title_vbox: VBoxContainer = %GamesChangedTitleVBox +var soundtracks_changed_title_vbox: VBoxContainer = %SoundtracksChangedTitleVBox @onready -var games_changed_title_separator: VSeparator = %GamesChangedTitleSeparator +var soundtracks_changed_title_separator: VSeparator = %SoundtracksChangedTitleSeparator @onready -var games_changed_content_vbox: VBoxContainer = %GamesChangedContentVBox +var soundtracks_changed_content_vbox: VBoxContainer = %SoundtracksChangedContentVBox @onready -var games_changed_content_separator: VSeparator = %GamesChangedContentSeparator +var soundtracks_changed_content_separator: VSeparator = %SoundtracksChangedContentSeparator @onready -var games_removed_vbox: VBoxContainer = %GamesRemovedVBox +var soundtracks_removed_vbox: VBoxContainer = %SoundtracksRemovedVBox @onready -var games_removed_separator: VSeparator = %GamesRemovedSeparator +var soundtracks_removed_separator: VSeparator = %SoundtracksRemovedSeparator @onready var catched_errors_vbox: VBoxContainer = %CatchedErrorsVBox @@ -57,6 +57,12 @@ var sync_time: Label = %SyncTime @onready 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 @@ -66,6 +72,8 @@ signal sync_finished func _ready() -> void: sync_timer.timeout.connect(_on_sync_timeout) + restart_sync_button.pressed.connect(start_sync) + restart_sync_button.visible = false func _input(event: InputEvent) -> void: if self.visible == true: @@ -74,17 +82,30 @@ func _input(event: InputEvent) -> void: 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 + make_list(data, vbox, header_text) + return true + else: + vbox.visible = false + separator.visible = false + return false + func start_sync() -> void: print("start_sync") self.visible = true - if !has_synced: - var sync_request_sent: Callable = func sync_request_sent() -> void: - sync_timer.start(0.75) - Settings.currently_syncing = true - sync_started.emit() - show_sync_progress() - if !Settings.currently_syncing: - Settings.make_request2("/sync", sync_request_sent, false) + if has_synced: + # Already synced, just show the results + show_sync_result() + return + var sync_request_sent: Callable = func sync_request_sent() -> void: + sync_timer.start(0.75) + Settings.currently_syncing = true + sync_started.emit() + show_sync_progress() + if !Settings.currently_syncing: + Settings.make_request2("/sync", sync_request_sent, false) func _on_sync_timeout() -> void: print("_on_sync_timeout!") @@ -94,7 +115,7 @@ func _on_sync_timeout() -> void: if data_received != null: if data_received.has("progress"): sync_progress_bar.value = int(data_received.progress) - sync_time.text = data_received.time_spent + sync_time.text = data_received.time_spent if data_received.has("time_spent") else "" else: on_sync_finished(data_received) Settings.make_request2("/sync/progress", get_progress, true) @@ -102,43 +123,77 @@ func _on_sync_timeout() -> void: func on_sync_finished(data_received: Dictionary) -> void: has_synced = true reset_sync_result() - if data_received.games_added != null: + + if show_section_if_has_data(data_received.soundtracks_added, soundtracks_added_vbox, soundtracks_added_separator, "Added"): changes = true - list_visible(games_added_vbox, games_added_separator) - make_list(data_received.games_added, games_added_vbox, "GamesAdded") - if data_received.games_re_added != null: + + if show_section_if_has_data(data_received.soundtracks_re_added, soundtracks_readded_vbox, soundtracks_readded_separator, "ReAdded"): changes = true - list_visible(games_readded_vbox, games_readded_separator) - make_list(data_received.games_re_added, games_readded_vbox, "GamesReAdded") - if data_received.games_changed_title != null: + + if data_received.soundtracks_changed_title != null && data_received.soundtracks_changed_title.size() > 0: changes = true - list_visible(games_changed_title_vbox, games_changed_title_separator) - Settings.delete_children(games_changed_title_vbox) - make_header_label(games_changed_title_vbox, "GamesChangedTitle") + Settings.delete_children(soundtracks_changed_title_vbox) + make_header_label(soundtracks_changed_title_vbox, "Changed Title") var row: int = 0 - for old_game_title: String in data_received.games_changed_title: - var label: Label = make_game_label(old_game_title + " changed title to " + data_received.games_changed_title[old_game_title]) + 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)) - games_changed_title_vbox.add_child(label) - if data_received.games_changed_content != null: + soundtracks_changed_title_vbox.add_child(label) + row += 1 + soundtracks_changed_title_vbox.visible = true + + if show_section_if_has_data(data_received.soundtracks_changed_content, soundtracks_changed_content_vbox, soundtracks_changed_content_separator, "Changed Content"): changes = true - list_visible(games_changed_content_vbox, games_changed_content_separator) - make_list(data_received.games_changed_content, games_changed_content_vbox, "GamesChangedContent") - if data_received.games_removed != null: + + if show_section_if_has_data(data_received.soundtracks_removed, soundtracks_removed_vbox, soundtracks_removed_separator, "Removed"): changes = true - list_visible(games_removed_vbox, games_removed_separator) - make_list(data_received.games_removed, games_removed_vbox, "GamesRemoved") - if data_received.catched_errors != null: + + 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") + + # 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 + var visible_sections: Array = [] + if soundtracks_added_vbox.visible: + visible_sections.append("added") + if soundtracks_readded_vbox.visible: + visible_sections.append("readded") + if soundtracks_changed_title_vbox.visible: + visible_sections.append("changed_title") + if soundtracks_changed_content_vbox.visible: + visible_sections.append("changed_content") + 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] + var separator_map = { + "added": soundtracks_added_separator, + "readded": soundtracks_readded_separator, + "changed_title": soundtracks_changed_title_separator, + "changed_content": soundtracks_changed_content_separator, + "removed": soundtracks_removed_separator + } + # Show this section's separator only if there's a next section + if i < visible_sections.size() - 1: + separator_map[section].visible = true + else: + separator_map[section].visible = false + if !changes: no_changes_label.visible = true - sync_time.text = data_received.total_time + sync_time.text = "Total time: " + data_received.total_time if data_received.has("total_time") else "" Settings.currently_syncing = false sync_timer.stop() print("sync finished") show_sync_result() + restart_sync_button.visible = true sync_finished.emit() func list_visible(vbox: VBoxContainer, seperator: VSeparator) -> void: @@ -150,15 +205,16 @@ func make_header_label(vbox: VBoxContainer, text: String) -> void: 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_game_label(text: String) -> 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", 20) + label.add_theme_font_size_override("font_size", 18) label.text = text - label.autowrap_mode = TextServer.AUTOWRAP_WORD + label.autowrap_mode = TextServer.AUTOWRAP_OFF return label func reset_sync_result() -> void: @@ -166,32 +222,35 @@ func reset_sync_result() -> void: sync_time.text = "" changes = false no_changes_label.visible = false - games_added_vbox.visible = false - games_added_separator.visible = false - games_readded_vbox.visible = false - games_readded_separator.visible = false - games_changed_title_vbox.visible = false - games_changed_title_separator.visible = false - games_changed_content_vbox.visible = false - games_changed_content_separator.visible = false - games_removed_vbox.visible = false - games_removed_separator.visible = false + soundtracks_added_vbox.visible = false + soundtracks_added_separator.visible = false + soundtracks_readded_vbox.visible = false + soundtracks_readded_separator.visible = false + soundtracks_changed_title_vbox.visible = false + soundtracks_changed_title_separator.visible = false + soundtracks_changed_content_vbox.visible = false + soundtracks_changed_content_separator.visible = false + 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 game: String in list: - var label: Label = make_game_label(game) + 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 func show_sync_result() -> void: sync_title_label.text = "Sync Result" progress_hbox.visible = false sync_hbox.visible = true + restart_sync_button.visible = true func show_sync_progress() -> void: sync_title_label.text = "Sync in Progress" @@ -199,3 +258,5 @@ func show_sync_progress() -> void: no_changes_label.visible = false sync_hbox.visible = false catched_errors_vbox.visible = false + restart_sync_button.visible = false + first_separator.visible = false