diff options
author | William Wilgus <wilgus.william@gmail.com> | 2024-12-07 14:23:06 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2024-12-07 23:02:22 -0500 |
commit | eb3e5eb2bf8130e96ba06c9265060921598c0bec (patch) | |
tree | 6d636be22e0be95bc6b6e2d574bda51b895ecbce | |
parent | 876e8c1305101136e1377c0d3e3689c49f92d40d (diff) | |
download | rockbox-eb3e5eb2bf.tar.gz rockbox-eb3e5eb2bf.zip |
[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
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 68 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_render.c | 18 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 7 | ||||
-rw-r--r-- | apps/main.c | 12 | ||||
-rwxr-xr-x | manual/advanced_topics/main.tex | 7 | ||||
-rw-r--r-- | manual/appendix/wps_tags.tex | 15 | ||||
-rw-r--r-- | utils/skinupdater/tag_table.c | 1 | ||||
-rw-r--r-- | wps/cabbiev2.128x160x16.wps | 2 |
8 files changed, 122 insertions, 8 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 33f82ef9e1..751bb86864 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -1316,6 +1316,71 @@ static int parse_progressbar_tag(struct skin_element* element, 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 static int parse_albumart_load(struct skin_element* element, struct wps_token *token, @@ -2378,6 +2443,9 @@ static int skin_element_callback(struct skin_element* element, void* data) case SKIN_TOKEN_FILE_DIRECTORY: token->value.i = get_param(element, 0)->data.number; break; + case SKIN_TOKEN_FILE_TEXT: + function = parse_filetext; + break; #ifdef HAVE_BACKDROP_IMAGE case SKIN_TOKEN_VIEWPORT_FGCOLOUR: case SKIN_TOKEN_VIEWPORT_BGCOLOUR: diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 06f7d9798d..b05d17c634 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -633,20 +633,23 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line) { token = SKINOFFSETTOPTR(skin_buffer, element->data); if (token) - return token->value.i; + retval = token->value.i; } else if (element->type == CONDITIONAL) { struct conditional *conditional = SKINOFFSETTOPTR(skin_buffer, element->data); - int val = evaluate_conditional(gwps, 0, conditional, - element->children_count); - if (val >= 0) + int val = evaluate_conditional(gwps, 0, conditional, element->children_count); + + int tmoval = get_subline_timeout(gwps, get_child(element->children, val)); + if (tmoval >= 0) { - retval = get_subline_timeout(gwps, get_child(element->children, val)); - if (retval >= 0) - return retval; + return MAX(retval, tmoval); /* Bugfix %t()%?CONDITIONAL tmo ignored */ } } + else if (element->type == COMMENT) + { + retval = 0; /* don't display this item */ + } element = SKINOFFSETTOPTR(skin_buffer, element->next); } return retval; @@ -657,6 +660,7 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info bool changed_lines = false; struct line_alternator *alternator = SKINOFFSETTOPTR(skin_buffer, element->data); unsigned old_refresh = info->refresh_type; + if (info->refresh_type == SKIN_REFRESH_ALL) { alternator->current_line = element->children_count-1; diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index b5365a3f77..366f79ac06 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -82,6 +82,13 @@ struct wps_token { 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); diff --git a/apps/main.c b/apps/main.c index 0241c0e488..b1a5091f1a 100644 --- a/apps/main.c +++ b/apps/main.c @@ -199,6 +199,18 @@ int main(void) } #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 { char filename[MAX_PATH]; diff --git a/manual/advanced_topics/main.tex b/manual/advanced_topics/main.tex index a7d3240d84..8b6f7d1435 100755 --- a/manual/advanced_topics/main.tex +++ b/manual/advanced_topics/main.tex @@ -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}). 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} Rockbox allows you to choose a plugin to run for select menu options. diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex index 567edd3c11..fc981c44e1 100644 --- a/manual/appendix/wps_tags.tex +++ b/manual/appendix/wps_tags.tex @@ -756,6 +756,21 @@ a horizontal progressbar which doesn't fill and draws the image \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} \config{\%(} & The character `('\\ \config{\%)} & The character `)'\\ \config{\%,} & The character `,'\\ diff --git a/utils/skinupdater/tag_table.c b/utils/skinupdater/tag_table.c index a1a5863de0..041856f3e9 100644 --- a/utils/skinupdater/tag_table.c +++ b/utils/skinupdater/tag_table.c @@ -70,6 +70,7 @@ struct tag_info legal_tags[] = { "fn", "" }, { "fp", "" }, { "fs", "" }, + { "ft", "" }, { "fv", "" }, { "d" , "I" }, diff --git a/wps/cabbiev2.128x160x16.wps b/wps/cabbiev2.128x160x16.wps index d4e221e2db..e93b9ea6cb 100644 --- a/wps/cabbiev2.128x160x16.wps +++ b/wps/cabbiev2.128x160x16.wps @@ -55,7 +55,7 @@ %s%ac%?it<%it|%fn> %s%ac%?ia<%ia|%?iA<%iA|%?d(2)<%d(2)|%(root%)>>> -%s%acNext Track: +%s%ac%Sx(Next Track:) %s%ac%?It<%It|%Fn> #Time and Playlist Info |