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
This commit is contained in:
Arin Kim 2026-01-13 16:41:55 +01:00 committed by Solomon Peachy
parent 1c429e2209
commit 41d5ca3c48
8 changed files with 35 additions and 1 deletions

View file

@ -207,6 +207,11 @@ void draw_progressbar(struct gui_wps *gwps, struct skin_viewport* skin_viewport,
length = MAX_PEAK; length = MAX_PEAK;
end = peak_meter_scale_value(val, length); 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) else if (pb->type == SKIN_TOKEN_LIST_SCROLLBAR)
{ {
int val, min, max; int val, min, max;

View file

@ -1241,6 +1241,8 @@ static int parse_progressbar_tag(struct skin_element* element,
token->type = SKIN_TOKEN_PEAKMETER_LEFTBAR; token->type = SKIN_TOKEN_PEAKMETER_LEFTBAR;
else if (token->type == SKIN_TOKEN_PEAKMETER_RIGHT) else if (token->type == SKIN_TOKEN_PEAKMETER_RIGHT)
token->type = SKIN_TOKEN_PEAKMETER_RIGHTBAR; 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) else if (token->type == SKIN_TOKEN_LIST_NEEDS_SCROLLBAR)
token->type = SKIN_TOKEN_LIST_SCROLLBAR; token->type = SKIN_TOKEN_LIST_SCROLLBAR;
else if (token->type == SKIN_TOKEN_SETTING) 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_PLAYER_PROGRESSBAR:
case SKIN_TOKEN_PEAKMETER_LEFT: case SKIN_TOKEN_PEAKMETER_LEFT:
case SKIN_TOKEN_PEAKMETER_RIGHT: case SKIN_TOKEN_PEAKMETER_RIGHT:
case SKIN_TOKEN_PLAYLIST_PERCENT:
case SKIN_TOKEN_LIST_NEEDS_SCROLLBAR: case SKIN_TOKEN_LIST_NEEDS_SCROLLBAR:
#ifdef HAVE_RADIO_RSSI #ifdef HAVE_RADIO_RSSI
case SKIN_TOKEN_TUNER_RSSI: case SKIN_TOKEN_TUNER_RSSI:

View file

@ -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 */ /* fall through to the progressbar code */
case SKIN_TOKEN_VOLUMEBAR: case SKIN_TOKEN_VOLUMEBAR:
case SKIN_TOKEN_BATTERY_PERCENTBAR: case SKIN_TOKEN_BATTERY_PERCENTBAR:
case SKIN_TOKEN_PLAYLIST_PERCENTBAR:
case SKIN_TOKEN_SETTINGBAR: case SKIN_TOKEN_SETTINGBAR:
case SKIN_TOKEN_PROGRESSBAR: case SKIN_TOKEN_PROGRESSBAR:
case SKIN_TOKEN_TUNER_RSSI_BAR: case SKIN_TOKEN_TUNER_RSSI_BAR:

View file

@ -1164,6 +1164,24 @@ const char *get_token_value(struct gui_wps *gwps,
numeric_buf = buf; numeric_buf = buf;
goto gtv_ret_numeric_tag_info; 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: case SKIN_TOKEN_PLAYLIST_SHUFFLE:
if ( global_settings.playlist_shuffle ) if ( global_settings.playlist_shuffle )
return "s"; return "s";

View file

@ -753,6 +753,7 @@ Petr Mikhalitsyn
Melissa Autumn Melissa Autumn
Sho Tanimoto Sho Tanimoto
Nyx Guan Nyx Guan
Arin Kim
The libmad team The libmad team
The wavpack team The wavpack team

View file

@ -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_STARTING, "pS" , "|D", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_TRACK_ENDING, "pE" , "|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_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_ENTRIES, "pe", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_PLAYLIST_NAME, "pn", "", SKIN_REFRESH_STATIC), TAG(SKIN_TOKEN_PLAYLIST_NAME, "pn", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "", SKIN_REFRESH_DYNAMIC), TAG(SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "", SKIN_REFRESH_DYNAMIC),
@ -329,3 +330,4 @@ const struct tag_info* find_tag(const char *name)
} }
return tag; return tag;
} }

View file

@ -211,6 +211,8 @@ enum skin_token_type {
SKIN_TOKEN_PLAYLIST_ENTRIES, SKIN_TOKEN_PLAYLIST_ENTRIES,
SKIN_TOKEN_PLAYLIST_NAME, SKIN_TOKEN_PLAYLIST_NAME,
SKIN_TOKEN_PLAYLIST_POSITION, SKIN_TOKEN_PLAYLIST_POSITION,
SKIN_TOKEN_PLAYLIST_PERCENT,
SKIN_TOKEN_PLAYLIST_PERCENTBAR,
SKIN_TOKEN_PLAYLIST_SHUFFLE, SKIN_TOKEN_PLAYLIST_SHUFFLE,

View file

@ -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, % \config{\%pR} & Peak meter for the right channel. Can be used as a value, %
a conditional tag or a bar tag.\\ a conditional tag or a bar tag.\\
\config{\%pn} & Playlist name (without path or extension)\\ \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{\%pr} & Remaining time in song\\
\config{\%ps} & ``s'' if shuffle mode is enabled\\ \config{\%ps} & ``s'' if shuffle mode is enabled\\
\config{\%pt} & Total track time\\ \config{\%pt} & Total track time\\