summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
119 119
120 120
121void *skin_find_item(const char *label, enum skin_find_what what, 121void *skin_find_item(const char *label, enum skin_find_what what,
122 struct wps_data *data) 122 struct wps_data *data)
123{ 123{
124 const char *itemlabel = NULL; 124 const char *itemlabel = NULL;
125 union { 125 union {
@@ -145,6 +145,11 @@ void *skin_find_item(const char *label, enum skin_find_what what,
145 list.linkedlist = data->touchregions; 145 list.linkedlist = data->touchregions;
146 break; 146 break;
147#endif 147#endif
148#ifdef HAVE_SKIN_VARIABLES
149 case SKIN_VARIABLE:
150 list.linkedlist = data->skinvars;
151 break;
152#endif
148 } 153 }
149 154
150 while (list.linkedlist) 155 while (list.linkedlist)
@@ -171,6 +176,13 @@ void *skin_find_item(const char *label, enum skin_find_what what,
171 itemlabel = ((struct touchregion *)ret)->label; 176 itemlabel = ((struct touchregion *)ret)->label;
172 break; 177 break;
173#endif 178#endif
179#ifdef HAVE_SKIN_VARIABLES
180 case SKIN_VARIABLE:
181 ret = list.linkedlist->token->value.data;
182 itemlabel = ((struct skin_var *)ret)->label;
183 break;
184#endif
185
174 } 186 }
175 if (!skip && itemlabel && !strcmp(itemlabel, label)) 187 if (!skip && itemlabel && !strcmp(itemlabel, label))
176 return ret; 188 return ret;
@@ -718,7 +730,7 @@ static int parse_progressbar_tag(struct skin_element* element,
718 curr_param++; 730 curr_param++;
719 param++; 731 param++;
720 pb->slider = skin_find_item(param->data.text, 732 pb->slider = skin_find_item(param->data.text,
721 SKIN_FIND_IMAGE, wps_data); 733 SKIN_FIND_IMAGE, wps_data);
722 } 734 }
723 else /* option needs the next param */ 735 else /* option needs the next param */
724 return -1; 736 return -1;
@@ -742,7 +754,7 @@ static int parse_progressbar_tag(struct skin_element* element,
742 curr_param++; 754 curr_param++;
743 param++; 755 param++;
744 pb->backdrop = skin_find_item(param->data.text, 756 pb->backdrop = skin_find_item(param->data.text,
745 SKIN_FIND_IMAGE, wps_data); 757 SKIN_FIND_IMAGE, wps_data);
746 758
747 } 759 }
748 else /* option needs the next param */ 760 else /* option needs the next param */
@@ -915,7 +927,86 @@ static int parse_albumart_load(struct skin_element* element,
915} 927}
916 928
917#endif /* HAVE_ALBUMART */ 929#endif /* HAVE_ALBUMART */
918 930#ifdef HAVE_SKIN_VARIABLES
931static struct skin_var* find_or_add_var(const char* label,
932 struct wps_data *data)
933{
934 struct skin_var* ret = skin_find_item(label, SKIN_VARIABLE, data);
935 if (!ret)
936 {
937 ret = (struct skin_var*)skin_buffer_alloc(sizeof(struct skin_var));
938 if (!ret)
939 return NULL;
940 ret->label = label;
941 ret->value = 1;
942 ret->last_changed = 0xffff;
943 struct skin_token_list *item = new_skin_token_list_item(NULL, ret);
944 if (!item)
945 return NULL;
946 add_to_ll_chain(&data->skinvars, item);
947 }
948 return ret;
949}
950static int parse_skinvar( struct skin_element *element,
951 struct wps_token *token,
952 struct wps_data *wps_data)
953{
954 const char* label = element->params[0].data.text;
955 struct skin_var* var = find_or_add_var(label, wps_data);
956 if (!var)
957 return WPS_ERROR_INVALID_PARAM;
958 switch (token->type)
959 {
960 case SKIN_TOKEN_VAR_GETVAL:
961 token->value.data = var;
962 break;
963 case SKIN_TOKEN_VAR_SET:
964 {
965 struct skin_var_changer *data =
966 (struct skin_var_changer*)skin_buffer_alloc(
967 sizeof(struct skin_var_changer));
968 if (!data)
969 return WPS_ERROR_INVALID_PARAM;
970 data->var = var;
971 data->newval = element->params[2].data.number;
972 data->max = 0;
973 if (!strcmp(element->params[1].data.text, "set"))
974 data->direct = true;
975 else if (!strcmp(element->params[1].data.text, "inc"))
976 {
977 data->direct = false;
978 }
979 else if (!strcmp(element->params[1].data.text, "dec"))
980 {
981 data->direct = false;
982 data->newval *= -1;
983 }
984 if (element->params_count > 3)
985 data->max = element->params[3].data.number;
986 token->value.data = data;
987 }
988 break;
989 case SKIN_TOKEN_VAR_TIMEOUT:
990 {
991 struct skin_var_lastchange *data =
992 (struct skin_var_lastchange*)skin_buffer_alloc(
993 sizeof(struct skin_var_lastchange));
994 if (!data)
995 return WPS_ERROR_INVALID_PARAM;
996 data->var = var;
997 data->timeout = 10;
998 if (element->params_count > 1)
999 data->timeout = element->params[1].data.number;
1000 data->timeout *= TIMEOUT_UNIT;
1001 token->value.data = data;
1002 }
1003 break;
1004 default: /* kill the warning */
1005 break;
1006 }
1007 return 0;
1008}
1009#endif /* HAVE_SKIN_VARIABLES */
919#ifdef HAVE_TOUCHSCREEN 1010#ifdef HAVE_TOUCHSCREEN
920static int parse_lasttouch(struct skin_element *element, 1011static int parse_lasttouch(struct skin_element *element,
921 struct wps_token *token, 1012 struct wps_token *token,
@@ -934,7 +1025,7 @@ static int parse_lasttouch(struct skin_element *element,
934 { 1025 {
935 if (element->params[i].type == STRING) 1026 if (element->params[i].type == STRING)
936 data->region = skin_find_item(element->params[i].data.text, 1027 data->region = skin_find_item(element->params[i].data.text,
937 SKIN_FIND_TOUCHREGION, wps_data); 1028 SKIN_FIND_TOUCHREGION, wps_data);
938 else if (element->params[i].type == INTEGER) 1029 else if (element->params[i].type == INTEGER)
939 data->timeout = element->params[i].data.number; 1030 data->timeout = element->params[i].data.number;
940 } 1031 }
@@ -1217,6 +1308,9 @@ static void skin_data_reset(struct wps_data *wps_data)
1217#ifdef HAVE_TOUCHSCREEN 1308#ifdef HAVE_TOUCHSCREEN
1218 wps_data->touchregions = NULL; 1309 wps_data->touchregions = NULL;
1219#endif 1310#endif
1311#ifdef HAVE_SKIN_VARIABLES
1312 wps_data->skinvars = NULL;
1313#endif
1220#ifdef HAVE_ALBUMART 1314#ifdef HAVE_ALBUMART
1221 wps_data->albumart = NULL; 1315 wps_data->albumart = NULL;
1222 if (wps_data->playback_aa_slot >= 0) 1316 if (wps_data->playback_aa_slot >= 0)
@@ -1632,6 +1726,13 @@ static int skin_element_callback(struct skin_element* element, void* data)
1632 function = parse_albumart_load; 1726 function = parse_albumart_load;
1633 break; 1727 break;
1634#endif 1728#endif
1729#ifdef HAVE_SKIN_VARIABLES
1730 case SKIN_TOKEN_VAR_SET:
1731 case SKIN_TOKEN_VAR_GETVAL:
1732 case SKIN_TOKEN_VAR_TIMEOUT:
1733 function = parse_skinvar;
1734 break;
1735#endif
1635 default: 1736 default:
1636 break; 1737 break;
1637 } 1738 }
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,
229 break; 229 break;
230 230
231#endif /* HAVE_LCD_BITMAP */ 231#endif /* HAVE_LCD_BITMAP */
232#ifdef HAVE_SKIN_VARIABLES
233 case SKIN_TOKEN_VAR_SET:
234 if (do_refresh)
235 {
236 struct skin_var_changer *data = token->value.data;
237 if (data->direct)
238 data->var->value = data->newval;
239 else
240 {
241 data->var->value += data->newval;
242 if (data->max)
243 {
244 if (data->var->value > data->max)
245 data->var->value = 1;
246 else if (data->var->value < 1)
247 data->var->value = data->max;
248 }
249 }
250 if (data->var->value < 1)
251 data->var->value = 1;
252 data->var->last_changed = current_tick;
253 }
254 break;
255#endif
232 default: 256 default:
233 return false; 257 return false;
234 } 258 }
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,
1772 case SKIN_TOKEN_LANG_IS_RTL: 1772 case SKIN_TOKEN_LANG_IS_RTL:
1773 return lang_is_rtl() ? "r" : NULL; 1773 return lang_is_rtl() ? "r" : NULL;
1774 1774
1775#ifdef HAVE_SKIN_VARIABLES
1776 case SKIN_TOKEN_VAR_GETVAL:
1777 {
1778 struct skin_var* var = token->value.data;
1779 if (intval)
1780 *intval = var->value;
1781 snprintf(buf, buf_size, "%d", var->value);
1782 return buf;
1783 }
1784 break;
1785 case SKIN_TOKEN_VAR_TIMEOUT:
1786 {
1787 struct skin_var_lastchange *data = token->value.data;
1788 unsigned int last_change = data->var->last_changed;
1789
1790 if (last_change != 0xffff &&
1791 TIME_BEFORE(current_tick, data->timeout + last_change))
1792 return "t";
1793 }
1794 return NULL;
1795#endif
1796
1775 default: 1797 default:
1776 return NULL; 1798 return NULL;
1777 } 1799 }
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 {
199 on repeat or release. */ 199 on repeat or release. */
200 union { /* Extra data, action dependant */ 200 union { /* Extra data, action dependant */
201 struct touchsetting { 201 struct touchsetting {
202 const struct settings_list *setting; /* setting being controlled */ 202 const struct settings_list *setting; /* setting being controlled */
203 union { /* Value to set the setting to for ACTION_SETTING_SET */ 203 union { /* Value to set the setting to for ACTION_SETTING_SET */
204 int number; 204 int number;
205 char* text; 205 char* text;
206 } value; 206 } value;
207 } setting_data; 207 } setting_data;
208 int value; 208 int value;
209 }; 209 };
210 long last_press; /* last tick this was pressed */ 210 long last_press; /* last tick this was pressed */
@@ -272,6 +272,24 @@ struct logical_if {
272 int num_options; 272 int num_options;
273}; 273};
274 274
275#ifdef HAVE_SKIN_VARIABLES
276struct skin_var {
277 const char *label;
278 int value;
279 long last_changed;
280};
281struct skin_var_lastchange {
282 struct skin_var *var;
283 long timeout;
284};
285struct skin_var_changer {
286 struct skin_var *var;
287 int newval;
288 bool direct; /* true to make val=newval, false for val += newval */
289 int max;
290};
291#endif
292
275/* wps_data 293/* wps_data
276 this struct holds all necessary data which describes the 294 this struct holds all necessary data which describes the
277 viewable content of a wps */ 295 viewable content of a wps */
@@ -296,6 +314,10 @@ struct wps_data
296 int playback_aa_slot; 314 int playback_aa_slot;
297#endif 315#endif
298 316
317#ifdef HAVE_SKIN_VARIABLES
318 struct skin_token_list *skinvars;
319#endif
320
299#ifdef HAVE_LCD_BITMAP 321#ifdef HAVE_LCD_BITMAP
300 bool peak_meter_enabled; 322 bool peak_meter_enabled;
301 bool wps_sb_tag; 323 bool wps_sb_tag;
@@ -364,17 +386,20 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
364#endif 386#endif
365 387
366enum skin_find_what { 388enum skin_find_what {
367 SKIN_FIND_VP = 0, 389 SKIN_FIND_VP = 0,
368 SKIN_FIND_UIVP, 390 SKIN_FIND_UIVP,
369#ifdef HAVE_LCD_BITMAP 391#ifdef HAVE_LCD_BITMAP
370 SKIN_FIND_IMAGE, 392 SKIN_FIND_IMAGE,
371#endif 393#endif
372#ifdef HAVE_TOUCHSCREEN 394#ifdef HAVE_TOUCHSCREEN
373 SKIN_FIND_TOUCHREGION, 395 SKIN_FIND_TOUCHREGION,
396#endif
397#ifdef HAVE_SKIN_VARIABLES
398 SKIN_VARIABLE,
374#endif 399#endif
375}; 400};
376void *skin_find_item(const char *label, enum skin_find_what what, 401void *skin_find_item(const char *label, enum skin_find_what what,
377 struct wps_data *data); 402 struct wps_data *data);
378#ifdef SIMULATOR 403#ifdef SIMULATOR
379#define DEBUG_SKIN_ENGINE 404#define DEBUG_SKIN_ENGINE
380extern bool debug_wps; 405extern 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 */
949#ifdef HAVE_TOUCHSCREEN 949#ifdef HAVE_TOUCHSCREEN
950/* Timeout objects required for kinetic list scrolling */ 950/* Timeout objects required for kinetic list scrolling */
951#define INCLUDE_TIMEOUT_API 951#define INCLUDE_TIMEOUT_API
952/* Enable skin variable system, may not be the best place for this #define. */
953#define HAVE_SKIN_VARIABLES
952#endif /* HAVE_TOUCHSCREEN */ 954#endif /* HAVE_TOUCHSCREEN */
953 955
954#if defined(HAVE_USB_CHARGING_ENABLE) && defined(HAVE_USBSTACK) 956#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[] =
225 { SKIN_TOKEN_REC_MINUTES, "Rn" , "", SKIN_REFRESH_DYNAMIC }, 225 { SKIN_TOKEN_REC_MINUTES, "Rn" , "", SKIN_REFRESH_DYNAMIC },
226 { SKIN_TOKEN_REC_HOURS, "Rh" , "", SKIN_REFRESH_DYNAMIC }, 226 { SKIN_TOKEN_REC_HOURS, "Rh" , "", SKIN_REFRESH_DYNAMIC },
227 227
228 /* Skin variables */
229 { SKIN_TOKEN_VAR_SET, "vs", "SSI|I", SKIN_REFRESH_STATIC },
230 { SKIN_TOKEN_VAR_GETVAL, "vg", "S", SKIN_REFRESH_DYNAMIC },
231 { SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC },
232
228 { SKIN_TOKEN_UNKNOWN, "" , "", 0 } 233 { SKIN_TOKEN_UNKNOWN, "" , "", 0 }
229 /* Keep this here to mark the end of the table */ 234 /* Keep this here to mark the end of the table */
230}; 235};
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 {
265 SKIN_TOKEN_HAVE_RDS, 265 SKIN_TOKEN_HAVE_RDS,
266 SKIN_TOKEN_RDS_NAME, 266 SKIN_TOKEN_RDS_NAME,
267 SKIN_TOKEN_RDS_TEXT, 267 SKIN_TOKEN_RDS_TEXT,
268 268
269 /* Skin variables */
270 SKIN_TOKEN_VAR_SET,
271 SKIN_TOKEN_VAR_GETVAL,
272 SKIN_TOKEN_VAR_TIMEOUT,
269}; 273};
270 274
271/* 275/*