diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index a3cb689..2303c9e 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -477,7 +477,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, "eq")) + lif->op = IF_EQUALS; + if (!strcmp(op, "neq")) + lif->op = IF_NOTEQUALS; + if (!strcmp(op, "lt")) + lif->op = IF_LESSTHAN; + if (!strcmp(op, "lte")) + lif->op = IF_LESSTHAN_EQ; + if (!strcmp(op, "gt")) + lif->op = IF_GREATERTHAN; + if (!strcmp(op, "gte")) + lif->op = IF_GREATERTHAN_EQ; + + lif->operand_value = element->params[2].data.number; + if (element->params_count > 3) + lif->num_options = element->params[3].data.number; + else + lif->num_options = 10000; + return 0; + +} static int parse_timeout_tag(struct skin_element *element, struct wps_token *token, struct wps_data *wps_data) @@ -1227,6 +1259,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 fa6a5da..a8f3fc3 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -569,6 +569,32 @@ 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 val = lif->num_options; /* some crazy high value */ + out_text = get_token_value(gwps, lif->token, buf, buf_size, &val); + if (val == -1) + val = (out_text && *out_text) ? 1 : 0; + switch (lif->op) + { + case IF_EQUALS: + return val == lif->operand_value ? "eq" : NULL; + case IF_NOTEQUALS: + return val == lif->operand_value ? "neq" : NULL; + case IF_LESSTHAN: + return val == lif->operand_value ? "lt" : NULL; + case IF_LESSTHAN_EQ: + return val == lif->operand_value ? "lte" : NULL; + case IF_GREATERTHAN: + return val == lif->operand_value ? "gt" : NULL; + case IF_GREATERTHAN_EQ: + return val == lif->operand_value ? "gte" : NULL; + } + return NULL; + } + break; + case SKIN_TOKEN_CHARACTER: if (token->value.c == '\n') return NULL; diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 709dbc6..c713ced 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -215,7 +215,7 @@ struct skin_albumart { int draw_handle; }; #endif - + struct line { int timeout; /* if inside a line alternator */ @@ -232,6 +232,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; + int operand_value; + 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 f92a527..fba074f 100644 --- a/lib/skin_parser/skin_parser.c +++ b/lib/skin_parser/skin_parser.c @@ -673,6 +673,17 @@ static int skin_parse_tag(struct skin_element* element, const char** document) if(!element->params[i].data.code) return 0; } + else if (tolower(*tag_args) == 't') + { + struct skin_element* child = skin_alloc_element(); + child->type = TAG; + if (!skin_parse_tag(child, &cursor)) + return 0; + child->next = NULL; + element->params[i].type = CODE; + element->params[i].data.code = child; + } + skip_whitespace(&cursor); diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 26c049b..bd73fdd 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", "TSI|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 0266c2f..2535798 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, @@ -273,6 +274,7 @@ enum skin_token_type { * F - Required file name * f - Nullable file name * C - Required skin code + * T - Required single skin tag * N - any amount of strings.. must be the last param in the list * \n - causes the parser to eat everything up to and including the \n * MUST be the last character of the prams string