From 41d5ca3c4875ac07095bac9e7a7a60c1b31110f3 Mon Sep 17 00:00:00 2001 From: Arin Kim Date: Tue, 13 Jan 2026 16:41:55 +0100 Subject: [PATCH] skin: add new %pP tag (playlist progress as percentage) This new tag returns the position in the playlist as a percent. The main usecase for this is to use it as a bar tag, allowing themes to visually present playlist progress. Change-Id: I0eb001e7458d97b8a0db39f3980d9c283bc8806b --- apps/gui/skin_engine/skin_display.c | 5 +++++ apps/gui/skin_engine/skin_parser.c | 3 +++ apps/gui/skin_engine/skin_render.c | 1 + apps/gui/skin_engine/skin_tokens.c | 18 ++++++++++++++++++ docs/CREDITS | 1 + lib/skin_parser/tag_table.c | 2 ++ lib/skin_parser/tag_table.h | 2 ++ manual/appendix/wps_tags.tex | 4 +++- 8 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 53efc1f7ac..2a6f8072ec 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -207,6 +207,11 @@ void draw_progressbar(struct gui_wps *gwps, struct skin_viewport* skin_viewport, length = MAX_PEAK; end = peak_meter_scale_value(val, length); } + else if (pb->type == SKIN_TOKEN_PLAYLIST_PERCENTBAR) + { + length = playlist_amount(); + end = playlist_get_display_index(); + } else if (pb->type == SKIN_TOKEN_LIST_SCROLLBAR) { int val, min, max; diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 2537e869ab..c3294c53bf 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -1241,6 +1241,8 @@ static int parse_progressbar_tag(struct skin_element* element, token->type = SKIN_TOKEN_PEAKMETER_LEFTBAR; else if (token->type == SKIN_TOKEN_PEAKMETER_RIGHT) token->type = SKIN_TOKEN_PEAKMETER_RIGHTBAR; + else if (token->type == SKIN_TOKEN_PLAYLIST_PERCENT) + token->type = SKIN_TOKEN_PLAYLIST_PERCENTBAR; else if (token->type == SKIN_TOKEN_LIST_NEEDS_SCROLLBAR) token->type = SKIN_TOKEN_LIST_SCROLLBAR; else if (token->type == SKIN_TOKEN_SETTING) @@ -2418,6 +2420,7 @@ static int skin_element_callback(struct skin_element* element, void* data) case SKIN_TOKEN_PLAYER_PROGRESSBAR: case SKIN_TOKEN_PEAKMETER_LEFT: case SKIN_TOKEN_PEAKMETER_RIGHT: + case SKIN_TOKEN_PLAYLIST_PERCENT: case SKIN_TOKEN_LIST_NEEDS_SCROLLBAR: #ifdef HAVE_RADIO_RSSI case SKIN_TOKEN_TUNER_RSSI: diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index aef5dae899..77443eb8eb 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -225,6 +225,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, /* fall through to the progressbar code */ case SKIN_TOKEN_VOLUMEBAR: case SKIN_TOKEN_BATTERY_PERCENTBAR: + case SKIN_TOKEN_PLAYLIST_PERCENTBAR: case SKIN_TOKEN_SETTINGBAR: case SKIN_TOKEN_PROGRESSBAR: case SKIN_TOKEN_TUNER_RSSI_BAR: diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 45887c17c8..a9d9e0d729 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -1164,6 +1164,24 @@ const char *get_token_value(struct gui_wps *gwps, numeric_buf = buf; goto gtv_ret_numeric_tag_info; + case SKIN_TOKEN_PLAYLIST_PERCENT: + int playlist_amt = playlist_amount(); + int current_pos = playlist_get_display_index() + offset; + int percentage = current_pos * 100 / playlist_amt; + + if (intval && limit != TOKEN_VALUE_ONLY) + { + numeric_ret = current_pos * limit / playlist_amt; + } + else + { + numeric_ret = percentage; + } + + itoa_buf(buf, buf_size, percentage); + numeric_buf = buf; + goto gtv_ret_numeric_tag_info; + case SKIN_TOKEN_PLAYLIST_SHUFFLE: if ( global_settings.playlist_shuffle ) return "s"; diff --git a/docs/CREDITS b/docs/CREDITS index 103b5270af..b2e8465938 100644 --- a/docs/CREDITS +++ b/docs/CREDITS @@ -753,6 +753,7 @@ Petr Mikhalitsyn Melissa Autumn Sho Tanimoto Nyx Guan +Arin Kim The libmad team The wavpack team diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 3715ffb670..2278dd23b3 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -163,6 +163,7 @@ static const struct tag_info legal_tags[] = TAG(SKIN_TOKEN_TRACK_STARTING, "pS" , "|D", SKIN_REFRESH_DYNAMIC), TAG(SKIN_TOKEN_TRACK_ENDING, "pE" , "|D", SKIN_REFRESH_DYNAMIC), TAG(SKIN_TOKEN_PLAYLIST_POSITION, "pp", "", SKIN_REFRESH_STATIC), + TAG(SKIN_TOKEN_PLAYLIST_PERCENT, "pP", BAR_PARAMS, SKIN_REFRESH_STATIC), TAG(SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "", SKIN_REFRESH_STATIC), TAG(SKIN_TOKEN_PLAYLIST_NAME, "pn", "", SKIN_REFRESH_STATIC), TAG(SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "", SKIN_REFRESH_DYNAMIC), @@ -329,3 +330,4 @@ const struct tag_info* find_tag(const char *name) } return tag; } + diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index ddabe68333..53cf340f5a 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h @@ -211,6 +211,8 @@ enum skin_token_type { SKIN_TOKEN_PLAYLIST_ENTRIES, SKIN_TOKEN_PLAYLIST_NAME, SKIN_TOKEN_PLAYLIST_POSITION, + SKIN_TOKEN_PLAYLIST_PERCENT, + SKIN_TOKEN_PLAYLIST_PERCENTBAR, SKIN_TOKEN_PLAYLIST_SHUFFLE, diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex index 762dbbad41..7cf0e4af26 100644 --- a/manual/appendix/wps_tags.tex +++ b/manual/appendix/wps_tags.tex @@ -174,7 +174,9 @@ or \config{\%D(2)}), produce the information for the next file to be played. \config{\%pR} & Peak meter for the right channel. Can be used as a value, % a conditional tag or a bar tag.\\ \config{\%pn} & Playlist name (without path or extension)\\ - \config{\%pp} & Playlist position\\ + \config{\%pp} & Playlist position as index\\ + \config{\%pP} & Playlist position as percentage. Can be used as a value, % + a conditional tag or a bar tag.\\ \config{\%pr} & Remaining time in song\\ \config{\%ps} & ``s'' if shuffle mode is enabled\\ \config{\%pt} & Total track time\\