diff options
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 37 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.c | 101 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 17 | ||||
-rw-r--r-- | lib/skin_parser/skin_parser.c | 6 | ||||
-rw-r--r-- | lib/skin_parser/tag_table.c | 2 | ||||
-rw-r--r-- | lib/skin_parser/tag_table.h | 1 |
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, |