mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-07 05:35:02 -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;
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = '*';
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue