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
Build / build (push) Successful in 1m14s
Publish / build (push) Successful in 1m10s

This commit is contained in:
Sansan committed 2026-09-26 16:21:02 +02:00
1 parent 235bdcbcb5
commit 8da6fc442f
17 files changed
+448 -363

No files matched your search

+127 -122
View File
@@ -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