From eda80390d5afc4346d2e64a256762df7df30bb17 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Sun, 15 Aug 2010 14:13:36 +0000 Subject: A bunch of new features for the bar type tags (%pb, %pv, %bl, etc): * the bar orientation (horiz/vert) is now chosen based on the width and heigt values (or can be forced). * the fill direction can now be inverted (fill right to left, or top to bottom is considered inverted) * It can now draw a slider type bar instead of a fill type (or indeed a slider with a fill type) To configure the new bar, any (or all) of the following params can be used after the bmp filename (order makes no difference either): invert - cause the bar to fill in the inverted direction vertical - draw a vertical bar (not needed if the height > width) horizontal - draw a horizontal bar (this is obviously the default) nofill - dont draw the filling bar (this still draws the outline, obviously pointless without the slider param) slider - draw an image for the slider. The next param MUST be the label of the image to draw. No option to use a subimage here, so the whole image needs to be the image you want on the slider. example: %pb(0,0,-,-,-,nofill, slider, slider_image, invert) - draw a boring horizontal progressbar which doesnt fill and only draws the image "slider_image" which moves right to left. the slider type might need some tweaking. let us know how it goes git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27821 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/scrollbar.c | 21 +++++++++- apps/gui/scrollbar.h | 9 +++-- apps/gui/skin_engine/skin_display.c | 77 ++++++++++++++++++++++++++++++++---- apps/gui/skin_engine/skin_parser.c | 37 +++++++++++++++++ apps/gui/skin_engine/wps_internals.h | 5 +++ lib/skin_parser/tag_table.c | 2 +- 6 files changed, 136 insertions(+), 15 deletions(-) diff --git a/apps/gui/scrollbar.c b/apps/gui/scrollbar.c index 317c55cdc7..8f431a4ff8 100644 --- a/apps/gui/scrollbar.c +++ b/apps/gui/scrollbar.c @@ -88,6 +88,12 @@ void gui_scrollbar_draw(struct screen * screen, int x, int y, int infill; #endif + if (flags & INVERTFILL) + { + min_shown = items - max_shown; + max_shown = items; + } + inner_x = x + 1; inner_y = y + 1; inner_wd = width - 2; @@ -178,11 +184,18 @@ void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap *bm, int x, int start; int size; int inner_len; + int startx = 0, starty = 0; screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); /* clear pixels in progress bar */ screen->fillrect(x, y, width, height); + + if (flags & INVERTFILL) + { + min_shown = items - max_shown; + max_shown = items; + } if (flags & HORIZONTAL) inner_len = width; @@ -196,19 +209,23 @@ void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap *bm, int x, if (flags & HORIZONTAL) { x += start; width = size; + if (flags & INVERTFILL) + startx = start; } else { y += start; height = size; + if (flags & INVERTFILL) + starty = start; } #if LCD_DEPTH > 1 if (bm->format == FORMAT_MONO) #endif - screen->mono_bitmap_part(bm->data, 0, 0, + screen->mono_bitmap_part(bm->data, startx, starty, bm->width, x, y, width, height); #if LCD_DEPTH > 1 else - screen->transparent_bitmap_part((fb_data *)bm->data, 0, 0, + screen->transparent_bitmap_part((fb_data *)bm->data, startx, starty, STRIDE(screen->screen_type, bm->width, bm->height), x, y, width, height); diff --git a/apps/gui/scrollbar.h b/apps/gui/scrollbar.h index 03e1e6ec43..e5ffae79b0 100644 --- a/apps/gui/scrollbar.h +++ b/apps/gui/scrollbar.h @@ -28,12 +28,13 @@ enum orientation { VERTICAL = 0x0000, /* Vertical orientation */ HORIZONTAL = 0x0001, /* Horizontal orientation */ + INVERTFILL = 0x0002, /* Invert the fill direction */ #ifdef HAVE_LCD_COLOR - FOREGROUND = 0x0002, /* Do not clear background pixels */ - INNER_FILL = 0x0004, /* Fill inner part even if FOREGROUND */ - INNER_BGFILL = 0x0008, /* Fill inner part with background + FOREGROUND = 0x0020, /* Do not clear background pixels */ + INNER_FILL = 0x0040, /* Fill inner part even if FOREGROUND */ + INNER_BGFILL = 0x0080, /* Fill inner part with background color even if FOREGROUND */ - INNER_FILL_MASK = 0x000c, + INNER_FILL_MASK = 0x00c0, #endif }; diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 53b568ad53..8e08343d82 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -129,7 +129,10 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) struct wps_state *state = gwps->state; struct mp3entry *id3 = state->id3; int y = pb->y, height = pb->height; - unsigned long length, elapsed; + unsigned long length, end; + int flags = HORIZONTAL; + + int drawn_length, drawn_end; if (height < 0) height = font_get(vp->font)->height; @@ -148,39 +151,62 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) int minvol = sound_min(SOUND_VOLUME); int maxvol = sound_max(SOUND_VOLUME); length = maxvol-minvol; - elapsed = global_settings.volume-minvol; + end = global_settings.volume-minvol; } else if (pb->type == SKIN_TOKEN_BATTERY_PERCENTBAR) { length = 100; - elapsed = battery_level(); + end = battery_level(); } #if CONFIG_TUNER else if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) { int min = fm_region_data[global_settings.fm_region].freq_min; - elapsed = radio_current_frequency() - min; + end = radio_current_frequency() - min; length = fm_region_data[global_settings.fm_region].freq_max - min; } #endif else if (id3 && id3->length) { length = id3->length; - elapsed = id3->elapsed + state->ff_rewind_count; + end = id3->elapsed + state->ff_rewind_count; } else { length = 1; - elapsed = 0; + end = 0; + } + + if (pb->nofill) + { + drawn_length = 1; + drawn_end = 0; + } + else + { + drawn_length = length; + drawn_end = end; + } + + if (!pb->horizontal) + { + /* we want to fill upwards which is technically inverted. */ + flags = VERTICAL|INVERTFILL; + } + + if (pb->invert_fill_direction) + { + flags ^= INVERTFILL; } + if (pb->have_bitmap_pb) gui_bitmap_scrollbar_draw(display, &pb->bm, pb->x, y, pb->width, pb->bm.height, - length, 0, elapsed, HORIZONTAL); + drawn_length, 0, drawn_end, flags); else gui_scrollbar_draw(display, pb->x, y, pb->width, height, - length, 0, elapsed, HORIZONTAL); + drawn_length, 0, drawn_end, flags); if (pb->type == SKIN_TOKEN_PROGRESSBAR) { @@ -201,6 +227,41 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) { presets_draw_markers(display, pb->x, y, pb->width, height); } +#endif + } + + if (pb->slider) + { + int x = pb->x, y = pb->y; + int width = pb->width; + int height = pb->height; + struct gui_img *img = pb->slider; + + if (flags&VERTICAL) + { + y += pb->height*end/length; + height = img->bm.height; + } + else + { + x += pb->width*end/length; + width = img->bm.width; + } +#if LCD_DEPTH > 1 + if(img->bm.format == FORMAT_MONO) { +#endif + display->mono_bitmap_part(img->bm.data, + 0, 0, + img->bm.width, x, + y, width, height); +#if LCD_DEPTH > 1 + } else { + display->transparent_bitmap_part((fb_data *)img->bm.data, + 0, 0, + STRIDE(display->screen_type, + img->bm.width, img->bm.height), + x, y, width, height); + } #endif } } diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 68cb01470c..341056ff87 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -540,6 +540,7 @@ static int parse_progressbar_tag(struct skin_element* element, struct skin_token_list *item; struct viewport *vp = &curr_vp->vp; struct skin_tag_parameter *param = element->params; + int curr_param = 0; if (element->params_count == 0 && element->tag->type != SKIN_TOKEN_PROGRESSBAR) @@ -554,6 +555,7 @@ static int parse_progressbar_tag(struct skin_element* element, pb->have_bitmap_pb = false; pb->bm.data = NULL; /* no bitmap specified */ pb->follow_lang_direction = follow_lang_direction > 0; + pb->invert_fill_direction = false; if (element->params_count == 0) { @@ -614,6 +616,41 @@ static int parse_progressbar_tag(struct skin_element* element, if (!isdefault(param)) pb->bm.data = param->data.text; + curr_param = 5; + pb->invert_fill_direction = false; + pb->nofill = false; + pb->slider = NULL; + pb->horizontal = pb->width > pb->height; + while (curr_param < element->params_count) + { + param++; + if (!strcmp(param->data.text, "invert")) + pb->invert_fill_direction = true; + else if (!strcmp(param->data.text, "nofill")) + pb->nofill = true; + else if (!strcmp(param->data.text, "slider")) + { + if (curr_param+1 < element->params_count) + { + curr_param++; + param++; + pb->slider = find_image(param->data.text, wps_data); + if (!pb->slider) + return -1; + } + } + else if (!strcmp(param->data.text, "vertical")) + { + pb->horizontal = false; + if (isdefault(&element->params[3])) + pb->height = vp->height - pb->x; + } + else if (!strcmp(param->data.text, "horizontal")) + pb->horizontal = true; + + curr_param++; + } + if (token->type == SKIN_TOKEN_VOLUME) token->type = SKIN_TOKEN_VOLUMEBAR; diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index ccae11b91a..c886a7584f 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -106,6 +106,11 @@ struct progressbar { /*progressbar image*/ struct bitmap bm; bool have_bitmap_pb; + + bool invert_fill_direction; + bool nofill; + struct gui_img *slider; + bool horizontal; }; #endif diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index e7e30b1609..9924d06619 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -22,7 +22,7 @@ #include "tag_table.h" #include -#define BAR_PARAMS "*|iiiis" +#define BAR_PARAMS "*|iiiisN" /* The tag definition table */ static const struct tag_info legal_tags[] = { -- cgit v1.2.3