forked from len0rd/rockbox
[Feature] Skin engine Themes grab text from a file %ft(file, line)
allow the skin engine to read text files and return a particular line you then can use ss on that string to allow display of strings from the file (Playername comes to mind) able to be used as conditional %?ft(filename)<Found|Not Found> if (selected) line of file is empty the tag is treated as #COMMENT bugfix: %t(n)%?x<text|text> would ignore the specified timeout defaulting to 2 seconds bugfix: cabbiev2.128x160x16.wps was missing %Sx() for translation on 'Next Track:' playername.txt generated at boot if it doesn't exist contents: 'Rockbox!' Change-Id: I04ea4fd411f74c7c6e672657949aa520c2f86f95
This commit is contained in:
parent
876e8c1305
commit
eb3e5eb2bf
8 changed files with 122 additions and 8 deletions
|
@ -1316,6 +1316,71 @@ static int parse_progressbar_tag(struct skin_element* element,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_filetext(struct skin_element *element,
|
||||||
|
struct wps_token *token,
|
||||||
|
struct wps_data *wps_data)
|
||||||
|
{
|
||||||
|
(void)wps_data;
|
||||||
|
const char* filename;
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
int fd;
|
||||||
|
int line = 0;
|
||||||
|
|
||||||
|
/* format: %ft(filename[,line]) */
|
||||||
|
filename = get_param_text(element, 0);
|
||||||
|
|
||||||
|
if (element->params_count == 2)
|
||||||
|
line = get_param(element, 1)->data.number;
|
||||||
|
else if (element->params_count != 1)
|
||||||
|
{
|
||||||
|
DEBUGF("%s(file, line): %s Error: param count %d\n",
|
||||||
|
__func__, filename, element->params_count);
|
||||||
|
return WPS_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
path_append(buf, ROCKBOX_DIR, filename, sizeof(buf));
|
||||||
|
DEBUGF("%s %s[%d]\n", __func__, buf, line);
|
||||||
|
|
||||||
|
if ((fd = open_utf8(buf, O_RDONLY)) < 0)
|
||||||
|
{
|
||||||
|
DEBUGF("%s: Error Opening %s\n", __func__, buf);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rd = 0;
|
||||||
|
while (line >= 0)
|
||||||
|
{
|
||||||
|
if ((rd = read_line(fd, buf, sizeof(buf))) < 0)
|
||||||
|
break;
|
||||||
|
line--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rd <= 0) /* empty line? */
|
||||||
|
{
|
||||||
|
DEBUGF("%s: Error(%d) Reading %s\n", __func__, rd, filename);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[rd] = '\0';
|
||||||
|
char * skinbuf = skin_buffer_alloc(rd+1);
|
||||||
|
|
||||||
|
if (!skinbuf)
|
||||||
|
{
|
||||||
|
DEBUGF("%s: Error No Buffer %s\n", __func__, filename);
|
||||||
|
close(fd);
|
||||||
|
return WPS_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
strcpy(skinbuf, buf);
|
||||||
|
close(fd);
|
||||||
|
token->value.data = PTRTOSKINOFFSET(skin_buffer, skinbuf);
|
||||||
|
token->type = SKIN_TOKEN_STRING;
|
||||||
|
return 0;
|
||||||
|
failure:
|
||||||
|
element->type = COMMENT;
|
||||||
|
element->data = INVALID_OFFSET;
|
||||||
|
token->type = SKIN_TOKEN_NO_TOKEN;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ALBUMART
|
#ifdef HAVE_ALBUMART
|
||||||
static int parse_albumart_load(struct skin_element* element,
|
static int parse_albumart_load(struct skin_element* element,
|
||||||
struct wps_token *token,
|
struct wps_token *token,
|
||||||
|
@ -2378,6 +2443,9 @@ static int skin_element_callback(struct skin_element* element, void* data)
|
||||||
case SKIN_TOKEN_FILE_DIRECTORY:
|
case SKIN_TOKEN_FILE_DIRECTORY:
|
||||||
token->value.i = get_param(element, 0)->data.number;
|
token->value.i = get_param(element, 0)->data.number;
|
||||||
break;
|
break;
|
||||||
|
case SKIN_TOKEN_FILE_TEXT:
|
||||||
|
function = parse_filetext;
|
||||||
|
break;
|
||||||
#ifdef HAVE_BACKDROP_IMAGE
|
#ifdef HAVE_BACKDROP_IMAGE
|
||||||
case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
|
case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
|
||||||
case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
|
case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
|
||||||
|
|
|
@ -633,20 +633,23 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
|
||||||
{
|
{
|
||||||
token = SKINOFFSETTOPTR(skin_buffer, element->data);
|
token = SKINOFFSETTOPTR(skin_buffer, element->data);
|
||||||
if (token)
|
if (token)
|
||||||
return token->value.i;
|
retval = token->value.i;
|
||||||
}
|
}
|
||||||
else if (element->type == CONDITIONAL)
|
else if (element->type == CONDITIONAL)
|
||||||
{
|
{
|
||||||
struct conditional *conditional = SKINOFFSETTOPTR(skin_buffer, element->data);
|
struct conditional *conditional = SKINOFFSETTOPTR(skin_buffer, element->data);
|
||||||
int val = evaluate_conditional(gwps, 0, conditional,
|
int val = evaluate_conditional(gwps, 0, conditional, element->children_count);
|
||||||
element->children_count);
|
|
||||||
if (val >= 0)
|
int tmoval = get_subline_timeout(gwps, get_child(element->children, val));
|
||||||
|
if (tmoval >= 0)
|
||||||
{
|
{
|
||||||
retval = get_subline_timeout(gwps, get_child(element->children, val));
|
return MAX(retval, tmoval); /* Bugfix %t()%?CONDITIONAL tmo ignored */
|
||||||
if (retval >= 0)
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (element->type == COMMENT)
|
||||||
|
{
|
||||||
|
retval = 0; /* don't display this item */
|
||||||
|
}
|
||||||
element = SKINOFFSETTOPTR(skin_buffer, element->next);
|
element = SKINOFFSETTOPTR(skin_buffer, element->next);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -657,6 +660,7 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
|
||||||
bool changed_lines = false;
|
bool changed_lines = false;
|
||||||
struct line_alternator *alternator = SKINOFFSETTOPTR(skin_buffer, element->data);
|
struct line_alternator *alternator = SKINOFFSETTOPTR(skin_buffer, element->data);
|
||||||
unsigned old_refresh = info->refresh_type;
|
unsigned old_refresh = info->refresh_type;
|
||||||
|
|
||||||
if (info->refresh_type == SKIN_REFRESH_ALL)
|
if (info->refresh_type == SKIN_REFRESH_ALL)
|
||||||
{
|
{
|
||||||
alternator->current_line = element->children_count-1;
|
alternator->current_line = element->children_count-1;
|
||||||
|
|
|
@ -82,6 +82,13 @@ struct wps_token {
|
||||||
bool next;
|
bool next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct wps_subline_timeout {
|
||||||
|
long next_tick;
|
||||||
|
unsigned short hide;
|
||||||
|
unsigned short show;
|
||||||
|
};
|
||||||
|
|
||||||
char* get_dir(char* buf, int buf_size, const char* path, int level);
|
char* get_dir(char* buf, int buf_size, const char* path, int level);
|
||||||
|
|
||||||
|
|
||||||
|
|
12
apps/main.c
12
apps/main.c
|
@ -199,6 +199,18 @@ int main(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOTLOADER)
|
||||||
|
if (!file_exists(ROCKBOX_DIR"/playername.txt"))
|
||||||
|
{
|
||||||
|
int fd = open(ROCKBOX_DIR"/playername.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666);
|
||||||
|
if(fd >= 0)
|
||||||
|
{
|
||||||
|
fdprintf(fd, "%s!", str(LANG_ROCKBOX_TITLE));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef AUTOROCK
|
#ifdef AUTOROCK
|
||||||
{
|
{
|
||||||
char filename[MAX_PATH];
|
char filename[MAX_PATH];
|
||||||
|
|
|
@ -36,6 +36,13 @@ This configuration entry can only be created and edited with a text editor or
|
||||||
the Main Menu Config Plugin (see \reference{ref:main_menu_config}).
|
the Main Menu Config Plugin (see \reference{ref:main_menu_config}).
|
||||||
It is not possible to change this setting via the settings menu.
|
It is not possible to change this setting via the settings menu.
|
||||||
|
|
||||||
|
\subsection{\label{ref:CustomisingThePlayername}Customising The Playername}
|
||||||
|
|
||||||
|
Some themes (Cabbiev2) show a customizable playername in the Whats Playing Screen.
|
||||||
|
Edit the first line of \fname{/.rockbox/playername.txt} to show your own message
|
||||||
|
or leave an empty file to disable the feature, deleting the file will generate a new
|
||||||
|
playername.txt file containing 'Rockbox!' next boot.
|
||||||
|
|
||||||
\subsection{\label{ref:OpenPlugins}Open Plugin Menu Items}
|
\subsection{\label{ref:OpenPlugins}Open Plugin Menu Items}
|
||||||
|
|
||||||
Rockbox allows you to choose a plugin to run for select menu options.
|
Rockbox allows you to choose a plugin to run for select menu options.
|
||||||
|
|
|
@ -755,6 +755,21 @@ a horizontal progressbar which doesn't fill and draws the image
|
||||||
0 is the first conditional option
|
0 is the first conditional option
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
|
\begin{tagmap}
|
||||||
|
\config{\%ft(filename [,line]} & Get a line of text from a file.\\
|
||||||
|
\end{tagmap}
|
||||||
|
Use this tag to check for the existence of a file or read a line of text from a file.
|
||||||
|
Checking if a file exists can be done with \%?(ft(filename)<Found|NotFound>
|
||||||
|
similarly you can also check if a specific line exists with \%?(ft(filename, n)<Found|NotFound>
|
||||||
|
where n is the desired line.
|
||||||
|
Note: empty files or files that do not exist are ignored by the skin engine otherwise
|
||||||
|
\begin{description}
|
||||||
|
\item[filename] -- filename Note: files can only be found in \fname{/.rockbox} directory or one of its children.
|
||||||
|
eg. \%ft(wps/file.txt) would refer to \fname{/.rockbox/wps/file.txt}
|
||||||
|
\item[line] -- OPTIONAL, which line to grab, defaults to the first line.
|
||||||
|
Note: lines must end with CR or LF but may not exceed 320 characters
|
||||||
|
\end{description}
|
||||||
|
|
||||||
\begin{tagmap}
|
\begin{tagmap}
|
||||||
\config{\%(} & The character `('\\
|
\config{\%(} & The character `('\\
|
||||||
\config{\%)} & The character `)'\\
|
\config{\%)} & The character `)'\\
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct tag_info legal_tags[] =
|
||||||
{ "fn", "" },
|
{ "fn", "" },
|
||||||
{ "fp", "" },
|
{ "fp", "" },
|
||||||
{ "fs", "" },
|
{ "fs", "" },
|
||||||
|
{ "ft", "" },
|
||||||
{ "fv", "" },
|
{ "fv", "" },
|
||||||
{ "d" , "I" },
|
{ "d" , "I" },
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
%s%ac%?it<%it|%fn>
|
%s%ac%?it<%it|%fn>
|
||||||
%s%ac%?ia<%ia|%?iA<%iA|%?d(2)<%d(2)|%(root%)>>>
|
%s%ac%?ia<%ia|%?iA<%iA|%?d(2)<%d(2)|%(root%)>>>
|
||||||
|
|
||||||
%s%acNext Track:
|
%s%ac%Sx(Next Track:)
|
||||||
%s%ac%?It<%It|%Fn>
|
%s%ac%?It<%It|%Fn>
|
||||||
|
|
||||||
#Time and Playlist Info
|
#Time and Playlist Info
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue