From 3f8e7fc26fdecde65fb78de84e4df31df8c0e750 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Thu, 5 Aug 2010 11:28:48 +0000 Subject: New feature for the %xd() (display a preloaded image) skin tag. It can now automatically load the correct subimage from a strip (assuming the strip is in the correct order) by giving a tag for the 2nd param. example: %xd(F, %mp) which is equivilant to %?mp<%xd(Fa)|%xd(Fb)|%xd(Fc)|%xd(Fd)|%xd(Fe)> You can also set the subimage offset.. i.e %xd(E, %mm, -1) which means "show nothing for the first value of %mm and use the bitmap strip for the remaining values" if a tag+offset is <0 or greater than the number of subimages in a strip he image is cleared (I'm open to changing this if someone has a better idea) cabbiev2.176x220x16.wps is an example of how to use this git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27717 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/skin_engine/skin_parser.c | 36 ++++++++++++++++++++++++------------ apps/gui/skin_engine/skin_render.c | 34 ++++++++++++++++++++++++++++++---- apps/gui/skin_engine/wps_internals.h | 9 +++++++++ lib/skin_parser/tag_table.c | 2 +- manual/appendix/wps_tags.tex | 11 ++++++++--- wps/cabbiev2.176x220x16.wps | 6 +++--- 6 files changed, 75 insertions(+), 23 deletions(-) diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index a3cb68915b..c5acd1fd75 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -232,27 +232,39 @@ static int parse_image_display(struct skin_element *element, char sublabel = text[1]; int subimage; struct gui_img *img; + struct image_display *id = skin_buffer_alloc(sizeof(struct image_display)); /* sanity check */ img = find_image(label, wps_data); - if (!img) + if (!img || !id) { token->value.i = label; /* so debug works */ return WPS_ERROR_INVALID_PARAM; } - - if ((subimage = get_image_id(sublabel)) != -1) + id->label = label; + id->offset = 0; + + if (element->params_count > 1) { - if (subimage >= img->num_subimages) - return WPS_ERROR_INVALID_PARAM; - - /* Store sub-image number to display in high bits */ - token->value.i = label | (subimage << 8); - return 4; /* We have consumed 2 bytes */ - } else { - token->value.i = label; - return 3; /* We have consumed 1 byte */ + id->token = element->params[1].data.code->data; + if (element->params_count > 2) + id->offset = element->params[2].data.number; } + else + { + id->token = NULL; + if ((subimage = get_image_id(sublabel)) != -1) + { + if (subimage >= img->num_subimages) + return WPS_ERROR_INVALID_PARAM; + id->subimage = subimage; + token->value.i = label | (subimage << 8); + } else { + id->subimage = 0; + } + } + token->value.data = id; + return 0; } static int parse_image_load(struct skin_element *element, diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 895746370e..e254c62cf9 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -144,11 +144,36 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, #ifdef HAVE_LCD_BITMAP case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: { - char n = token->value.i & 0xFF; - int subimage = token->value.i >> 8; + struct image_display *id = token->value.data; + char n = id->label; struct gui_img *img = find_image(n, data); if (img && img->loaded) - img->display = subimage; + { + if (id->token == NULL) + { + img->display = id->subimage; + } + else + { + char buf[16]; + const char *out; + int a = TOKEN_VALUE_ONLY; + out = get_token_value(gwps, id->token, buf, sizeof(buf), &a); + /* NOTE: get_token_value() returns values starting at 1! */ + if (a == -1) + a = (out && *out) ? 1 : 2; + a--; + a += id->offset; + /* If the token returned a value which is higher than + * the amount of subimages clear the image. */ + if (a<0 || a >= img->num_subimages) + { + clear_image_pos(gwps, img); + } + else + img->display = a; + } + } break; } #ifdef HAVE_ALBUMART @@ -230,7 +255,8 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, /* clear all pictures in the conditional and nested ones */ if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) { - struct gui_img *img = find_image(token->value.i&0xFF, data); + struct image_display *id = token->value.data; + struct gui_img *img = find_image(id->label, data); clear_image_pos(gwps, img); } else if (token->type == SKIN_TOKEN_PEAKMETER) diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 709dbc6ff7..e42fc5a53b 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -49,6 +49,9 @@ #define WPS_ALIGN_CENTER 64 #define WPS_ALIGN_LEFT 128 + +#define TOKEN_VALUE_ONLY 0xDEADD0D0 + #ifdef HAVE_ALBUMART /* albumart definitions */ @@ -80,6 +83,12 @@ struct gui_img { int display; }; +struct image_display { + char label; + int subimage; + struct wps_token *token; /* the token to get the subimage number from */ + int offset; /* offset into the bitmap strip to start */ +}; struct progressbar { enum skin_token_type type; diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 26c049b3dd..dccb9f8259 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -167,7 +167,7 @@ static const struct tag_info legal_tags[] = { SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "", SKIN_REFRESH_STATIC|NOBREAK }, { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I", 0|NOBREAK }, - { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S", 0 }, + { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|TI", 0 }, { SKIN_TOKEN_IMAGE_DISPLAY, "x", "SFII", 0|NOBREAK }, { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF", 0|NOBREAK }, diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex index 070d191646..2992b18a1c 100644 --- a/manual/appendix/wps_tags.tex +++ b/manual/appendix/wps_tags.tex @@ -320,10 +320,15 @@ Examples: \config{y}: y coordinate\newline \config{nimages}: (optional) number of sub-images (tiled vertically, of the same height) contained in the bitmap. Default is 1.\\ - \config{\%xd(n[i])} & Display a preloaded image. + \config{\%xd(n[i] [,tag] [,offset])} & Display a preloaded image. \config{n}: image ID (a-z and A-Z) as it was specified in \config{\%x} or \config{\%xl}\newline - \config{i}: (optional) number of the sub-image to display (a-z for 1-26 and A-Z for 27-52). - By default the first (i.e. top most) sub-image will be used.\\ + \config{i}: (optional) number of the sub-image to display (a-z for 1-26 and A-Z for 27-52). + (ignored when \config{tag} is used) + By default the first (i.e. top most) sub-image will be used.\newline + \config{tag}: (optional) Another tag to calculate the subimage from e.g \config{\%xd(A, \%mh)} would + use the first subimage when \config{\%mh} is on and the second when it is off\newline + \config{offset}}: (optional) Add this number to the value from the \config{tag} when + chosing the subimage (may be negative)\\ \end{tagmap} Examples: diff --git a/wps/cabbiev2.176x220x16.wps b/wps/cabbiev2.176x220x16.wps index c0c7cfc827..7b20adf7cf 100644 --- a/wps/cabbiev2.176x220x16.wps +++ b/wps/cabbiev2.176x220x16.wps @@ -27,10 +27,10 @@ %?C<%s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>>|> %al %pc%ac%?Sr<%pe %Sx(of) %pp|%pp %Sx(of) %pe>%ar%pr -%?mh<%xd(Aa)|%xd(Ab)> +%xd(A, %mh) %?bp<%?bc<%xd(Ba)|%xd(Bb)>|%?bl<|%xd(Bc)|%xd(Bd)|%xd(Be)|%xd(Bf)|%xd(Bg)|%xd(Bh)|%xd(Bi)|%xd(Bj)>> %?pv<%xd(Ca)|%xd(Cb)|%xd(Cc)|%xd(Cd)|%xd(Ce)|%xd(Cf)|%xd(Cg)|%xd(Ch)|%xd(Ci)|%xd(Cj)> %?ps<%xd(D)> -%?mm<|%xd(Ea)|%xd(Eb)|%xd(Ec)|%xd(Ed)> -%?mp<%xd(Fa)|%xd(Fb)|%xd(Fc)|%xd(Fd)|%xd(Fe)> +%xd(E, %mm, -1) +%xd(F, %mp) %?C<%Cd> -- cgit