From 216ed29e4dc709ac696f256e851accb8f093d1ea Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Thu, 2 Sep 2010 11:43:33 +0000 Subject: fix FS#11588 - %t(0) inside conditionals wasnt making that subline skip git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27983 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/skin_engine/skin_display.c | 17 ++++---- apps/gui/skin_engine/skin_render.c | 83 +++++++++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 32 deletions(-) (limited to 'apps') diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 8e08343d82..d76b57976d 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -503,12 +503,7 @@ int evaluate_conditional(struct gui_wps *gwps, int offset, char result[128]; const char *value; - /* treat ?xx constructs as if they had 2 options. - * (i.e ?xx) */ - if (num_options < 2) - num_options = 2; - - int intval = num_options; + int intval = num_options < 2 ? 2 : num_options; /* get_token_value needs to know the number of options in the enum */ value = get_token_value(gwps, conditional->token, offset, result, sizeof(result), &intval); @@ -516,11 +511,15 @@ int evaluate_conditional(struct gui_wps *gwps, int offset, /* intval is now the number of the enum option we want to read, starting from 1. If intval is -1, we check if value is empty. */ if (intval == -1) - intval = (value && *value) ? 1 : num_options; + { + if (num_options == 1) /* so %?AA */ + intval = (value && *value) ? 1 : 0; /* returned as 0 for true, -1 for false */ + else + intval = (value && *value) ? 1 : num_options; + } else if (intval > num_options || intval < 1) intval = num_options; - - conditional->last_value = intval -1; + return intval -1; } diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 46ae16b1ab..9f392f144f 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -394,22 +394,19 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i last_value = conditional->last_value; value = evaluate_conditional(info->gwps, info->offset, conditional, child->children_count); - - if (value != 1 && value >= child->children_count) - value = child->children_count-1; + conditional->last_value = value; if (child->children_count == 1) { /* special handling so * %?aa and %? need special handlng here */ - if (value == 1) /* tag is false */ + if (value == -1) /* tag is false */ { /* we are in a false branch of a %?aa conditional */ if (last_value == 0) do_tags_in_hidden_conditional(child->children[0], info); break; } - value = 0; } else { @@ -482,6 +479,38 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i return needs_update; } +static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line) +{ + struct skin_element *element=line; + struct wps_token *token; + int retval = -1; + if (element->type == LINE) + element = element->children[0]; + while (element) + { + if (element->type == TAG && + element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) + { + token = element->data; + return token->value.i; + } + else if (element->type == CONDITIONAL) + { + struct conditional *conditional = element->data; + int val = evaluate_conditional(gwps, 0, conditional, + element->children_count); + if (val >= 0) + { + retval = get_subline_timeout(gwps, element->children[val]); + if (retval >= 0) + return retval; + } + } + element = element->next; + } + return retval; +} + bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info) { bool changed_lines = false; @@ -500,30 +529,38 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info int next_change = alternator->last_change_tick + line->timeout; if (TIME_AFTER(current_tick, next_change)) { - alternator->current_line++; - if (alternator->current_line >= element->children_count) - alternator->current_line = 0; alternator->last_change_tick = current_tick; changed_lines = true; } } - if (element->children[alternator->current_line]->children_count == 0) - { - int old_line = alternator->current_line; - int line = alternator->current_line+1; - /* skip empty sublines */ - while (line!=old_line && element->children[line]->children_count == 0) - { - line++; - if (line >= element->children_count) - line = 0; - } - alternator->current_line = line; - changed_lines = true; - } - if (changed_lines) { + struct skin_element *current_line = element->children[alternator->current_line]; + int start = alternator->current_line; + int try_line = start; + bool suitable = false; + + /* find a subline which has at least one token in it, + * and that line doesnt have a timeout set to 0 through conditionals */ + do { + try_line++; + if (try_line >= element->children_count) + try_line = 0; + if (element->children[try_line]->children_count != 0) + { + current_line = element->children[try_line]; + if ((current_line->children[0]->type != CONDITIONAL) || + get_subline_timeout(info->gwps, current_line->children[0]) > 0) + { + suitable = true; + } + } + } + while (try_line != start && !suitable); + + if (suitable) + alternator->current_line = try_line; + info->refresh_type = SKIN_REFRESH_ALL; info->force_redraw = true; } -- cgit v1.2.3