summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2024-12-07 14:23:06 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2024-12-07 23:02:22 -0500
commiteb3e5eb2bf8130e96ba06c9265060921598c0bec (patch)
tree6d636be22e0be95bc6b6e2d574bda51b895ecbce
parent876e8c1305101136e1377c0d3e3689c49f92d40d (diff)
downloadrockbox-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.c68
-rw-r--r--apps/gui/skin_engine/skin_render.c18
-rw-r--r--apps/gui/skin_engine/wps_internals.h7
-rw-r--r--apps/main.c12
-rwxr-xr-xmanual/advanced_topics/main.tex7
-rw-r--r--manual/appendix/wps_tags.tex15
-rw-r--r--utils/skinupdater/tag_table.c1
-rw-r--r--wps/cabbiev2.128x160x16.wps2
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