Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+150 -14
+36 -1
apps/gui/skin_engine/skin_parser.c
··· 502 502 token->value.i = i; 503 503 return 0; 504 504 } 505 - 505 + static int parse_logical_if(struct skin_element *element, 506 + struct wps_token *token, 507 + struct wps_data *wps_data) 508 + { 509 + (void)wps_data; 510 + char *op = element->params[1].data.text; 511 + struct logical_if *lif = skin_buffer_alloc(sizeof(struct logical_if)); 512 + if (!lif) 513 + return -1; 514 + token->value.data = lif; 515 + lif->token = element->params[0].data.code->data; 516 + 517 + if (!strcmp(op, "=")) 518 + lif->op = IF_EQUALS; 519 + if (!strcmp(op, "!=")) 520 + lif->op = IF_NOTEQUALS; 521 + if (!strcmp(op, "<")) 522 + lif->op = IF_LESSTHAN; 523 + if (!strcmp(op, "<=")) 524 + lif->op = IF_LESSTHAN_EQ; 525 + if (!strcmp(op, ">")) 526 + lif->op = IF_GREATERTHAN; 527 + if (!strcmp(op, ">=")) 528 + lif->op = IF_GREATERTHAN_EQ; 529 + 530 + memcpy(&lif->operand, &element->params[2], sizeof(lif->operand)); 531 + if (element->params_count > 3) 532 + lif->num_options = element->params[3].data.number; 533 + else 534 + lif->num_options = TOKEN_VALUE_ONLY; 535 + return 0; 536 + 537 + } 506 538 static int parse_timeout_tag(struct skin_element *element, 507 539 struct wps_token *token, 508 540 struct wps_data *wps_data) ··· 1297 1329 { 1298 1330 case SKIN_TOKEN_ALIGN_LANGDIRECTION: 1299 1331 follow_lang_direction = 2; 1332 + break; 1333 + case SKIN_TOKEN_LOGICAL_IF: 1334 + function = parse_logical_if; 1300 1335 break; 1301 1336 case SKIN_TOKEN_PROGRESSBAR: 1302 1337 case SKIN_TOKEN_VOLUME:
+92 -9
apps/gui/skin_engine/skin_tokens.c
··· 315 315 316 316 if (intval) 317 317 { 318 + if (limit == TOKEN_VALUE_ONLY) 319 + limit = 100; /* make it a percentage */ 318 320 *intval = limit * elapsed / length + 1; 319 321 } 320 322 snprintf(buf, buf_size, "%lu", 100 * elapsed / length); ··· 619 621 620 622 switch (token->type) 621 623 { 624 + case SKIN_TOKEN_LOGICAL_IF: 625 + { 626 + struct logical_if *lif = token->value.data; 627 + int a = lif->num_options; 628 + int b; 629 + out_text = get_token_value(gwps, lif->token, offset, buf, buf_size, &a); 630 + if (a == -1 && lif->token->type != SKIN_TOKEN_VOLUME) 631 + a = (out_text && *out_text) ? 1 : 0; 632 + switch (lif->operand.type) 633 + { 634 + case STRING: 635 + if (lif->op == IF_EQUALS) 636 + return strcmp(out_text, lif->operand.data.text) == 0 ? 637 + "eq" : NULL; 638 + else 639 + return NULL; 640 + break; 641 + case INTEGER: 642 + case DECIMAL: 643 + b = lif->operand.data.number; 644 + break; 645 + case CODE: 646 + { 647 + char temp_buf[MAX_PATH]; 648 + const char *outb; 649 + struct wps_token *token = lif->operand.data.code->data; 650 + b = lif->num_options; 651 + outb = get_token_value(gwps, token, offset, temp_buf, 652 + sizeof(temp_buf), &b); 653 + if (b == -1 && lif->token->type != SKIN_TOKEN_VOLUME) 654 + { 655 + if (!out_text || !outb) 656 + return (lif->op == IF_EQUALS) ? NULL : "neq"; 657 + bool equal = strcmp(out_text, outb) == 0; 658 + if (lif->op == IF_EQUALS) 659 + return equal ? "eq" : NULL; 660 + else if (lif->op == IF_NOTEQUALS) 661 + return !equal ? "neq" : NULL; 662 + else 663 + b = (outb && *outb) ? 1 : 0; 664 + } 665 + } 666 + break; 667 + case DEFAULT: 668 + break; 669 + } 670 + 671 + switch (lif->op) 672 + { 673 + case IF_EQUALS: 674 + return a == b ? "eq" : NULL; 675 + case IF_NOTEQUALS: 676 + return a != b ? "neq" : NULL; 677 + case IF_LESSTHAN: 678 + return a < b ? "lt" : NULL; 679 + case IF_LESSTHAN_EQ: 680 + return a <= b ? "lte" : NULL; 681 + case IF_GREATERTHAN: 682 + return a > b ? "gt" : NULL; 683 + case IF_GREATERTHAN_EQ: 684 + return a >= b ? "gte" : NULL; 685 + } 686 + return NULL; 687 + } 688 + break; 689 + 622 690 case SKIN_TOKEN_CHARACTER: 623 691 if (token->value.c == '\n') 624 692 return NULL; ··· 632 700 633 701 case SKIN_TOKEN_PLAYLIST_ENTRIES: 634 702 snprintf(buf, buf_size, "%d", playlist_amount()); 703 + if (intval) 704 + *intval = playlist_amount(); 635 705 return buf; 636 706 637 707 case SKIN_TOKEN_LIST_TITLE_TEXT: ··· 647 717 648 718 case SKIN_TOKEN_PLAYLIST_POSITION: 649 719 snprintf(buf, buf_size, "%d", playlist_get_display_index()+offset); 720 + if (intval) 721 + *intval = playlist_get_display_index()+offset; 650 722 return buf; 651 723 652 724 case SKIN_TOKEN_PLAYLIST_SHUFFLE: ··· 661 733 if (intval) 662 734 { 663 735 int minvol = sound_min(SOUND_VOLUME); 664 - if (global_settings.volume == minvol) 736 + if (limit == TOKEN_VALUE_ONLY) 737 + { 738 + *intval = global_settings.volume; 739 + } 740 + else if (global_settings.volume == minvol) 665 741 { 666 742 *intval = 1; 667 743 } ··· 705 781 706 782 if (intval) 707 783 { 708 - limit = MAX(limit, 3); 709 - if (l > -1) { 710 - /* First enum is used for "unknown level", 711 - * last enum is used for 100%. 712 - */ 713 - *intval = (limit - 2) * l / 100 + 2; 714 - } else { 715 - *intval = 1; 784 + if (limit == TOKEN_VALUE_ONLY) 785 + { 786 + *intval = l; 787 + } 788 + else 789 + { 790 + limit = MAX(limit, 3); 791 + if (l > -1) { 792 + /* First enum is used for "unknown level", 793 + * last enum is used for 100%. 794 + */ 795 + *intval = (limit - 2) * l / 100 + 2; 796 + } else { 797 + *intval = 1; 798 + } 716 799 } 717 800 } 718 801
+15 -2
apps/gui/skin_engine/wps_internals.h
··· 50 50 #define WPS_ALIGN_LEFT 128 51 51 52 52 53 - #define TOKEN_VALUE_ONLY 0xDEADD0D0 53 + #define TOKEN_VALUE_ONLY 0x0DEADC0D 54 54 55 55 #ifdef HAVE_ALBUMART 56 56 ··· 223 223 int draw_handle; 224 224 }; 225 225 #endif 226 - 226 + 227 227 228 228 struct line { 229 229 int timeout; /* if inside a line alternator */ ··· 240 240 struct wps_token *token; 241 241 }; 242 242 243 + struct logical_if { 244 + struct wps_token *token; 245 + enum { 246 + IF_EQUALS, /* == */ 247 + IF_NOTEQUALS, /* != */ 248 + IF_LESSTHAN, /* < */ 249 + IF_LESSTHAN_EQ, /* <= */ 250 + IF_GREATERTHAN, /* > */ 251 + IF_GREATERTHAN_EQ /* >= */ 252 + } op; 253 + struct skin_tag_parameter operand; 254 + int num_options; 255 + }; 243 256 244 257 /* wps_data 245 258 this struct holds all necessary data which describes the
+4 -2
lib/skin_parser/skin_parser.c
··· 621 621 } 622 622 temp_params[j] = '\0'; 623 623 j = 0; 624 - while (cursor[j] != ',' && cursor[j] != ')') 624 + while (cursor[j] && cursor[j] != ',' && cursor[j] != ')') 625 625 { 626 626 haspercent = haspercent || (cursor[j] == '%'); 627 627 hasdecimal = hasdecimal || (cursor[j] == '.'); 628 - number = number && (isdigit(cursor[j]) || (cursor[j] == '.')); 628 + number = number && (isdigit(cursor[j]) || 629 + (cursor[j] == '.') || 630 + (cursor[j] == '-')); 629 631 j++; 630 632 } 631 633 type_code = '*';
+2
lib/skin_parser/tag_table.c
··· 33 33 { SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "", 0 }, 34 34 { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "", 0 }, 35 35 36 + { SKIN_TOKEN_LOGICAL_IF, "if", "TS[ITS]|D", SKIN_REFRESH_DYNAMIC }, 37 + 36 38 { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC }, 37 39 { SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC }, 38 40 { SKIN_TOKEN_BATTERY_TIME, "bt", "", SKIN_REFRESH_DYNAMIC },
+1
lib/skin_parser/tag_table.h
··· 73 73 SKIN_TOKEN_SUBLINE_SCROLL, 74 74 75 75 /* Conditional */ 76 + SKIN_TOKEN_LOGICAL_IF, 76 77 SKIN_TOKEN_CONDITIONAL, 77 78 SKIN_TOKEN_CONDITIONAL_START, 78 79 SKIN_TOKEN_CONDITIONAL_OPTION,