mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-07 13:45:03 -05:00
New skin tag: %if(<tag>, <operator>, <operand> [,option count]) which lets you do very simple logical comparissons on other tags.
<tag> is the tag to check against <operator> is the comparisson to do, any one of... =, !=, >, >=, <, <= (when comparring against a string tag like %ia only = and != work, and it is done NOT case sensitive) <operand> is either another tag, a number, or text. [option count] is an optinal number to use for the few tags which scale to the amount of options when used as a conditional (i.e %?pv<a|b|c|d> would have 4 options) example: %?if(%pv, >=, 0)<Warning.. volume clipping|coool...> That says "If the value from %pv (volume) is greater than or equal to 0 then display the warning line, otherwise the cool line." %?if(%ia, =, %Ia)<same artist> <= this artist and next artist are the same. some tags might need a touch of tweaking to work better with this. experiment and have fun git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27846 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
b73d15e9c6
commit
74ec011bb8
6 changed files with 150 additions and 14 deletions
|
|
@ -502,7 +502,39 @@ static int parse_setting_and_lang(struct skin_element *element,
|
||||||
token->value.i = i;
|
token->value.i = i;
|
||||||
return 0;
|
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,
|
static int parse_timeout_tag(struct skin_element *element,
|
||||||
struct wps_token *token,
|
struct wps_token *token,
|
||||||
struct wps_data *wps_data)
|
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:
|
case SKIN_TOKEN_ALIGN_LANGDIRECTION:
|
||||||
follow_lang_direction = 2;
|
follow_lang_direction = 2;
|
||||||
break;
|
break;
|
||||||
|
case SKIN_TOKEN_LOGICAL_IF:
|
||||||
|
function = parse_logical_if;
|
||||||
|
break;
|
||||||
case SKIN_TOKEN_PROGRESSBAR:
|
case SKIN_TOKEN_PROGRESSBAR:
|
||||||
case SKIN_TOKEN_VOLUME:
|
case SKIN_TOKEN_VOLUME:
|
||||||
case SKIN_TOKEN_BATTERY_PERCENT:
|
case SKIN_TOKEN_BATTERY_PERCENT:
|
||||||
|
|
|
||||||
|
|
@ -315,6 +315,8 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
|
||||||
|
|
||||||
if (intval)
|
if (intval)
|
||||||
{
|
{
|
||||||
|
if (limit == TOKEN_VALUE_ONLY)
|
||||||
|
limit = 100; /* make it a percentage */
|
||||||
*intval = limit * elapsed / length + 1;
|
*intval = limit * elapsed / length + 1;
|
||||||
}
|
}
|
||||||
snprintf(buf, buf_size, "%lu", 100 * elapsed / length);
|
snprintf(buf, buf_size, "%lu", 100 * elapsed / length);
|
||||||
|
|
@ -619,6 +621,72 @@ const char *get_token_value(struct gui_wps *gwps,
|
||||||
|
|
||||||
switch (token->type)
|
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:
|
case SKIN_TOKEN_CHARACTER:
|
||||||
if (token->value.c == '\n')
|
if (token->value.c == '\n')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -632,6 +700,8 @@ const char *get_token_value(struct gui_wps *gwps,
|
||||||
|
|
||||||
case SKIN_TOKEN_PLAYLIST_ENTRIES:
|
case SKIN_TOKEN_PLAYLIST_ENTRIES:
|
||||||
snprintf(buf, buf_size, "%d", playlist_amount());
|
snprintf(buf, buf_size, "%d", playlist_amount());
|
||||||
|
if (intval)
|
||||||
|
*intval = playlist_amount();
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
case SKIN_TOKEN_LIST_TITLE_TEXT:
|
case SKIN_TOKEN_LIST_TITLE_TEXT:
|
||||||
|
|
@ -647,6 +717,8 @@ const char *get_token_value(struct gui_wps *gwps,
|
||||||
|
|
||||||
case SKIN_TOKEN_PLAYLIST_POSITION:
|
case SKIN_TOKEN_PLAYLIST_POSITION:
|
||||||
snprintf(buf, buf_size, "%d", playlist_get_display_index()+offset);
|
snprintf(buf, buf_size, "%d", playlist_get_display_index()+offset);
|
||||||
|
if (intval)
|
||||||
|
*intval = playlist_get_display_index()+offset;
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
case SKIN_TOKEN_PLAYLIST_SHUFFLE:
|
case SKIN_TOKEN_PLAYLIST_SHUFFLE:
|
||||||
|
|
@ -661,7 +733,11 @@ const char *get_token_value(struct gui_wps *gwps,
|
||||||
if (intval)
|
if (intval)
|
||||||
{
|
{
|
||||||
int minvol = sound_min(SOUND_VOLUME);
|
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;
|
*intval = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -705,14 +781,21 @@ const char *get_token_value(struct gui_wps *gwps,
|
||||||
|
|
||||||
if (intval)
|
if (intval)
|
||||||
{
|
{
|
||||||
limit = MAX(limit, 3);
|
if (limit == TOKEN_VALUE_ONLY)
|
||||||
if (l > -1) {
|
{
|
||||||
/* First enum is used for "unknown level",
|
*intval = l;
|
||||||
* last enum is used for 100%.
|
}
|
||||||
*/
|
else
|
||||||
*intval = (limit - 2) * l / 100 + 2;
|
{
|
||||||
} else {
|
limit = MAX(limit, 3);
|
||||||
*intval = 1;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
#define WPS_ALIGN_LEFT 128
|
#define WPS_ALIGN_LEFT 128
|
||||||
|
|
||||||
|
|
||||||
#define TOKEN_VALUE_ONLY 0xDEADD0D0
|
#define TOKEN_VALUE_ONLY 0x0DEADC0D
|
||||||
|
|
||||||
#ifdef HAVE_ALBUMART
|
#ifdef HAVE_ALBUMART
|
||||||
|
|
||||||
|
|
@ -223,7 +223,7 @@ struct skin_albumart {
|
||||||
int draw_handle;
|
int draw_handle;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct line {
|
struct line {
|
||||||
int timeout; /* if inside a line alternator */
|
int timeout; /* if inside a line alternator */
|
||||||
|
|
@ -240,6 +240,19 @@ struct conditional {
|
||||||
struct wps_token *token;
|
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
|
/* wps_data
|
||||||
this struct holds all necessary data which describes the
|
this struct holds all necessary data which describes the
|
||||||
|
|
|
||||||
|
|
@ -621,11 +621,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
|
||||||
}
|
}
|
||||||
temp_params[j] = '\0';
|
temp_params[j] = '\0';
|
||||||
j = 0;
|
j = 0;
|
||||||
while (cursor[j] != ',' && cursor[j] != ')')
|
while (cursor[j] && cursor[j] != ',' && cursor[j] != ')')
|
||||||
{
|
{
|
||||||
haspercent = haspercent || (cursor[j] == '%');
|
haspercent = haspercent || (cursor[j] == '%');
|
||||||
hasdecimal = hasdecimal || (cursor[j] == '.');
|
hasdecimal = hasdecimal || (cursor[j] == '.');
|
||||||
number = number && (isdigit(cursor[j]) || (cursor[j] == '.'));
|
number = number && (isdigit(cursor[j]) ||
|
||||||
|
(cursor[j] == '.') ||
|
||||||
|
(cursor[j] == '-'));
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
type_code = '*';
|
type_code = '*';
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ static const struct tag_info legal_tags[] =
|
||||||
{ SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "", 0 },
|
{ SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "", 0 },
|
||||||
{ SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "", 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_PERCENT, "bl" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC },
|
||||||
{ SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC },
|
{ SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC },
|
||||||
{ SKIN_TOKEN_BATTERY_TIME, "bt", "", SKIN_REFRESH_DYNAMIC },
|
{ SKIN_TOKEN_BATTERY_TIME, "bt", "", SKIN_REFRESH_DYNAMIC },
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ enum skin_token_type {
|
||||||
SKIN_TOKEN_SUBLINE_SCROLL,
|
SKIN_TOKEN_SUBLINE_SCROLL,
|
||||||
|
|
||||||
/* Conditional */
|
/* Conditional */
|
||||||
|
SKIN_TOKEN_LOGICAL_IF,
|
||||||
SKIN_TOKEN_CONDITIONAL,
|
SKIN_TOKEN_CONDITIONAL,
|
||||||
SKIN_TOKEN_CONDITIONAL_START,
|
SKIN_TOKEN_CONDITIONAL_START,
|
||||||
SKIN_TOKEN_CONDITIONAL_OPTION,
|
SKIN_TOKEN_CONDITIONAL_OPTION,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue