From e0622ab588583d1148af54c0e856ae63339a3491 Mon Sep 17 00:00:00 2001 From: Ben Basha Date: Fri, 10 Feb 2006 13:57:11 +0000 Subject: add a bitmap progress bar option + add %P|filename.bmp| tag to the WPS git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8648 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/gwps-common.c | 76 +++++++++++++++++++++++++++++++++++++---- apps/gui/gwps.c | 1 + apps/gui/gwps.h | 6 ++++ apps/gui/scrollbar.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ apps/gui/scrollbar.h | 4 +++ apps/screen_access.c | 5 +++ apps/screen_access.h | 6 ++++ 7 files changed, 183 insertions(+), 6 deletions(-) (limited to 'apps') diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index 34d868f6a2..c918fddf5c 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -190,6 +190,61 @@ bool wps_data_preload_tags(struct wps_data *data, char *buf, break; #endif + case 'P': + /* progress bar image */ + { + int ret = 0; + char *ptr = buf+2; + char *pos = NULL; + char imgname[MAX_PATH]; + + /* format: %P|filename.bmp| */ + { + /* get filename */ + pos = strchr(ptr, '|'); + if ((pos - ptr) < + (int)sizeof(imgname)-ROCKBOX_DIR_LEN-2) + { + memcpy(imgname, bmpdir, bmpdirlen); + imgname[bmpdirlen] = '/'; + memcpy(&imgname[bmpdirlen+1], + ptr, pos - ptr); + imgname[bmpdirlen+1+pos-ptr] = 0; + } + else + /* filename too long */ + imgname[0] = 0; + + ptr = pos+1; + + /* load the image */ + data->progressbar.bm.data=data->img_buf_ptr; + ret = read_bmp_file(imgname, &data->progressbar.bm, + data->img_buf_free, + FORMAT_ANY|FORMAT_TRANSPARENT); + + if (ret > 0) + { +#if LCD_DEPTH == 16 + if (ret % 2) ret++; + /* Always consume an even number of bytes */ +#endif + + data->img_buf_ptr += ret; + data->img_buf_free -= ret; + + if (data->progressbar.bm.width <= LCD_WIDTH) { + data->progressbar.have_bitmap_pb=true; + return true; + } else + return false; + } + + } + } + + break; + case 'x': /* Preload images so the %xd# tag can display it */ { @@ -1536,12 +1591,21 @@ bool gui_wps_refresh(struct gui_wps *gwps, int ffwd_offset, if (!data->progress_end) data->progress_end=display->width; - gui_scrollbar_draw(display, data->progress_start, sb_y, - data->progress_end-data->progress_start, - data->progress_height, - state->id3->length?state->id3->length:1, 0, - state->id3->length?state->id3->elapsed + state->ff_rewind_count:0, - HORIZONTAL); + if (gwps->data->progressbar.have_bitmap_pb) + gui_bitmap_scrollbar_draw(display, data->progressbar.bm, + data->progress_start, sb_y, + data->progress_end-data->progress_start, + data->progressbar.bm.height, + state->id3->length?state->id3->length:1, 0, + state->id3->length?state->id3->elapsed + state->ff_rewind_count:0, + HORIZONTAL); + else + gui_scrollbar_draw(display, data->progress_start, sb_y, + data->progress_end-data->progress_start, + data->progress_height, + state->id3->length?state->id3->length:1, 0, + state->id3->length?state->id3->elapsed + state->ff_rewind_count:0, + HORIZONTAL); #ifdef AB_REPEAT_ENABLE if ( ab_repeat_mode_enabled() ) ab_draw_markers(display, state->id3->length, 0, sb_y, diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c index 024c3cc79f..166b2ec770 100644 --- a/apps/gui/gwps.c +++ b/apps/gui/gwps.c @@ -811,6 +811,7 @@ void wps_data_init(struct wps_data *wps_data) } wps_data->wps_sb_tag = false; wps_data->show_sb_on_wps = false; + wps_data->progressbar.have_bitmap_pb=false; #else /* HAVE_LCD_CHARCELLS */ for(i = 0; i < 8; i++) wps_data->wps_progress_pat[i] = 0; diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h index 4d586147af..2f63a4d1e4 100644 --- a/apps/gui/gwps.h +++ b/apps/gui/gwps.h @@ -263,6 +263,11 @@ struct gui_img{ bool display; /* is to be displayed */ bool always_display; /* not using the preload/display mechanism */ }; + +struct prog_img{ /*progressbar image*/ + struct bitmap bm; + bool have_bitmap_pb; +}; #endif struct align_pos { @@ -293,6 +298,7 @@ struct wps_data { #ifdef HAVE_LCD_BITMAP struct gui_img img[MAX_IMAGES]; + struct prog_img progressbar; unsigned char img_buf[IMG_BUFSIZE]; unsigned char* img_buf_ptr; int img_buf_free; diff --git a/apps/gui/scrollbar.c b/apps/gui/scrollbar.c index 73c523f56a..4cf92f4b47 100644 --- a/apps/gui/scrollbar.c +++ b/apps/gui/scrollbar.c @@ -21,6 +21,7 @@ #ifdef HAVE_LCD_BITMAP #include "config.h" #include "limits.h" +#include "bmp.h" void gui_scrollbar_draw(struct screen * screen, int x, int y, int width, int height, int items, @@ -101,4 +102,94 @@ void gui_scrollbar_draw(struct screen * screen, int x, int y, else screen->fillrect(x + start + 1, y + 1, size, height - 2); } + +void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y, + int width, int height, int items, + int min_shown, int max_shown, + enum orientation orientation) +{ + int min; + int max; + int inner_len; + int start; + int size; + + screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + + /* clear pixels in progress bar */ + screen->fillrect(x, y, width, height); + + /* min should be min */ + if(min_shown < max_shown) { + min = min_shown; + max = max_shown; + } + else { + min = max_shown; + max = min_shown; + } + + /* limit min and max */ + if(min < 0) + min = 0; + if(min > items) + min = items; + + if(max < 0) + max = 0; + if(max > items) + max = items; + + if (orientation == VERTICAL) + inner_len = height; + else + inner_len = width; + + /* avoid overflows */ + while (items > (INT_MAX / inner_len)) { + items >>= 1; + min >>= 1; + max >>= 1; + } + + /* calc start and end of the knob */ + if (items > 0 && items > (max - min)) { + size = inner_len * (max - min) / items; + if (size == 0) { /* width of knob is null */ + size = 1; + start = (inner_len - 1) * min / items; + } else { + start = (inner_len - size) * min / (items - (max - min)); + } + } else { /* if null draw full bar */ + size = inner_len; + start = 0; + } + + screen->set_drawmode(DRMODE_SOLID); + + if(orientation == VERTICAL) { +#if LCD_DEPTH > 1 + if (bm.format == FORMAT_MONO) +#endif + screen->mono_bitmap_part(bm.data, 0, 0, + bm.width, x, y + start, width, size); +#if LCD_DEPTH > 1 + else + screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0, + bm.width, x, y + start, width, size); +#endif + } else { +#if LCD_DEPTH > 1 + if (bm.format == FORMAT_MONO) +#endif + screen->mono_bitmap_part(bm.data, 0, 0, + bm.width, x + start, y, size, height); +#if LCD_DEPTH > 1 + else + screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0, + bm.width, x + start, y, size, height); +#endif + } +} #endif /* HAVE_LCD_BITMAP */ diff --git a/apps/gui/scrollbar.h b/apps/gui/scrollbar.h index d7d0be7a7e..541cc2d4df 100644 --- a/apps/gui/scrollbar.h +++ b/apps/gui/scrollbar.h @@ -44,5 +44,9 @@ extern void gui_scrollbar_draw(struct screen * screen, int x, int y, int width, int height, int items, int min_shown, int max_shown, enum orientation orientation); +extern void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y, + int width, int height, int items, + int min_shown, int max_shown, + enum orientation orientation); #endif /* HAVE_LCD_BITMAP */ #endif /* _GUI_SCROLLBAR_H_ */ diff --git a/apps/screen_access.c b/apps/screen_access.c index a1f615cd16..4aa2cad67f 100644 --- a/apps/screen_access.c +++ b/apps/screen_access.c @@ -52,6 +52,7 @@ void screen_init(struct screen * screen, enum screen_type screen_type) screen->getstringsize=&lcd_remote_getstringsize; screen->putsxy=&lcd_remote_putsxy; screen->mono_bitmap=&lcd_remote_mono_bitmap; + screen->mono_bitmap_part=&lcd_remote_mono_bitmap_part; screen->set_drawmode=&lcd_remote_set_drawmode; #if LCD_REMOTE_DEPTH > 1 screen->get_background=&lcd_remote_get_background; @@ -121,14 +122,18 @@ void screen_init(struct screen * screen, enum screen_type screen_type) screen->getstringsize=&lcd_getstringsize; screen->putsxy=&lcd_putsxy; screen->mono_bitmap=&lcd_mono_bitmap; + screen->mono_bitmap_part=&lcd_mono_bitmap_part; screen->set_drawmode=&lcd_set_drawmode; #if LCD_DEPTH > 1 screen->bitmap=&lcd_bitmap; + screen->bitmap_part=&lcd_bitmap_part; #if LCD_DEPTH == 2 /* No transparency yet for grayscale lcd */ screen->transparent_bitmap=&lcd_bitmap; + screen->transparent_bitmap_part=&lcd_bitmap_part; #else screen->transparent_bitmap=&lcd_bitmap_transparent; + screen->transparent_bitmap_part=&lcd_bitmap_transparent_part; #endif screen->get_background=&lcd_get_background; screen->get_foreground=&lcd_get_foreground; diff --git a/apps/screen_access.h b/apps/screen_access.h index 7b8018dc41..ae0a962015 100644 --- a/apps/screen_access.h +++ b/apps/screen_access.h @@ -82,10 +82,16 @@ struct screen int style, int offset); void (*mono_bitmap)(const unsigned char *src, int x, int y, int width, int height); + void (*mono_bitmap_part)(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); void (*bitmap)(const fb_data *src, int x, int y, int width, int height); + void (*bitmap_part)(const fb_data *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); void (*transparent_bitmap)(const fb_data *src, int x, int y, int width, int height); + void (*transparent_bitmap_part)(const fb_data *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); void (*set_drawmode)(int mode); #if (LCD_DEPTH > 1) || (LCD_REMOTE_DEPTH > 1) unsigned (*get_background)(void); -- cgit v1.2.3