summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/skin_engine/skin_parser.c37
-rw-r--r--apps/gui/skin_engine/skin_tokens.c101
-rw-r--r--apps/gui/skin_engine/wps_internals.h17
-rw-r--r--lib/skin_parser/skin_parser.c6
-rw-r--r--lib/skin_parser/tag_table.c2
-rw-r--r--lib/skin_parser/tag_table.h1
6 files changed, 150 insertions, 14 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 1d471e8580..2c766162c3 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -502,7 +502,39 @@ static int parse_setting_and_lang(struct skin_element *element,
token->value.i = i;
return 0;
}
-
+static int parse_logical_if(struct skin_element *element,
+ struct wps_token *token,
+ struct wps_data *wps_data)
+{
+ (void)wps_data;
+ char *op = element->params[1].data.text;
+ struct logical_if *lif = skin_buffer_alloc(sizeof(struct logical_if));
+ if (!lif)
+ return -1;
+ token->value.data = lif;
+ lif->token = element->params[0].data.code->data;
+
+ if (!strcmp(op, "="))
+ lif->op = IF_EQUALS;
+ if (!strcmp(op, "!="))
+ lif->op = IF_NOTEQUALS;
+ if (!strcmp(op, "<"))
+ lif->op = IF_LESSTHAN;
+ if (!strcmp(op, "<="))
+ lif->op = IF_LESSTHAN_EQ;
+ if (!strcmp(op, ">"))
+ lif->op = IF_GREATERTHAN;
+ if (!strcmp(op, ">="))
+ lif->op = IF_GREATERTHAN_EQ;
+
+ memcpy(&lif->operand, &element->params[2], sizeof(lif->operand));
+ if (element->params_count > 3)
+ lif->num_options = element->params[3].data.number;
+ else
+ lif->num_options = TOKEN_VALUE_ONLY;
+ return 0;
+
+}
static int parse_timeout_tag(struct skin_element *element,
struct wps_token *token,
struct wps_data *wps_data)
@@ -1298,6 +1330,9 @@ static int skin_element_callback(struct skin_element* element, void* data)
case SKIN_TOKEN_ALIGN_LANGDIRECTION:
follow_lang_direction = 2;
break;
+ case SKIN_TOKEN_LOGICAL_IF:
+ function = parse_logical_if;
+ break;
case SKIN_TOKEN_PROGRESSBAR:
case SKIN_TOKEN_VOLUME:
case SKIN_TOKEN_BATTERY_PERCENT:
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index b55588557a..36ad056410 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -315,6 +315,8 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
if (intval)
{
+ if (limit == TOKEN_VALUE_ONLY)
+ limit = 100; /* make it a percentage */
*intval = limit * elapsed / length + 1;
}
snprintf(buf, buf_size, "%lu", 100 * elapsed / length);
@@ -619,6 +621,72 @@ const char *get_token_value(struct gui_wps *gwps,
switch (token->type)
{
+ case SKIN_TOKEN_LOGICAL_IF:
+ {
+ struct logical_if *lif = token->value.data;
+ int a = lif->num_options;
+ int b;
+ out_text = get_token_value(gwps, lif->token, offset, buf, buf_size, &a);
+ if (a == -1 && lif->token->type != SKIN_TOKEN_VOLUME)
+ a = (out_text && *out_text) ? 1 : 0;
+ switch (lif->operand.type)
+ {
+ case STRING:
+ if (lif->op == IF_EQUALS)
+ return strcmp(out_text, lif->operand.data.text) == 0 ?
+ "eq" : NULL;
+ else
+ return NULL;
+ break;
+ case INTEGER:
+ case DECIMAL:
+ b = lif->operand.data.number;
+ break;
+ case CODE:
+ {
+ char temp_buf[MAX_PATH];
+ const char *outb;
+ struct wps_token *token = lif->operand.data.code->data;
+ b = lif->num_options;
+ outb = get_token_value(gwps, token, offset, temp_buf,
+ sizeof(temp_buf), &b);
+ if (b == -1 && lif->token->type != SKIN_TOKEN_VOLUME)
+ {
+ if (!out_text || !outb)
+ return (lif->op == IF_EQUALS) ? NULL : "neq";
+ bool equal = strcmp(out_text, outb) == 0;
+ if (lif->op == IF_EQUALS)
+ return equal ? "eq" : NULL;
+ else if (lif->op == IF_NOTEQUALS)
+ return !equal ? "neq" : NULL;
+ else
+ b = (outb && *outb) ? 1 : 0;
+ }
+ }
+ break;
+ case DEFAULT:
+ break;
+ }
+
+ switch (lif->op)
+ {
+ case IF_EQUALS:
+ return a == b ? "eq" : NULL;
+ case IF_NOTEQUALS:
+ return a != b ? "neq" : NULL;
+ case IF_LESSTHAN:
+ return a < b ? "lt" : NULL;
+ case IF_LESSTHAN_EQ:
+ return a <= b ? "lte" : NULL;
+ case IF_GREATERTHAN:
+ return a > b ? "gt" : NULL;
+ case IF_GREATERTHAN_EQ:
+ return a >= b ? "gte" : NULL;
+ }
+ return NULL;
+ }
+ break;
+
case SKIN_TOKEN_CHARACTER:
if (token->value.c == '\n')
return NULL;
@@ -632,6 +700,8 @@ const char *get_token_value(struct gui_wps *gwps,
case SKIN_TOKEN_PLAYLIST_ENTRIES:
snprintf(buf, buf_size, "%d", playlist_amount());
+ if (intval)
+ *intval = playlist_amount();
return buf;
case SKIN_TOKEN_LIST_TITLE_TEXT:
@@ -647,6 +717,8 @@ const char *get_token_value(struct gui_wps *gwps,
case SKIN_TOKEN_PLAYLIST_POSITION:
snprintf(buf, buf_size, "%d", playlist_get_display_index()+offset);
+ if (intval)
+ *intval = playlist_get_display_index()+offset;
return buf;
case SKIN_TOKEN_PLAYLIST_SHUFFLE:
@@ -661,7 +733,11 @@ const char *get_token_value(struct gui_wps *gwps,
if (intval)
{
int minvol = sound_min(SOUND_VOLUME);
- if (global_settings.volume == minvol)
+ if (limit == TOKEN_VALUE_ONLY)
+ {
+ *intval = global_settings.volume;
+ }
+ else if (global_settings.volume == minvol)
{
*intval = 1;
}
@@ -705,14 +781,21 @@ const char *get_token_value(struct gui_wps *gwps,
if (intval)
{
- limit = MAX(limit, 3);
- if (l > -1) {
- /* First enum is used for "unknown level",
- * last enum is used for 100%.
- */
- *intval = (limit - 2) * l / 100 + 2;
- } else {
- *intval = 1;
+ if (limit == TOKEN_VALUE_ONLY)
+ {
+ *intval = l;
+ }
+ else
+ {
+ limit = MAX(limit, 3);
+ if (l > -1) {
+ /* First enum is used for "unknown level",
+ * last enum is used for 100%.
+ */
+ *intval = (limit - 2) * l / 100 + 2;
+ } else {
+ *intval = 1;
+ }
}
}
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index c886a7584f..81958c7966 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -50,7 +50,7 @@
#define WPS_ALIGN_LEFT 128
-#define TOKEN_VALUE_ONLY 0xDEADD0D0
+#define TOKEN_VALUE_ONLY 0x0DEADC0D
#ifdef HAVE_ALBUMART
@@ -223,7 +223,7 @@ struct skin_albumart {
int draw_handle;
};
#endif
-
+
struct line {
int timeout; /* if inside a line alternator */
@@ -240,6 +240,19 @@ struct conditional {
struct wps_token *token;
};
+struct logical_if {
+ struct wps_token *token;
+ enum {
+ IF_EQUALS, /* == */
+ IF_NOTEQUALS, /* != */
+ IF_LESSTHAN, /* < */
+ IF_LESSTHAN_EQ, /* <= */
+ IF_GREATERTHAN, /* > */
+ IF_GREATERTHAN_EQ /* >= */
+ } op;
+ struct skin_tag_parameter operand;
+ int num_options;
+};
/* wps_data
this struct holds all necessary data which describes the
diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c
index 66deaab102..b3bc9856b9 100644
--- a/lib/skin_parser/skin_parser.c
+++ b/lib/skin_parser/skin_parser.c
@@ -621,11 +621,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
}
temp_params[j] = '\0';
j = 0;
- while (cursor[j] != ',' && cursor[j] != ')')
+ while (cursor[j] && cursor[j] != ',' && cursor[j] != ')')
{
haspercent = haspercent || (cursor[j] == '%');
hasdecimal = hasdecimal || (cursor[j] == '.');
- number = number && (isdigit(cursor[j]) || (cursor[j] == '.'));
+ number = number && (isdigit(cursor[j]) ||
+ (cursor[j] == '.') ||
+ (cursor[j] == '-'));
j++;
}
type_code = '*';
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c
index 9924d06619..9c0b51dacf 100644
--- a/lib/skin_parser/tag_table.c
+++ b/lib/skin_parser/tag_table.c
@@ -33,6 +33,8 @@ static const struct tag_info legal_tags[] =
{ SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "", 0 },
{ SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "", 0 },
+ { SKIN_TOKEN_LOGICAL_IF, "if", "TS[ITS]|D", SKIN_REFRESH_DYNAMIC },
+
{ SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC },
{ SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC },
{ SKIN_TOKEN_BATTERY_TIME, "bt", "", SKIN_REFRESH_DYNAMIC },
diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h
index 4b7efaa835..f16709d133 100644
--- a/lib/skin_parser/tag_table.h
+++ b/lib/skin_parser/tag_table.h
@@ -73,6 +73,7 @@ enum skin_token_type {
SKIN_TOKEN_SUBLINE_SCROLL,
/* Conditional */
+ SKIN_TOKEN_LOGICAL_IF,
SKIN_TOKEN_CONDITIONAL,
SKIN_TOKEN_CONDITIONAL_START,
SKIN_TOKEN_CONDITIONAL_OPTION,