From 65f9df3083623484efccf502c33ecc959555d247 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Thu, 5 Jul 2012 22:44:13 +1000 Subject: skin_engine: Allow the %St() (setting) skin tag be used as a bar %St() or %St(, setting, ) Change-Id: I71396d683634d4d1ad2357018c4029ecb4229677 --- apps/gui/option_select.c | 25 +++++++++++++++++++++++++ apps/gui/option_select.h | 2 ++ apps/gui/skin_engine/skin_display.c | 8 ++++++++ apps/gui/skin_engine/skin_parser.c | 27 +++++++++++++++++++++++++++ apps/gui/skin_engine/skin_render.c | 1 + apps/gui/skin_engine/wps_internals.h | 2 ++ lib/skin_parser/tag_table.c | 5 +++-- lib/skin_parser/tag_table.h | 1 + manual/appendix/wps_tags.tex | 4 ++++ 9 files changed, 73 insertions(+), 2 deletions(-) diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c index ca206b86da..f85570d699 100644 --- a/apps/gui/option_select.c +++ b/apps/gui/option_select.c @@ -575,3 +575,28 @@ bool option_screen(const struct settings_list *setting, return false; } +int get_setting_info_for_bar(int setting_id, int *count, int *val) +{ + const struct settings_list *setting = &settings[setting_id]; + int var_type = setting->flags&F_T_MASK; + void (*function)(int) = NULL; + int oldvalue; + + if (var_type == F_T_INT || var_type == F_T_UINT) + { + oldvalue = *(int*)setting->setting; + } + else if (var_type == F_T_BOOL) + { + oldvalue = *(bool*)setting->setting?1:0; + } + else + { + *val = 0; + *count = 1; + return false; /* only int/bools can go here */ + } + + val_to_selection(setting, oldvalue, count, val, &function); + return true; +} diff --git a/apps/gui/option_select.h b/apps/gui/option_select.h index 0a7600ce80..3a14a179a6 100644 --- a/apps/gui/option_select.h +++ b/apps/gui/option_select.h @@ -48,4 +48,6 @@ void option_talk_value(const struct settings_list *setting, int value, bool enqu /* only use this for int and bool settings */ int option_value_as_int(const struct settings_list *setting); +int get_setting_info_for_bar(int setting_id, int *count, int *val); + #endif /* _GUI_OPTION_SELECT_H_ */ diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 08d17a0258..4f491dea24 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -44,6 +44,7 @@ #include "audio.h" #include "tagcache.h" #include "list.h" +#include "option_select.h" #ifdef HAVE_LCD_BITMAP #include "peakmeter.h" @@ -145,6 +146,13 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) end = val - min; length = max - min; } + else if (pb->type == SKIN_TOKEN_SETTINGBAR) + { + int val, count; + get_setting_info_for_bar(pb->setting_id, &count, &val); + length = count - 1; + end = val; + } #if CONFIG_TUNER else if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) { diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index f66961d488..cbc2ebed4e 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -736,6 +736,10 @@ static int parse_image_special(struct skin_element *element, #endif /* HAVE_LCD_BITMAP */ +static int parse_progressbar_tag(struct skin_element* element, + struct wps_token *token, + struct wps_data *wps_data); + static int parse_setting_and_lang(struct skin_element *element, struct wps_token *token, struct wps_data *wps_data) @@ -757,6 +761,13 @@ static int parse_setting_and_lang(struct skin_element *element, return WPS_ERROR_INVALID_PARAM; #endif } + else if (element->params_count > 1) + { + if (element->params_count > 4) + return parse_progressbar_tag(element, token, wps_data); + else + return WPS_ERROR_INVALID_PARAM; + } else { #ifndef __PCTOOL__ @@ -891,6 +902,7 @@ static int parse_progressbar_tag(struct skin_element* element, pb->image = PTRTOSKINOFFSET(skin_buffer, NULL); pb->slider = PTRTOSKINOFFSET(skin_buffer, NULL); pb->backdrop = PTRTOSKINOFFSET(skin_buffer, NULL); + pb->setting_id = -1; pb->invert_fill_direction = false; pb->horizontal = true; @@ -1015,6 +1027,19 @@ static int parse_progressbar_tag(struct skin_element* element, else if (!strcmp(text, "notouch")) suppress_touchregion = true; #endif + else if (token->type == SKIN_TOKEN_SETTING && !strcmp(text, "setting")) + { + if (curr_param+1 < element->params_count) + { + curr_param++; + param++; + text = SKINOFFSETTOPTR(skin_buffer, param->data.text); +#ifndef __PCTOOL__ + if (find_setting_by_cfgname(text, &pb->setting_id) == NULL) + return WPS_ERROR_INVALID_PARAM; +#endif + } + } else if (curr_param == 4) image_filename = text; @@ -1060,6 +1085,8 @@ static int parse_progressbar_tag(struct skin_element* element, token->type = SKIN_TOKEN_PEAKMETER_RIGHTBAR; else if (token->type == SKIN_TOKEN_LIST_NEEDS_SCROLLBAR) token->type = SKIN_TOKEN_LIST_SCROLLBAR; + else if (token->type == SKIN_TOKEN_SETTING) + token->type = SKIN_TOKEN_SETTINGBAR; pb->type = token->type; #ifdef HAVE_TOUCHSCREEN diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index bf7f03d738..0fdf6b019f 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -209,6 +209,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, #endif case SKIN_TOKEN_VOLUMEBAR: case SKIN_TOKEN_BATTERY_PERCENTBAR: + case SKIN_TOKEN_SETTINGBAR: #ifdef HAVE_LCD_BITMAP case SKIN_TOKEN_PROGRESSBAR: case SKIN_TOKEN_TUNER_RSSI_BAR: diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index ab2bc3579e..8cd5d9cb60 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -112,6 +112,8 @@ struct progressbar { OFFSETTYPE(struct gui_img *) slider; bool horizontal; OFFSETTYPE(struct gui_img *) backdrop; + int setting_id; /* for the setting bar type */ + }; struct draw_rectangle { diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 1842cb9f70..76139df04e 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -211,8 +211,9 @@ static const struct tag_info legal_tags[] = { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii", 0 }, { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f", SKIN_REFRESH_STATIC|NOBREAK }, - - { SKIN_TOKEN_SETTING, "St" , "S", SKIN_REFRESH_DYNAMIC }, + /* This uses the bar tag params also but the first item can be a string + * and we don't allow no params. */ + { SKIN_TOKEN_SETTING, "St" , "[Si]|iiis*", SKIN_REFRESH_DYNAMIC }, { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S", SKIN_REFRESH_STATIC }, { SKIN_TOKEN_LANG_IS_RTL, "Sr" , "", SKIN_REFRESH_STATIC }, diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index 932f4a5ffd..b29c6d79d8 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h @@ -246,6 +246,7 @@ enum skin_token_type { /* Setting option */ SKIN_TOKEN_SETTING, + SKIN_TOKEN_SETTINGBAR, SKIN_TOKEN_CURRENT_SCREEN, SKIN_TOKEN_LANG_IS_RTL, diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex index 14e0308940..220a308322 100644 --- a/manual/appendix/wps_tags.tex +++ b/manual/appendix/wps_tags.tex @@ -360,6 +360,8 @@ that, it will display the volume value. \config{\%St()} & The value of the Rockbox setting with the specified name. See \reference{ref:config_file_options} for the list of the available settings.\\ + \config{\%St(...)} & Draw a bar using from the setting. + See \reference{ref:bar_tags} for details.\\ \end{tagmap} Examples: @@ -715,6 +717,8 @@ display cycling round the defined sublines. See \opt{touchscreen}{ \item[notouch] -- don't create the touchregion for progress/volume bars. } + \item[setting] -- Specify the setting name to draw the bar from (bar must be + \%St type), the next param is the settings config name. \end{description} Example: \config{\%pb(0,0,-,-,-,nofill, slider, slider\_image, invert)} -- draw -- cgit v1.2.3