1
0
Fork 0
forked from len0rd/rockbox

skin_engine: New tag to draw a rectangle (optionally with a gradient)

%dr(x, y, width, height, [colour1[, colour2]]):
x,y - viewport relative pixel coordinates to start the rectangle.
width, height - obvious. can be '-' to fill the viewport
if both colours are left out the viewports foreground colour will be used
if one colour is specified it will fill the rectangle that colour.
if both colours are specified it will gradient fill the rectangle.

Change-Id: Iad451e99ded663bc7c5d182443659db7d909b388
This commit is contained in:
Jonathan Gordon 2012-03-15 22:50:17 +11:00
parent dcc78cb867
commit 014a08cabb
9 changed files with 105 additions and 6 deletions

View file

@ -638,6 +638,51 @@ static int parse_viewporttextstyle(struct skin_element *element,
return 0; return 0;
} }
static int parse_drawrectangle( struct skin_element *element,
struct wps_token *token,
struct wps_data *wps_data)
{
(void)wps_data;
struct draw_rectangle *rect =
(struct draw_rectangle *)skin_buffer_alloc(sizeof(struct draw_rectangle));
if (!rect)
return -1;
rect->x = get_param(element, 0)->data.number;
rect->y = get_param(element, 1)->data.number;
if (isdefault(get_param(element, 2)))
rect->width = curr_vp->vp.width - rect->x;
else
rect->width = get_param(element, 2)->data.number;
if (isdefault(get_param(element, 3)))
rect->height = curr_vp->vp.height - rect->y;
else
rect->height = get_param(element, 3)->data.number;
rect->start_colour = curr_vp->vp.fg_pattern;
rect->end_colour = curr_vp->vp.fg_pattern;
if (element->params_count > 4)
{
if (!parse_color(curr_screen, get_param_text(element, 4),
&rect->start_colour))
return -1;
rect->end_colour = rect->start_colour;
}
if (element->params_count > 5)
{
if (!parse_color(curr_screen, get_param_text(element, 5),
&rect->end_colour))
return -1;
}
token->value.data = PTRTOSKINOFFSET(skin_buffer, rect);
return 0;
}
static int parse_viewportcolour(struct skin_element *element, static int parse_viewportcolour(struct skin_element *element,
struct wps_token *token, struct wps_token *token,
struct wps_data *wps_data) struct wps_data *wps_data)
@ -2013,6 +2058,9 @@ static int skin_element_callback(struct skin_element* element, void* data)
sb_skin_has_title(curr_screen); sb_skin_has_title(curr_screen);
#endif #endif
break; break;
case SKIN_TOKEN_DRAWRECTANGLE:
function = parse_drawrectangle;
break;
#endif #endif
case SKIN_TOKEN_FILE_DIRECTORY: case SKIN_TOKEN_FILE_DIRECTORY:
token->value.i = get_param(element, 0)->data.number; token->value.i = get_param(element, 0)->data.number;

View file

@ -176,8 +176,29 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
if (do_refresh) if (do_refresh)
draw_peakmeters(gwps, info->line_number, vp); draw_peakmeters(gwps, info->line_number, vp);
break; break;
case SKIN_TOKEN_DRAWRECTANGLE:
if (do_refresh)
{
struct draw_rectangle *rect =
SKINOFFSETTOPTR(skin_buffer, token->value.data);
#ifdef HAVE_LCD_COLOR
if (rect->start_colour != rect->end_colour &&
gwps->display->screen_type == SCREEN_MAIN)
{
gwps->display->gradient_fillrect(rect->x, rect->y, rect->width,
rect->height, rect->start_colour, rect->end_colour);
}
else
#endif #endif
#ifdef HAVE_LCD_BITMAP {
unsigned backup = vp->fg_pattern;
vp->fg_pattern = rect->start_colour;
gwps->display->fillrect(rect->x, rect->y, rect->width,
rect->height);
vp->fg_pattern = backup;
}
}
break;
case SKIN_TOKEN_PEAKMETER_LEFTBAR: case SKIN_TOKEN_PEAKMETER_LEFTBAR:
case SKIN_TOKEN_PEAKMETER_RIGHTBAR: case SKIN_TOKEN_PEAKMETER_RIGHTBAR:
data->peak_meter_enabled = true; data->peak_meter_enabled = true;

View file

@ -113,6 +113,15 @@ struct progressbar {
bool horizontal; bool horizontal;
OFFSETTYPE(struct gui_img *) backdrop; OFFSETTYPE(struct gui_img *) backdrop;
}; };
struct draw_rectangle {
int x;
int y;
int width;
int height;
unsigned start_colour;
unsigned end_colour;
};
#endif #endif

View file

