summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-03-27 08:01:58 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-03-27 08:01:58 +0000
commit87aa86cedd27445e51b0ad38dbc7cf2bdaa42364 (patch)
tree09d19881a5a48bbd3979877bfd08e5a109e6fa56
parent969381322d080a636d961a2e4505a9d88f04147d (diff)
downloadrockbox-87aa86cedd27445e51b0ad38dbc7cf2bdaa42364.tar.gz
rockbox-87aa86cedd27445e51b0ad38dbc7cf2bdaa42364.zip
Skin variables for touchscreen targets (origional implementation by Jens Theeß)
%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
-rw-r--r--apps/gui/skin_engine/skin_parser.c111
-rw-r--r--apps/gui/skin_engine/skin_render.c24
-rw-r--r--apps/gui/skin_engine/skin_tokens.c22
-rw-r--r--apps/gui/skin_engine/wps_internals.h47
-rw-r--r--firmware/export/config.h2
-rw-r--r--lib/skin_parser/tag_table.c5
-rw-r--r--lib/skin_parser/tag_table.h6
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 {
@@ -145,6 +145,11 @@ void *skin_find_item(const char *label, enum skin_find_what what,
list.linkedlist = data->touchregions;
break;
#endif
+#ifdef HAVE_SKIN_VARIABLES
+ case SKIN_VARIABLE:
+ list.linkedlist = data->skinvars;
+ break;
+#endif
}
while (list.linkedlist)
@@ -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)
@@ -1632,6 +1726,13 @@ static int skin_element_callback(struct skin_element* element, void* data)
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,
};
/*