From 281f1a1ed6f6213139fbc230dc819bbcbe3ee40a Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Sun, 14 Aug 2011 13:50:07 +0000 Subject: New skin tags: %Vs() to set the text style and %Vg() to get the viewports gradient colours %Vs(mode[, param]) : mode can be "invert", "color" (where param is the colour to use", "clear" to disable the current style, "gradient" where param is the number of lines the gradient should draw over. %Vg(start colour, end colour, [text colour]), if this tag isnt used the list selection colours from the settings will set the gradient colours git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30302 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/skin_engine/skin_display.c | 29 ++++++------- apps/gui/skin_engine/skin_display.h | 6 +-- apps/gui/skin_engine/skin_parser.c | 84 ++++++++++++++++++++++++++++++++++++ apps/gui/skin_engine/skin_render.c | 45 ++++++++++++++++--- apps/gui/skin_engine/skin_tokens.h | 1 + apps/gui/skin_engine/wps_internals.h | 13 ++++++ 6 files changed, 150 insertions(+), 28 deletions(-) (limited to 'apps') diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index a967114125..02e9d39711 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -450,15 +450,12 @@ int evaluate_conditional(struct gui_wps *gwps, int offset, line is the index of the line on the screen. scroll indicates whether the line is a scrolling one or not. */ -void write_line(struct screen *display, - struct align_pos *format_align, - int line, - bool scroll) +void write_line(struct screen *display, struct align_pos *format_align, + int line, bool scroll, unsigned style) { int left_width = 0, left_xpos; int center_width = 0, center_xpos; int right_width = 0, right_xpos; - int ypos; int space_width; int string_height; int scroll_width; @@ -565,22 +562,19 @@ void write_line(struct screen *display, right_width = 0; } - ypos = (line * string_height); - - if (scroll && ((left_width > scroll_width) || (center_width > scroll_width) || (right_width > scroll_width))) { - display->puts_scroll(0, line, - (unsigned char *)format_align->left); + display->puts_scroll_style(0, line, + (unsigned char *)format_align->left, style); } else { #ifdef HAVE_LCD_BITMAP /* clear the line first */ display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); - display->fillrect(left_xpos, ypos, display->getwidth(), string_height); + display->fillrect(left_xpos, line*string_height, display->getwidth(), string_height); display->set_drawmode(DRMODE_SOLID); #endif @@ -591,18 +585,19 @@ void write_line(struct screen *display, /* print aligned strings */ if (left_width != 0) { - display->putsxy(left_xpos, ypos, - (unsigned char *)format_align->left); + display->puts_style_xyoffset(left_xpos/space_width, line, + (unsigned char *)format_align->left, style, 0, 0); + } if (center_width != 0) { - display->putsxy(center_xpos, ypos, - (unsigned char *)format_align->center); + display->puts_style_xyoffset(center_xpos/space_width, line, + (unsigned char *)format_align->center, style, 0, 0); } if (right_width != 0) { - display->putsxy(right_xpos, ypos, - (unsigned char *)format_align->right); + display->puts_style_xyoffset(right_xpos/space_width, line, + (unsigned char *)format_align->right, style, 0, 0); } } } diff --git a/apps/gui/skin_engine/skin_display.h b/apps/gui/skin_engine/skin_display.h index da4bb92aef..9faaea30cf 100644 --- a/apps/gui/skin_engine/skin_display.h +++ b/apps/gui/skin_engine/skin_display.h @@ -48,10 +48,8 @@ int evaluate_conditional(struct gui_wps *gwps, int offset, line is the index of the line on the screen. scroll indicates whether the line is a scrolling one or not. */ -void write_line(struct screen *display, - struct align_pos *format_align, - int line, - bool scroll); +void write_line(struct screen *display, struct align_pos *format_align, + int line, bool scroll, unsigned style); void draw_peakmeters(struct gui_wps *gwps, int line_number, struct viewport *viewport); #endif diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 53e1efedd8..b7bb045411 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -453,6 +453,77 @@ static int parse_playlistview(struct skin_element *element, return 0; } #endif +#ifdef HAVE_LCD_COLOR +static int parse_viewport_gradient_setup(struct skin_element *element, + struct wps_token *token, + struct wps_data *wps_data) +{ + (void)wps_data; + struct gradient_config *cfg; + if (element->params_count < 2) /* only start and end are required */ + return 1; + cfg = (struct gradient_config *)skin_buffer_alloc(sizeof(struct gradient_config)); + if (!cfg) + return 1; + if (!parse_color(curr_screen, element->params[0].data.text, &cfg->start) || + !parse_color(curr_screen, element->params[1].data.text, &cfg->end)) + return 1; + if (element->params_count > 2) + { + if (!parse_color(curr_screen, element->params[2].data.text, &cfg->text)) + return 1; + } + else + { + cfg->text = curr_vp->vp.fg_pattern; + } + + token->value.data = cfg; + return 0; +} +#endif +static int parse_viewporttextstyle(struct skin_element *element, + struct wps_token *token, + struct wps_data *wps_data) +{ + (void)wps_data; + int style; + char *mode = element->params[0].data.text; + unsigned colour; + + if (!strcmp(mode, "invert")) + { + style = STYLE_INVERT; + } + else if (!strcmp(mode, "colour") || !strcmp(mode, "color")) + { + if (element->params_count < 2 || + !parse_color(curr_screen, element->params[1].data.text, &colour)) + return 1; + style = STYLE_COLORED|(STYLE_COLOR_MASK&colour); + } +#ifdef HAVE_LCD_COLOR + else if (!strcmp(mode, "gradient")) + { + int num_lines; + if (element->params_count < 2) + num_lines = 1; + else /* atoi() instead of using a number in the parser is because [si] + * will select the number for something which looks like a colour + * making the "colour" case (above) harder to parse */ + num_lines = atoi(element->params[1].data.text); + style = STYLE_GRADIENT|NUMLN_PACK(num_lines)|CURLN_PACK(0); + } +#endif + else if (!strcmp(mode, "clear")) + { + style = STYLE_DEFAULT; + } + else + return 1; + token->value.l = style; + return 0; +} #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) @@ -1514,6 +1585,11 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element) skin_vp->start_fgcolour = skin_vp->vp.fg_pattern; skin_vp->start_bgcolour = skin_vp->vp.bg_pattern; #endif +#ifdef HAVE_LCD_COLOR + skin_vp->start_gradient.start = skin_vp->vp.lss_pattern; + skin_vp->start_gradient.end = skin_vp->vp.lse_pattern; + skin_vp->start_gradient.text = skin_vp->vp.lst_pattern; +#endif struct skin_tag_parameter *param = element->params; @@ -1683,6 +1759,14 @@ static int skin_element_callback(struct skin_element* element, void* data) case SKIN_TOKEN_IMAGE_BACKDROP: function = parse_image_special; break; +#endif + case SKIN_TOKEN_VIEWPORT_TEXTSTYLE: + function = parse_viewporttextstyle; + break; +#ifdef HAVE_LCD_COLOR + case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP: + function = parse_viewport_gradient_setup; + break; #endif case SKIN_TOKEN_TRANSLATEDSTRING: case SKIN_TOKEN_SETTING: diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 13eb69c744..27e6747c29 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -55,6 +55,7 @@ struct skin_draw_info { struct skin_viewport *skin_vp; int line_number; unsigned long refresh_type; + unsigned text_style; char* cur_align_start; struct align_pos align; @@ -106,6 +107,19 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, col->vp->bg_pattern = col->colour; } break; + case SKIN_TOKEN_VIEWPORT_TEXTSTYLE: + info->text_style = token->value.l; + break; +#endif +#ifdef HAVE_LCD_COLOR + case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP: + { + struct gradient_config *cfg = token->value.data; + vp->lss_pattern = cfg->start; + vp->lse_pattern = cfg->end; + vp->lst_pattern = cfg->text; + } + break; #endif case SKIN_TOKEN_VIEWPORT_ENABLE: { @@ -614,7 +628,8 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps * .line_scrolls = false, .refresh_type = refresh_type, .skin_vp = skin_viewport, - .offset = 0 + .offset = 0, + .text_style = STYLE_DEFAULT }; struct align_pos * align = &info.align; @@ -636,7 +651,17 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps * info.no_line_break = false; info.line_scrolls = false; info.force_redraw = false; - +#ifdef HAVE_LCD_COLOR + if (info.text_style&STYLE_GRADIENT) + { + int cur = CURLN_UNPACK(info.text_style); + int num = NUMLN_UNPACK(info.text_style); + if (cur+1 == num) + info.text_style = STYLE_DEFAULT; + else + info.text_style = STYLE_GRADIENT|CURLN_PACK(cur+1)|NUMLN_PACK(num); + } +#endif info.cur_align_start = info.buf; align->left = info.buf; align->center = NULL; @@ -668,10 +693,10 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps * /* if the line is a scrolling one we don't want to update too often, so that it has the time to scroll */ if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw) - write_line(display, align, info.line_number, true); + write_line(display, align, info.line_number, true, info.text_style); } else - write_line(display, align, info.line_number, false); + write_line(display, align, info.line_number, false, info.text_style); } if (!info.no_line_break) info.line_number++; @@ -717,6 +742,11 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour; skin_viewport->vp.bg_pattern = skin_viewport->start_bgcolour; #endif +#ifdef HAVE_LCD_COLOR + skin_viewport->vp.lss_pattern = skin_viewport->start_gradient.start; + skin_viewport->vp.lse_pattern = skin_viewport->start_gradient.end; + skin_viewport->vp.lst_pattern = skin_viewport->start_gradient.text; +#endif /* dont redraw the viewport if its disabled */ if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) @@ -772,7 +802,8 @@ static __attribute__((noinline)) void skin_render_playlistviewer(struct playlist .line_scrolls = false, .refresh_type = refresh_type, .skin_vp = skin_viewport, - .offset = viewer->start_offset + .offset = viewer->start_offset, + .text_style = STYLE_DEFAULT }; struct align_pos * align = &info.align; @@ -829,10 +860,10 @@ static __attribute__((noinline)) void skin_render_playlistviewer(struct playlist /* if the line is a scrolling one we don't want to update too often, so that it has the time to scroll */ if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw) - write_line(display, align, info.line_number, true); + write_line(display, align, info.line_number, true, info.text_style); } else - write_line(display, align, info.line_number, false); + write_line(display, align, info.line_number, false, info.text_style); } info.line_number++; info.offset++; diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h index d259fe431c..9df2137ece 100644 --- a/apps/gui/skin_engine/skin_tokens.h +++ b/apps/gui/skin_engine/skin_tokens.h @@ -35,6 +35,7 @@ struct wps_token { union { char c; unsigned short i; + long l; void* data; } value; }; diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 6de98455a7..01f67d4a0b 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -161,6 +161,14 @@ enum wps_parse_error { PARSE_FAIL_COND_INVALID_PARAM, PARSE_FAIL_LIMITS_EXCEEDED, }; +#ifdef HAVE_LCD_COLOR +struct gradient_config { + unsigned start; + unsigned end; + unsigned text; + int lines_count; +}; +#endif #define VP_DRAW_HIDEABLE 0x1 #define VP_DRAW_HIDDEN 0x2 @@ -173,8 +181,13 @@ struct skin_viewport { char hidden_flags; bool is_infovp; char* label; +#if LCD_DEPTH > 1 unsigned start_fgcolour; unsigned start_bgcolour; +#ifdef HAVE_LCD_COLOR + struct gradient_config start_gradient; +#endif +#endif }; struct viewport_colour { struct viewport *vp; -- cgit v1.2.3