@ -264,6 +264,9 @@ struct screen screens[NB_SCREENS] =
#endif #endif
#if defined(HAVE_LCD_BITMAP) #if defined(HAVE_LCD_BITMAP)
.set_framebuffer = (void*)lcd_set_framebuffer, .set_framebuffer = (void*)lcd_set_framebuffer,
#if defined(HAVE_LCD_COLOR)
.gradient_fillrect = lcd_gradient_fillrect,
#endif
#endif #endif
}, },
#if NB_SCREENS == 2 #if NB_SCREENS == 2

View file

@ -162,6 +162,10 @@ struct screen
#endif #endif
#if defined(HAVE_LCD_BITMAP) #if defined(HAVE_LCD_BITMAP)
void (*set_framebuffer)(void *framebuffer); void (*set_framebuffer)(void *framebuffer);
#if defined(HAVE_LCD_COLOR)
void (*gradient_fillrect)(int x, int y, int width, int height,
unsigned start, unsigned end);
#endif
#endif #endif
}; };

View file

@ -41,14 +41,18 @@
#endif #endif
#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) #if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR)
void lcd_gradient_fillrect(int x1, int x2, int y1, int y2, void lcd_gradient_fillrect(int x, int y, int width, int height,
unsigned start_rgb, unsigned end_rgb) unsigned start_rgb, unsigned end_rgb)
{ {
int old_pattern = current_vp->fg_pattern; int old_pattern = current_vp->fg_pattern;
int step_mul, i; int step_mul, i;
if (y2 - y1 == 0) return; int x1, x2;
x1 = x;
x2 = x + width;
if (height == 0) return;
step_mul = (1 << 16) / (y2 - y1); step_mul = (1 << 16) / height;
int h_r = RGB_UNPACK_RED(start_rgb); int h_r = RGB_UNPACK_RED(start_rgb);
int h_g = RGB_UNPACK_GREEN(start_rgb); int h_g = RGB_UNPACK_GREEN(start_rgb);
int h_b = RGB_UNPACK_BLUE(start_rgb); int h_b = RGB_UNPACK_BLUE(start_rgb);
@ -59,7 +63,7 @@ void lcd_gradient_fillrect(int x1, int x2, int y1, int y2,
h_g = (h_g << 16) + (1 << 15); h_g = (h_g << 16) + (1 << 15);
h_b = (h_b << 16) + (1 << 15); h_b = (h_b << 16) + (1 << 15);
for(i = y1; i < y2; i++) { for(i = y; i < y + height; i++) {
current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
lcd_hline(x1, x2, i); lcd_hline(x1, x2, i);
h_r -= rstep; h_r -= rstep;
@ -108,7 +112,7 @@ static void lcd_do_gradient_line(int x1, int x2, int y, unsigned h,
h_g -= h * gstep; h_g -= h * gstep;
h_b -= h * bstep; h_b -= h * bstep;
end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
lcd_gradient_fillrect(x1, x2, y, y + h, start_rgb, end_rgb); lcd_gradient_fillrect(x1, y, x2 - x1, h, start_rgb, end_rgb);
} }
#endif #endif

View file

@ -244,6 +244,7 @@ static const struct tag_info legal_tags[] =
{ SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC }, { SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC },
{ SKIN_TOKEN_SUBSTRING, "ss", "IiT|s", SKIN_REFRESH_DYNAMIC }, { SKIN_TOKEN_SUBSTRING, "ss", "IiT|s", SKIN_REFRESH_DYNAMIC },
{ SKIN_TOKEN_DRAWRECTANGLE, "dr", "IIii|ss", SKIN_REFRESH_STATIC },
{ SKIN_TOKEN_UNKNOWN, "" , "", 0 } { SKIN_TOKEN_UNKNOWN, "" , "", 0 }
/* Keep this here to mark the end of the table */ /* Keep this here to mark the end of the table */
}; };

View file

@ -288,6 +288,8 @@ enum skin_token_type {
SKIN_TOKEN_VAR_TIMEOUT, SKIN_TOKEN_VAR_TIMEOUT,
SKIN_TOKEN_SUBSTRING, SKIN_TOKEN_SUBSTRING,
SKIN_TOKEN_DRAWRECTANGLE,
}; };
/* /*

View file

@ -100,6 +100,13 @@ show the information for the next song to be played.
\config{\%Fl('id',filename)} & See section \ref{ref:multifont}.\\ \config{\%Fl('id',filename)} & See section \ref{ref:multifont}.\\
\end{tagmap} \end{tagmap}
\section{Misc Coloring Tags}
\begin{tagmap}
\config{\%dr(x,y,width,height,[color1,color2])} & Color a rectangle. \\
\end{tagmap}
width and height can be - to fill the viewport. If no color is
specified the viewports foreground color will be used. If two
colors are specified it will do a gradient fill.
} }
\section{Power Related Information} \section{Power Related Information}