From 87aa86cedd27445e51b0ad38dbc7cf2bdaa42364 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Sun, 27 Mar 2011 08:01:58 +0000 Subject: Skin variables for touchscreen targets (origional implementation by Jens Theeß) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit %vs(name, [set|inc|dec], value [,max]) - name is the id, set sets the value, inc increments by value, dec decrements by value %vg(name) - get the current value %vl(name [,timeout]) - 'has it changed in [timeout]'? values start at 1 and are all reset to 1 on skin load git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29655 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/skin_engine/skin_parser.c | 111 +++++++++++++++++++++++++++++++++-- apps/gui/skin_engine/skin_render.c | 24 ++++++++ apps/gui/skin_engine/skin_tokens.c | 22 +++++++ apps/gui/skin_engine/wps_internals.h | 47 +++++++++++---- firmware/export/config.h | 2 + lib/skin_parser/tag_table.c | 5 ++ lib/skin_parser/tag_table.h | 6 +- 7 files changed, 200 insertions(+), 17 deletions(-) diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 468f6808c4..2370a38eab 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -119,7 +119,7 @@ static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_lis void *skin_find_item(const char *label, enum skin_find_what what, - struct wps_data *data) + struct wps_data *data) { const char *itemlabel = NULL; union { @@ -144,6 +144,11 @@ void *skin_find_item(const char *label, enum skin_find_what what, case SKIN_FIND_TOUCHREGION: list.linkedlist = data->touchregions; break; +#endif +#ifdef HAVE_SKIN_VARIABLES + case SKIN_VARIABLE: + list.linkedlist = data->skinvars; + break; #endif } @@ -171,6 +176,13 @@ void *skin_find_item(const char *label, enum skin_find_what what, itemlabel = ((struct touchregion *)ret)->label; break; #endif +#ifdef HAVE_SKIN_VARIABLES + case SKIN_VARIABLE: + ret = list.linkedlist->token->value.data; + itemlabel = ((struct skin_var *)ret)->label; + break; +#endif + } if (!skip && itemlabel && !strcmp(itemlabel, label)) return ret; @@ -718,7 +730,7 @@ static int parse_progressbar_tag(struct skin_element* element, curr_param++; param++; pb->slider = skin_find_item(param->data.text, - SKIN_FIND_IMAGE, wps_data); + SKIN_FIND_IMAGE, wps_data); } else /* option needs the next param */ return -1; @@ -742,7 +754,7 @@ static int parse_progressbar_tag(struct skin_element* element, curr_param++; param++; pb->backdrop = skin_find_item(param->data.text, - SKIN_FIND_IMAGE, wps_data); + SKIN_FIND_IMAGE, wps_data); } else /* option needs the next param */ @@ -915,7 +927,86 @@ static int parse_albumart_load(struct skin_element* element, } #endif /* HAVE_ALBUMART */ - +#ifdef HAVE_SKIN_VARIABLES +static struct skin_var* find_or_add_var(const char* label, + struct wps_data *data) +{ + struct skin_var* ret = skin_find_item(label, SKIN_VARIABLE, data); + if (!ret) + { + ret = (struct skin_var*)skin_buffer_alloc(sizeof(struct skin_var)); + if (!ret) + return NULL; + ret->label = label; + ret->value = 1; + ret->last_changed = 0xffff; + struct skin_token_list *item = new_skin_token_list_item(NULL, ret); + if (!item) + return NULL; + add_to_ll_chain(&data->skinvars, item); + } + return ret; +} +static int parse_skinvar( struct skin_element *element, + struct wps_token *token, + struct wps_data *wps_data) +{ + const char* label = element->params[0].data.text; + struct skin_var* var = find_or_add_var(label, wps_data); + if (!var) + return WPS_ERROR_INVALID_PARAM; + switch (token->type) + { + case SKIN_TOKEN_VAR_GETVAL: + token->value.data = var; + break; + case SKIN_TOKEN_VAR_SET: + { + struct skin_var_changer *data = + (struct skin_var_changer*)skin_buffer_alloc( + sizeof(struct skin_var_changer)); + if (!data) + return WPS_ERROR_INVALID_PARAM; + data->var = var; + data->newval = element->params[2].data.number; + data->max = 0; + if (!strcmp(element->params[1].data.text, "set")) + data->direct = true; + else if (!strcmp(element->params[1].data.text, "inc")) + { + data->direct = false; + } + else if (!strcmp(element->params[1].data.text, "dec")) + { + data->direct = false; + data->newval *= -1; + } + if (element->params_count > 3) + data->max = element->params[3].data.number; + token->value.data = data; + } + break; + case SKIN_TOKEN_VAR_TIMEOUT: + { + struct skin_var_lastchange *data = + (struct skin_var_lastchange*)skin_buffer_alloc( + sizeof(struct skin_var_lastchange)); + if (!data) + return WPS_ERROR_INVALID_PARAM; + data->var = var; + data->timeout = 10; + if (element->params_count > 1) + data->timeout = element->params[1].data.number; + data->timeout *= TIMEOUT_UNIT; + token->value.data = data; + } + break; + default: /* kill the warning */ + break; + } + return 0; +} +#endif /* HAVE_SKIN_VARIABLES */ #ifdef HAVE_TOUCHSCREEN static int parse_lasttouch(struct skin_element *element, struct wps_token *token, @@ -934,7 +1025,7 @@ static int parse_lasttouch(struct skin_element *element, { if (element->params[i].type == STRING) data->region = skin_find_item(element->params[i].data.text, - SKIN_FIND_TOUCHREGION, wps_data); + SKIN_FIND_TOUCHREGION, wps_data); else if (element->params[i].type == INTEGER) data->timeout = element->params[i].data.number; } @@ -1217,6 +1308,9 @@ static void skin_data_reset(struct wps_data *wps_data) #ifdef HAVE_TOUCHSCREEN wps_data->touchregions = NULL; #endif +#ifdef HAVE_SKIN_VARIABLES + wps_data->skinvars = NULL; +#endif #ifdef HAVE_ALBUMART wps_data->albumart = NULL; if (wps_data->playback_aa_slot >= 0) @@ -1631,6 +1725,13 @@ static int skin_element_callback(struct skin_element* element, void* data) case SKIN_TOKEN_ALBUMART_LOAD: function = parse_albumart_load; break; +#endif +#ifdef HAVE_SKIN_VARIABLES + case SKIN_TOKEN_VAR_SET: + case SKIN_TOKEN_VAR_GETVAL: + case SKIN_TOKEN_VAR_TIMEOUT: + function = parse_skinvar; + break; #endif default: break; diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 9fa940dba2..3037a955c7 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -229,6 +229,30 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, break; #endif /* HAVE_LCD_BITMAP */ +#ifdef HAVE_SKIN_VARIABLES + case SKIN_TOKEN_VAR_SET: + if (do_refresh) + { + struct skin_var_changer *data = token->value.data; + if (data->direct) + data->var->value = data->newval; + else + { + data->var->value += data->newval; + if (data->max) + { + if (data->var->value > data->max) + data->var->value = 1; + else if (data->var->value < 1) + data->var->value = data->max; + } + } + if (data->var->value < 1) + data->var->value = 1; + data->var->last_changed = current_tick; + } + break; +#endif default: return false; } diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index cf71014a62..a315bae609 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -1772,6 +1772,28 @@ const char *get_token_value(struct gui_wps *gwps, case SKIN_TOKEN_LANG_IS_RTL: return lang_is_rtl() ? "r" : NULL; +#ifdef HAVE_SKIN_VARIABLES + case SKIN_TOKEN_VAR_GETVAL: + { + struct skin_var* var = token->value.data; + if (intval) + *intval = var->value; + snprintf(buf, buf_size, "%d", var->value); + return buf; + } + break; + case SKIN_TOKEN_VAR_TIMEOUT: + { + struct skin_var_lastchange *data = token->value.data; + unsigned int last_change = data->var->last_changed; + + if (last_change != 0xffff && + TIME_BEFORE(current_tick, data->timeout + last_change)) + return "t"; + } + return NULL; +#endif + default: return NULL; } diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 0f5cb6df0c..4714609c1e 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -199,12 +199,12 @@ struct touchregion { on repeat or release. */ union { /* Extra data, action dependant */ struct touchsetting { - const struct settings_list *setting; /* setting being controlled */ - union { /* Value to set the setting to for ACTION_SETTING_SET */ - int number; - char* text; - } value; - } setting_data; + const struct settings_list *setting; /* setting being controlled */ + union { /* Value to set the setting to for ACTION_SETTING_SET */ + int number; + char* text; + } value; + } setting_data; int value; }; long last_press; /* last tick this was pressed */ @@ -272,6 +272,24 @@ struct logical_if { int num_options; }; +#ifdef HAVE_SKIN_VARIABLES +struct skin_var { + const char *label; + int value; + long last_changed; +}; +struct skin_var_lastchange { + struct skin_var *var; + long timeout; +}; +struct skin_var_changer { + struct skin_var *var; + int newval; + bool direct; /* true to make val=newval, false for val += newval */ + int max; +}; +#endif + /* wps_data this struct holds all necessary data which describes the viewable content of a wps */ @@ -296,6 +314,10 @@ struct wps_data int playback_aa_slot; #endif +#ifdef HAVE_SKIN_VARIABLES + struct skin_token_list *skinvars; +#endif + #ifdef HAVE_LCD_BITMAP bool peak_meter_enabled; bool wps_sb_tag; @@ -364,17 +386,20 @@ const char *get_radio_token(struct wps_token *token, int preset_offset, #endif enum skin_find_what { - SKIN_FIND_VP = 0, - SKIN_FIND_UIVP, + SKIN_FIND_VP = 0, + SKIN_FIND_UIVP, #ifdef HAVE_LCD_BITMAP - SKIN_FIND_IMAGE, + SKIN_FIND_IMAGE, #endif #ifdef HAVE_TOUCHSCREEN - SKIN_FIND_TOUCHREGION, + SKIN_FIND_TOUCHREGION, +#endif +#ifdef HAVE_SKIN_VARIABLES + SKIN_VARIABLE, #endif }; void *skin_find_item(const char *label, enum skin_find_what what, - struct wps_data *data); + struct wps_data *data); #ifdef SIMULATOR #define DEBUG_SKIN_ENGINE extern bool debug_wps; diff --git a/firmware/export/config.h b/firmware/export/config.h index cd4896f620..c8531b8f65 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -949,6 +949,8 @@ Lyre prototype 1 */ #ifdef HAVE_TOUCHSCREEN /* Timeout objects required for kinetic list scrolling */ #define INCLUDE_TIMEOUT_API +/* Enable skin variable system, may not be the best place for this #define. */ +#define HAVE_SKIN_VARIABLES #endif /* HAVE_TOUCHSCREEN */ #if defined(HAVE_USB_CHARGING_ENABLE) && defined(HAVE_USBSTACK) diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 56f5df1911..dea28b63ea 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -225,6 +225,11 @@ static const struct tag_info legal_tags[] = { SKIN_TOKEN_REC_MINUTES, "Rn" , "", SKIN_REFRESH_DYNAMIC }, { SKIN_TOKEN_REC_HOURS, "Rh" , "", SKIN_REFRESH_DYNAMIC }, + /* Skin variables */ + { SKIN_TOKEN_VAR_SET, "vs", "SSI|I", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_VAR_GETVAL, "vg", "S", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_UNKNOWN, "" , "", 0 } /* Keep this here to mark the end of the table */ }; diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index 31a5ec215f..e52fded61e 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h @@ -265,7 +265,11 @@ enum skin_token_type { SKIN_TOKEN_HAVE_RDS, SKIN_TOKEN_RDS_NAME, SKIN_TOKEN_RDS_TEXT, - + + /* Skin variables */ + SKIN_TOKEN_VAR_SET, + SKIN_TOKEN_VAR_GETVAL, + SKIN_TOKEN_VAR_TIMEOUT, }; /* -- cgit v1.2.3