A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

skin_engine: Support percentages for viewport positioning

%V(0,50%,75%,50%,-) - make a viewport at x=0, y=half the lcd height,
75% lcd width and the remaining height (the other half) of the lcd.

Change-Id: If26ccb65e8dc52c9225f3fd6d7b222d770add0f0
Reviewed-on: http://gerrit.rockbox.org/184
Reviewed-by: Thomas Martitz <kugel@rockbox.org>
Tested-by: Thomas Martitz <kugel@rockbox.org>
Reviewed-by: Jonathan Gordon <rockbox@jdgordon.info>

+33 -8
+8
apps/gui/skin_engine/skin_parser.c
··· 1995 1995 skin_vp->vp.x = param->data.number; 1996 1996 if (param->data.number < 0) 1997 1997 skin_vp->vp.x += display->lcdwidth; 1998 + else if (param->type == PERCENT) 1999 + skin_vp->vp.x = param->data.number * display->lcdwidth / 1000; 1998 2000 } 1999 2001 param++; 2000 2002 /* y */ ··· 2003 2005 skin_vp->vp.y = param->data.number; 2004 2006 if (param->data.number < 0) 2005 2007 skin_vp->vp.y += display->lcdheight; 2008 + else if (param->type == PERCENT) 2009 + skin_vp->vp.y = param->data.number * display->lcdheight / 1000; 2006 2010 } 2007 2011 param++; 2008 2012 /* width */ ··· 2011 2015 skin_vp->vp.width = param->data.number; 2012 2016 if (param->data.number < 0) 2013 2017 skin_vp->vp.width = (skin_vp->vp.width + display->lcdwidth) - skin_vp->vp.x; 2018 + else if (param->type == PERCENT) 2019 + skin_vp->vp.width = param->data.number * display->lcdwidth / 1000; 2014 2020 } 2015 2021 else 2016 2022 { ··· 2023 2029 skin_vp->vp.height = param->data.number; 2024 2030 if (param->data.number < 0) 2025 2031 skin_vp->vp.height = (skin_vp->vp.height + display->lcdheight) - skin_vp->vp.y; 2032 + else if (param->type == PERCENT) 2033 + skin_vp->vp.height = param->data.number * display->lcdheight / 1000; 2026 2034 } 2027 2035 else 2028 2036 {
+1
apps/gui/skin_engine/skin_tokens.c
··· 761 761 if (!number_set && out_text && *out_text >= '0' && *out_text <= '9') 762 762 a = atoi(out_text); 763 763 /* fall through */ 764 + case PERCENT: 764 765 case DECIMAL: 765 766 b = lif->operand.data.number; 766 767 break;
+17 -5
lib/skin_parser/skin_parser.c
··· 568 568 while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM) 569 569 { 570 570 /* Skipping over escaped characters */ 571 - if(*cursor == TAGSYM) 571 + if(*cursor == TAGSYM && *(cursor+1) != ARGLISTSEPARATESYM) 572 572 { 573 573 skip_tag(&cursor); 574 574 } ··· 625 625 * default > decimal/integer > single tag/code > string 626 626 */ 627 627 int j=0; 628 - bool canbedefault = false; 628 + bool canbedefault = false, last_char_is_percent = false; 629 629 bool haspercent = false, number = true, hasdecimal = false; 630 630 char temp_params[8]; 631 631 open_square_bracket = tag_args; ··· 644 644 hasdecimal = hasdecimal || (cursor[j] == '.'); 645 645 number = number && (isdigit(cursor[j]) || 646 646 (cursor[j] == '.') || 647 - (cursor[j] == '-')); 647 + (cursor[j] == '-') || 648 + (cursor[j] == '%')); 648 649 j++; 649 650 } 651 + last_char_is_percent = cursor[j-1] == '%'; 650 652 type_code = '?'; 651 653 if (canbedefault && *cursor == DEFAULTSYM && !isdigit(cursor[1])) 652 654 { ··· 656 658 { 657 659 type_code = 'd'; 658 660 } 661 + else if (number && last_char_is_percent && strchr(temp_params, 'p')) 662 + { 663 + type_code = 'p'; 664 + } 659 665 else if (number && 660 666 (strchr(temp_params, 'i') || strchr(temp_params, 'd'))) 661 667 { ··· 707 713 params[i].type = INTEGER; 708 714 params[i].data.number = scan_int(&cursor); 709 715 } 710 - else if(tolower(type_code) == 'd') 716 + else if(tolower(type_code) == 'd' || tolower(type_code) == 'p') 711 717 { 712 718 int val = 0; 713 719 bool have_point = false; ··· 731 737 } 732 738 if (have_tenth == false) 733 739 val *= 10; 734 - params[i].type = DECIMAL; 740 + if (tolower(type_code) == 'd') 741 + params[i].type = DECIMAL; 742 + else 743 + { 744 + params[i].type = PERCENT; 745 + cursor++; /* skip trailing % sign */ 746 + } 735 747 params[i].data.number = val; 736 748 } 737 749 else if(tolower(type_code) == 's' || tolower(type_code) == 'f')
+1
lib/skin_parser/skin_parser.h
··· 89 89 { 90 90 INTEGER, 91 91 DECIMAL, /* stored in data.number as (whole*10)+part */ 92 + PERCENT, /* stored in data.number as (whole*10)+part */ 92 93 STRING, 93 94 CODE, 94 95 DEFAULT
+3 -3
lib/skin_parser/tag_table.c
··· 206 206 { SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, "Vg" , "SS|s", SKIN_REFRESH_STATIC|NOBREAK }, 207 207 { SKIN_TOKEN_VIEWPORT_DRAWONBG, "VB" , "", SKIN_REFRESH_STATIC|NOBREAK }, 208 208 209 - { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii", 0 }, 210 - { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii", 0 }, 211 - { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii", 0 }, 209 + { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "S[IP][IP][ip][ip]i", 0 }, 210 + { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "s[IP][IP][ip][ip]i", 0 }, 211 + { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "[IP][IP][ip][ip]i", 0 }, 212 212 213 213 { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f", SKIN_REFRESH_STATIC|NOBREAK }, 214 214 /* This uses the bar tag params also but the first item can be a string
+3
lib/skin_parser/tag_table.h
··· 304 304 * D - Required decimal 305 305 * d - Nullable decimal 306 306 * Decimals are stored as (whole*10)+part 307 + * P - Required percentage 308 + * p - Nullable percentage 309 + * Percentages pestored as permilles (percent*10 + part) 307 310 * S - Required string 308 311 * s - Nullable string 309 312 * F - Required file name