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
This commit is contained in:
Jonathan Gordon 2010-09-02 11:43:33 +00:00
parent 5cc11a1914
commit 216ed29e4d
2 changed files with 68 additions and 32 deletions

View file

@ -503,12 +503,7 @@ int evaluate_conditional(struct gui_wps *gwps, int offset,
char result[128]; char result[128];
const char *value; const char *value;
/* treat ?xx<true> constructs as if they had 2 options. int intval = num_options < 2 ? 2 : num_options;
* (i.e ?xx<true|false>) */
if (num_options < 2)
num_options = 2;
int intval = num_options;
/* get_token_value needs to know the number of options in the enum */ /* get_token_value needs to know the number of options in the enum */
value = get_token_value(gwps, conditional->token, offset, value = get_token_value(gwps, conditional->token, offset,
result, sizeof(result), &intval); 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, /* 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. */ starting from 1. If intval is -1, we check if value is empty. */
if (intval == -1) if (intval == -1)
intval = (value && *value) ? 1 : num_options; {
if (num_options == 1) /* so %?AA<true> */
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) else if (intval > num_options || intval < 1)
intval = num_options; intval = num_options;
conditional->last_value = intval -1;
return intval -1; return intval -1;
} }

View file

@ -394,22 +394,19 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
last_value = conditional->last_value; last_value = conditional->last_value;
value = evaluate_conditional(info->gwps, info->offset, value = evaluate_conditional(info->gwps, info->offset,
conditional, child->children_count); conditional, child->children_count);
conditional->last_value = value;
if (value != 1 && value >= child->children_count)
value = child->children_count-1;
if (child->children_count == 1) if (child->children_count == 1)
{ {
/* special handling so /* special handling so
* %?aa<true> and %?<true|false> need special handlng here */ * %?aa<true> and %?<true|false> 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<true> conditional */ /* we are in a false branch of a %?aa<true> conditional */
if (last_value == 0) if (last_value == 0)
do_tags_in_hidden_conditional(child->children[0], info); do_tags_in_hidden_conditional(child->children[0], info);
break; break;
} }
value = 0;
} }
else else
{ {
@ -482,6 +479,38 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
return needs_update; 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 skin_render_alternator(struct skin_element* element, struct skin_draw_info *info)
{ {
bool changed_lines = false; 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; int next_change = alternator->last_change_tick + line->timeout;
if (TIME_AFTER(current_tick, next_change)) 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; alternator->last_change_tick = current_tick;
changed_lines = true; 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) 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->refresh_type = SKIN_REFRESH_ALL;
info->force_redraw = true; info->force_redraw = true;
} }