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
This commit is contained in:
Ben Basha 2006-02-10 13:57:11 +00:00
parent 1e385fdaeb
commit e0622ab588
7 changed files with 183 additions and 6 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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_ */

View File

@ -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;

View File

@ -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);