Skip to content

box_song

Anthony Samms edited this page Jun 1, 2026 · 1 revision

SongBox is the box_base subclass that represents a single playable song in the navigator. It handles metadata display, preview music playback, score loading, and the difficulty-select overlay.

SongBox

SongBox(const fs::path& path, const BoxDef& box_def, SongParser parser);

Stores the pre-parsed SongParser result, computes chart hashes for each difficulty, and loads scores from the database. All rendered text is deferred to load_text().

Members

Member Type Description
parser SongParser Parsed song metadata (title, subtitle, BPM, difficulties, etc.)
hashes array<string, 5> Chart hashes for each of the five difficulty slots, used for score lookup
scores array<optional<Score>, 5> Loaded score data per difficulty
is_favorite bool Whether this song is in the player's favorites list
text_subtitle string Raw subtitle string
subtitle unique_ptr<OutlinedText> Rendered subtitle
name_black unique_ptr<OutlinedText> Title rendered in the dark style used on the open box
bpm_text unique_ptr<OutlinedText> BPM display text
preimage optional<ray::Texture2D> Preview image loaded from the song folder, if present
music_playing bool true while the song's preview audio is playing
score_history unique_ptr<ScoreHistory> Rotating score history display panel
box_opened_at double Timestamp of when the box was last opened, used to delay score history appearance
diff_fade_in FadeAnimation* Fade applied to the difficulty tile strip during expand animation

Lifecycle

void load_text() override;

Creates name, name_black, subtitle, and bpm_text outlined text objects from the parser data. Also loads the preview image from the song directory if one exists.

void update(double current_time) override;

Advances all base animations, updates score_history, and manages preview music: starts playback (at the configured preview start time) after the box has been open for a short delay, and stops it when the box is closed.

void reset() override;

Stops preview music and resets all animations to their initial state.

Open / Close

void expand_box() override;

Calls the base expand_box(), records box_opened_at, creates a ScoreHistory, starts the diff_fade_in animation, and queues preview music to begin.

void close_box() override;

Stops preview music, destroys score_history, and calls the base close_box().

void enter_box() override;

Called when the player presses Don on the opened song box to start difficulty selection. Transitions the visual state to difficulty-select mode.

Scores

void refresh_scores();

Reloads scores from the scores database using hashes and updates score_history.

void draw_score_history() override;

Draws the ScoreHistory panel. Called by Navigator::draw_score_history() so it renders above the box strip.

Difficulties

vector<Difficulty> get_diffs();

Returns the ordered list of Difficulty values that this song has charts for, suitable for passing to SongSelectPlayer::curr_diffs.

Drawing

void draw_closed() override; // protected

Draws the box in its collapsed state: background texture, title text, genre stripe, and the "new" indicator badge if is_new is set.

void draw_open() override; // protected

Draws the expanded box: preview image (if loaded), title and subtitle text, BPM, and score crowns. The diff_fade_in animation controls opacity of the difficulty information.

void draw_diff_select(bool is_ura) override; // protected

Draws the difficulty tile row with difficulty numbers, level stars, and score crown icons for each available difficulty. If is_ura is true, the URA tile is shown in place of the ONI tile.

// private
void draw_text();

Internal helper that draws the title/subtitle/BPM text at the correct positions for the current open state.

Clone this wiki locally