Files
Sansan a4e6da4c28 Show every song in the statistics, as an alternative to the cards
A Soundtracks / Songs switch in the statistics toolbar shows a list of
every song with its soundtrack and how often it was played. It is searched
on both song and soundtrack names, filtered and sorted like the cards, and
clicking a song shows its soundtrack's popup.

The server has tens of thousands of songs, so the list only makes the rows
on screen and reuses them while scrolling, songs are sorted once per load,
and searching waits for a pause in typing.

Closes #47
2026-10-09 17:02:27 +02:00

67 lines
2.1 KiB
GDScript

class_name SongStatsRow
extends PanelContainer
## One song in the statistics' list of songs: its name, its soundtrack and how often it
## was played, with the letters a search matched highlighted. Clicking it asks for the
## song's soundtrack.
##
## Rows are reused for other songs as the list scrolls, see [SongStatsList].
## Emitted when the row is clicked.
signal pressed(song: SongInfoForStats)
## The song the row shows.
var song: SongInfoForStats
# The place in the list of the song shown, for the alternating background
var _index: int = 0
var _hovered: bool = false
@onready var song_label: RichTextLabel = %SongLabel
@onready var soundtrack_label: RichTextLabel = %SoundtrackLabel
@onready var played_label: Label = %PlayedLabel
func _ready() -> void:
mouse_entered.connect(_set_hovered.bind(true))
mouse_exited.connect(_set_hovered.bind(false))
gui_input.connect(_on_gui_input)
## Shows [param data], song number [param index] in the list, with the letters
## [param search_text] matched highlighted.
func show_song(data: SongInfoForStats, index: int, search_text: String) -> void:
song = data
_index = index
_update_style()
var highlight: Color = get_theme_color(&"font_color", &"HighlightLarge")
_set_text(song_label, SearchPopup.highlighted_name(data.song_name, search_text, highlight))
_set_text(soundtrack_label,
SearchPopup.highlighted_name(data.soundtrack_name, search_text, highlight))
played_label.text = str(data.times_played)
tooltip_text = "%s\n%s" % [data.song_name, data.soundtrack_name]
# Setting the same text again would make the label lay it out again for nothing
static func _set_text(label: RichTextLabel, text: String) -> void:
if label.text != text:
label.text = text
func _set_hovered(hovered: bool) -> void:
_hovered = hovered
_update_style()
func _update_style() -> void:
if _hovered:
theme_type_variation = &"ListRowHover"
else:
theme_type_variation = &"ListRowOdd" if _index % 2 != 0 else &"ListRowEven"
func _on_gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton && event.pressed \
&& event.button_index == MOUSE_BUTTON_LEFT:
accept_event()
pressed.emit(song)