Index: apps/screen_access.c =================================================================== --- apps/screen_access.c (revision 17684) +++ apps/screen_access.c (working copy) @@ -51,11 +51,8 @@ .has_disk_led=true, #endif .set_viewport=&lcd_set_viewport, - .setmargins=&lcd_setmargins, .getwidth=&lcd_getwidth, .getheight=&lcd_getheight, - .getymargin=&lcd_getymargin, - .getxmargin=&lcd_getxmargin, .getstringsize=&lcd_getstringsize, #ifdef HAVE_LCD_BITMAP .setfont=&lcd_setfont, @@ -142,11 +139,8 @@ .pixel_format=LCD_REMOTE_PIXELFORMAT, .has_disk_led=false, .set_viewport=&lcd_remote_set_viewport, - .setmargins=&lcd_remote_setmargins, .getwidth=&lcd_remote_getwidth, .getheight=&lcd_remote_getheight, - .getymargin=&lcd_remote_getymargin, - .getxmargin=&lcd_remote_getxmargin, .getstringsize=&lcd_remote_getstringsize, #if 1 /* all remote LCDs are bitmapped so far */ .setfont=&lcd_remote_setfont, Index: apps/misc.h =================================================================== --- apps/misc.h (revision 17684) +++ apps/misc.h (working copy) @@ -129,6 +129,7 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename); /* A simplified scanf */ -const char* parse_list(const char *fmt, const char sep, const char* str, ...); +const char* parse_list(const char *fmt, unsigned int *valid_vals, + const char sep, const char* str, ...); #endif /* MISC_H */ Index: apps/playlist.c =================================================================== --- apps/playlist.c (revision 17684) +++ apps/playlist.c (working copy) @@ -1758,15 +1758,6 @@ } fmt = P2STR(fmt); - lcd_clear_display(); - -#ifdef HAVE_LCD_BITMAP - if(global_settings.statusbar) - lcd_setmargins(0, STATUSBAR_HEIGHT); - else - lcd_setmargins(0, 0); -#endif - gui_syncsplash(0, fmt, count, str(LANG_OFF_ABORT)); } Index: apps/screen_access.h =================================================================== --- apps/screen_access.h (revision 17684) +++ apps/screen_access.h (working copy) @@ -72,11 +72,8 @@ bool has_buttonbar; #endif void (*set_viewport)(struct viewport* vp); - void (*setmargins)(int x, int y); int (*getwidth)(void); int (*getheight)(void); - int (*getxmargin)(void); - int (*getymargin)(void); int (*getstringsize)(const unsigned char *str, int *w, int *h); #if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD) /* always bitmap */ void (*setfont)(int newfont); @@ -155,32 +152,6 @@ void (*backlight_set_timeout)(int index); }; -#ifdef HAVE_BUTTONBAR -/* - * Sets if the given screen has a buttonbar or not - * - screen : the screen structure - * - has : a boolean telling wether the current screen will have a buttonbar or not - */ -#define screen_has_buttonbar(screen, has_btnb) \ - (screen)->has_buttonbar=has_btnb; -#endif - -/* - * Sets the x margin in pixels for the given screen - * - screen : the screen structure - * - xmargin : the number of pixels to the left of the screen - */ -#define screen_set_xmargin(screen, xmargin) \ - (screen)->setmargins(xmargin, (screen)->getymargin()); - -/* - * Sets the y margin in pixels for the given screen - * - screen : the screen structure - * - xmargin : the number of pixels to the top of the screen - */ -#define screen_set_ymargin(screen, ymargin) \ - (screen)->setmargins((screen)->getxmargin(), ymargin); - #if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD) /* * Clear only a given area of the screen Index: apps/recorder/recording.c =================================================================== --- apps/recorder/recording.c (revision 17684) +++ apps/recorder/recording.c (working copy) @@ -68,6 +68,7 @@ #include "action.h" #include "radio.h" #include "sound_menu.h" +#include "viewport.h" #ifdef HAVE_RECORDING /* This array holds the record timer interval lengths, in seconds */ @@ -882,6 +883,8 @@ int base_style = STYLE_INVERT; int style; + struct viewport vp[NB_SCREENS]; + int ymargin = global_settings.cursor_style?0:10; #ifdef HAVE_LCD_COLOR if (global_settings.cursor_style == 2) { base_style |= STYLE_COLORBAR; @@ -956,11 +959,12 @@ FOR_NB_SCREENS(i) { - screens[i].setfont(FONT_SYSFIXED); + viewport_set_defaults(&vp[i], i); + vp[i].font = FONT_SYSFIXED; + screens[i].set_viewport(&vp[i]); screens[i].getstringsize("M", &w, &h); - screens[i].setmargins(global_settings.cursor_style ? 0 : w, 8); - filename_offset[i] = ((screens[i].height >= 80) ? 1 : 0); - pm_y[i] = 8 + h * (2 + filename_offset[i]); + filename_offset[i] = ((vp[i].height >= 80) ? 1 : 0); + pm_y[i] = h * (2 + filename_offset[i]); } #ifdef HAVE_REMOTE_LCD @@ -968,8 +972,8 @@ { screens[1].clear_display(); snprintf(buf, sizeof(buf), str(LANG_REMOTE_LCD_ON)); - screens[1].puts((screens[1].width/w - strlen(buf))/2 + 1, - screens[1].height/(h*2) + 1, buf); + screens[1].puts((vp[1].width/w - strlen(buf))/2 + 1, + vp[1].height/(h*2) + 1, buf); screens[1].update(); gui_syncsplash(0, str(LANG_REMOTE_LCD_OFF)); } @@ -1363,9 +1367,8 @@ FOR_NB_SCREENS(i) { + screens[i].set_viewport(&vp[i]); screens[i].setfont(FONT_SYSFIXED); - screens[i].setmargins( - global_settings.cursor_style ? 0 : w, 8); } } } @@ -1613,7 +1616,9 @@ else { for(i = 0; i < screen_update; i++) - screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 2, buf); + screens[i].putsxy(ymargin, + SYSFONT_HEIGHT*(filename_offset[i]+ + PM_HEIGHT + 2), buf); } if(global_settings.rec_source == AUDIO_SRC_MIC) @@ -1632,8 +1637,9 @@ else { for(i = 0; i < screen_update; i++) - screens[i].puts(0, filename_offset[i] + - PM_HEIGHT + 3, buf); + screens[i].putsxy(ymargin, + SYSFONT_HEIGHT*(filename_offset[i] + + PM_HEIGHT + 3), buf); } } else if(0 @@ -1664,8 +1670,9 @@ else { for(i = 0; i < screen_update; i++) - screens[i].puts(0, filename_offset[i] + - PM_HEIGHT + 3, buf); + screens[i].putsxy(ymargin, + SYSFONT_HEIGHT*(filename_offset[i] + + PM_HEIGHT + 3), buf); } snprintf(buf, sizeof(buf), "%s:%s", @@ -1688,8 +1695,9 @@ else { for(i = 0; i < screen_update; i++) - screens[i].puts(0, filename_offset[i] + - PM_HEIGHT + 4, buf); + screens[i].putsxy(ymargin, + SYSFONT_HEIGHT*(filename_offset[i] + + PM_HEIGHT + 4), buf); } } #ifdef HAVE_LCD_COLOR @@ -1721,7 +1729,7 @@ break; } /* end switch */ #ifdef HAVE_AGC - if (screens[i].height < h * (2 + filename_offset[i] + + if (vp[i].height < h * (2 + filename_offset[i] + PM_HEIGHT + line[i])) { line[i] -= 1; @@ -1785,8 +1793,9 @@ { for(i = 0; i < screen_update; i++) { if (display_agc[i]) { - screens[i].puts(0, filename_offset[i] + - PM_HEIGHT + line[i], buf); + screens[i].putsxy(ymargin, + SYSFONT_HEIGHT*(filename_offset[i] + + PM_HEIGHT + line[i]), buf); } } } @@ -1859,7 +1868,9 @@ for(i = 0; i < screen_update; i++) { + screens[i].set_viewport(NULL); gui_statusbar_draw(&(statusbars.statusbars[i]), true); + screens[i].set_viewport(&vp[i]); peak_meter_screen(&screens[i], pm_x, pm_y[i], h*PM_HEIGHT); screens[i].update(); } @@ -1867,11 +1878,11 @@ /* draw the trigger status */ FOR_NB_SCREENS(i) { - trig_width[i] = ((screens[i].height < 64) || - ((screens[i].height < 72) && (PM_HEIGHT > 1))) ? + trig_width[i] = ((vp[i].height < 64) || + ((vp[i].height < 72) && (PM_HEIGHT > 1))) ? screens[i].width - 14 * w : screens[i].width; trig_xpos[i] = screens[i].width - trig_width[i]; - trig_ypos[i] = ((screens[i].height < 72) && (PM_HEIGHT > 1)) ? + trig_ypos[i] = ((vp[i].height < 72) && (PM_HEIGHT > 1)) ? h*2 : h*(1 + filename_offset[i] + PM_HEIGHT + line[i] Index: apps/plugins/test_viewports.c =================================================================== --- apps/plugins/test_viewports.c (revision 17684) +++ apps/plugins/test_viewports.c (working copy) @@ -43,8 +43,6 @@ .height = 20, .font = FONT_UI, .drawmode = DRMODE_SOLID, - .xmargin = 0, - .ymargin = 0, #if LCD_DEPTH > 1 .fg_pattern = LCD_DEFAULT_FG, .bg_pattern = BGCOLOR_1, @@ -64,8 +62,6 @@ .height = LCD_HEIGHT / 2, .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, - .xmargin = 0, - .ymargin = 0, #if LCD_DEPTH > 1 .fg_pattern = LCD_DEFAULT_FG, .bg_pattern = LCD_DEFAULT_BG, @@ -85,8 +81,6 @@ .height = (LCD_HEIGHT / 2), .font = FONT_UI, .drawmode = DRMODE_SOLID, - .xmargin = 0, - .ymargin = 0, #if LCD_DEPTH > 1 .fg_pattern = FGCOLOR_1, .bg_pattern = BGCOLOR_2, @@ -107,8 +101,6 @@ .height = (LCD_HEIGHT / 4), .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, - .xmargin = 0, - .ymargin = 0, #if LCD_DEPTH > 1 .fg_pattern = LCD_BLACK, .bg_pattern = LCD_WHITE, @@ -130,8 +122,6 @@ .height = LCD_REMOTE_HEIGHT - 10, .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, - .xmargin = 0, - .ymargin = 0, #if LCD_REMOTE_DEPTH > 1 .fg_pattern = LCD_REMOTE_BLACK, .bg_pattern = LCD_REMOTE_LIGHTGRAY, @@ -146,8 +136,6 @@ .height = LCD_REMOTE_HEIGHT - 10, .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, - .xmargin = 0, - .ymargin = 0, #if LCD_REMOTE_DEPTH > 1 .fg_pattern = LCD_REMOTE_DEFAULT_FG, .bg_pattern = LCD_REMOTE_DEFAULT_BG @@ -253,8 +241,6 @@ .y = 0, .width = 5, .height = 1, - .xmargin = 0, - .ymargin = 0, }; static struct viewport vp1 = @@ -263,8 +249,6 @@ .y = 0, .width = 5, .height = 1, - .xmargin = 0, - .ymargin = 0, }; static struct viewport vp2 = @@ -273,8 +257,6 @@ .y = 1, .width = LCD_WIDTH, .height = 1, - .xmargin = 0, - .ymargin = 0, }; Index: apps/plugins/solitaire.c =================================================================== --- apps/plugins/solitaire.c (revision 17684) +++ apps/plugins/solitaire.c (working copy) @@ -744,7 +744,6 @@ break; case 2: - rb->lcd_setmargins(0, 0); if (solitaire_help() == HELP_USB) result = MENU_USB; break; @@ -766,7 +765,6 @@ } } menu_exit(m); - rb->lcd_setmargins(0, 0); return result; } Index: apps/plugins/test_disk.c =================================================================== --- apps/plugins/test_disk.c (revision 17684) +++ apps/plugins/test_disk.c (working copy) @@ -77,7 +77,6 @@ { int h; - rb->lcd_setmargins(0, 0); rb->lcd_getstringsize("A", NULL, &h); max_line = LCD_HEIGHT / h; line = 0; Index: apps/plugins/viewer.c =================================================================== --- apps/plugins/viewer.c (revision 17684) +++ apps/plugins/viewer.c (working copy) @@ -1421,7 +1421,6 @@ result = menu_run(m); menu_exit(m); #ifdef HAVE_LCD_BITMAP - rb->lcd_setmargins(0,0); /* Show-scrollbar mode for current view-width mode */ init_need_scrollbar(); @@ -1459,9 +1458,6 @@ break; } menu_exit(m); -#ifdef HAVE_LCD_BITMAP - rb->lcd_setmargins(0,0); -#endif viewer_draw(col); } Index: apps/plugins/test_codec.c =================================================================== --- apps/plugins/test_codec.c (revision 17684) +++ apps/plugins/test_codec.c (working copy) @@ -44,7 +44,6 @@ { int h; - rb->lcd_setmargins(0, 0); rb->lcd_getstringsize("A", NULL, &h); max_line = LCD_HEIGHT / h; line = 0; Index: apps/plugins/test_fps.c =================================================================== --- apps/plugins/test_fps.c (revision 17684) +++ apps/plugins/test_fps.c (working copy) @@ -57,14 +57,12 @@ { int h; - rb->lcd_setmargins(0, 0); rb->lcd_getstringsize("A", NULL, &h); max_line = LCD_HEIGHT / h; line = 0; rb->lcd_clear_display(); rb->lcd_update(); #ifdef HAVE_REMOTE_LCD - rb->lcd_remote_setmargins(0, 0); rb->lcd_remote_getstringsize("A", NULL, &h); remote_max_line = LCD_REMOTE_HEIGHT / h; remote_line = 0; Index: apps/gui/gwps-common.c =================================================================== --- apps/gui/gwps-common.c (revision 17684) +++ apps/gui/gwps-common.c (working copy) @@ -333,7 +333,6 @@ /* Update the values in the first (default) viewport - in case the user has modified the statusbar or colour settings */ #ifdef HAVE_LCD_BITMAP - gui_wps[i].data->viewports[0].vp.ymargin = gui_wps[i].display->getymargin(); #if LCD_DEPTH > 1 if (gui_wps[i].display->depth > 1) { @@ -494,53 +493,33 @@ #ifdef HAVE_LCD_BITMAP -static void draw_progressbar(struct gui_wps *gwps, int line) +static void draw_progressbar(struct gui_wps *gwps, + struct progressbar *pb) { - struct wps_data *data = gwps->data; struct screen *display = gwps->display; struct wps_state *state = gwps->state; - int h = font_get(display->getfont())->height; - - int sb_y; - if (data->progress_top < 0) - sb_y = line*h + display->getymargin() + - ((h > data->progress_height + 1) - ? (h - data->progress_height) / 2 : 1); - else - sb_y = data->progress_top; - - if (!data->progress_end) - data->progress_end=display->getwidth(); - - 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, + if (pb->have_bitmap_pb) + gui_bitmap_scrollbar_draw(display, pb->bm, + pb->x, pb->y, pb->width, pb->bm.height, state->id3->length ? state->id3->length : 1, 0, state->id3->length ? state->id3->elapsed - + state->ff_rewind_count : 0, - HORIZONTAL); + + 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, + gui_scrollbar_draw(display, pb->x, pb->y, pb->width, pb->height, state->id3->length ? state->id3->length : 1, 0, state->id3->length ? state->id3->elapsed - + state->ff_rewind_count : 0, - HORIZONTAL); - + + state->ff_rewind_count : 0, + HORIZONTAL); #ifdef AB_REPEAT_ENABLE if ( ab_repeat_mode_enabled() && state->id3->length != 0 ) ab_draw_markers(display, state->id3->length, - data->progress_start, data->progress_end, sb_y, - data->progress_height); + pb->x, pb->x + pb->width, pb->y, pb->height); #endif if ( cuesheet_is_enabled() && state->id3->cuesheet_type ) cue_draw_markers(display, state->id3->length, - data->progress_start, data->progress_end, - sb_y+1, data->progress_height-2); + pb->x, pb->x + pb->width, pb->y+1, pb->height-2); } /* clears the area where the image was shown */ @@ -1415,14 +1394,6 @@ else return NULL; #endif - -#ifdef HAVE_LCD_BITMAP - case WPS_TOKEN_LEFTMARGIN: - gwps->display->setmargins(token->value.i, - gwps->display->getymargin()); - return NULL; -#endif - default: return NULL; } @@ -1536,11 +1507,6 @@ align->center = NULL; align->right = NULL; -#ifdef HAVE_LCD_BITMAP - /* Reset margins - only bitmap targets modify them */ - gwps->display->setmargins(0, gwps->display->getymargin()); -#endif - /* Process all tokens of the desired subline */ last_token_idx = wps_last_token_index(data, line, subline); for (i = wps_first_token_index(data, line, subline); @@ -1608,7 +1574,24 @@ *buf++ = 0; cur_align_start = buf; break; - + case WPS_VIEWPORT_ENABLE: + { + char label = data->tokens[i].value.i; + int j; + char temp = VP_DRAW_HIDEABLE; + for(j=0;jnum_viewports;j++) + { + temp = VP_DRAW_HIDEABLE; + if ((data->viewports[j].hidden_flags&VP_DRAW_HIDEABLE) && + (data->viewports[j].label == label)) + { + if (data->viewports[j].hidden_flags&VP_DRAW_WASHIDDEN) + temp |= VP_DRAW_WASHIDDEN; + data->viewports[j].hidden_flags = temp; + } + } + } + break; default: { /* get the value of the tag and copy it to the buffer */ @@ -1790,7 +1773,7 @@ ¢er_width, &string_height); } - left_xpos = display->getxmargin(); + left_xpos = 0; right_xpos = (display->getwidth() - right_width); center_xpos = (display->getwidth() + left_xpos - center_width) / 2; @@ -1875,7 +1858,7 @@ right_width = 0; } - ypos = (line * string_height) + display->getymargin(); + ypos = (line * string_height); if (scroll && ((left_width > scroll_width) || @@ -1932,6 +1915,7 @@ int v, line, i, subline_idx; unsigned char flags; char linebuf[MAX_PATH]; + unsigned char vp_refresh_mode; struct align_pos align; align.left = NULL; @@ -1957,7 +1941,8 @@ /* reset to first subline if refresh all flag is set */ if (refresh_mode == WPS_REFRESH_ALL) { - display->clear_display(); + display->set_viewport(&data->viewports[0].vp); + display->clear_viewport(); for (i = 0; i <= data->num_lines; i++) { @@ -1981,14 +1966,21 @@ state->ff_rewind_count = ffwd_offset; + /* disable any viewports which are conditionally displayed */ for (v = 0; v < data->num_viewports; v++) { - display->set_viewport(&data->viewports[v].vp); - - if (refresh_mode == WPS_REFRESH_ALL) + if (data->viewports[v].hidden_flags&VP_DRAW_HIDEABLE) { - display->clear_viewport(); + if (data->viewports[v].hidden_flags&VP_DRAW_HIDDEN) + data->viewports[v].hidden_flags |= VP_DRAW_WASHIDDEN; + else + data->viewports[v].hidden_flags |= VP_DRAW_HIDDEN; } + } + for (v = 0; v < data->num_viewports; v++) + { + display->set_viewport(&data->viewports[v].vp); + vp_refresh_mode = refresh_mode; #ifdef HAVE_LCD_BITMAP /* Set images to not to be displayed */ @@ -1997,7 +1989,26 @@ data->img[i].display = -1; } #endif - + /* dont redraw the viewport if its disabled */ + if ((data->viewports[v].hidden_flags&VP_DRAW_HIDDEN)) + { + if (!(data->viewports[v].hidden_flags&VP_DRAW_WASHIDDEN)) + display->scroll_stop(&data->viewports[v].vp); + data->viewports[v].hidden_flags |= VP_DRAW_WASHIDDEN; + continue; + } + else if (((data->viewports[v].hidden_flags& + (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)) + == (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))) + { + vp_refresh_mode = WPS_REFRESH_ALL; + data->viewports[v].hidden_flags = VP_DRAW_HIDEABLE; + } + if (vp_refresh_mode == WPS_REFRESH_ALL) + { + display->clear_viewport(); + } + for (line = data->viewports[v].first_line; line <= data->viewports[v].last_line; line++) { @@ -2011,49 +2022,40 @@ data->lines[line].curr_subline); flags = data->sublines[subline_idx].line_type; - if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode) + if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode) || new_subline_refresh) { /* get_line tells us if we need to update the line */ update_line = get_line(gwps, line, data->lines[line].curr_subline, &align, linebuf, sizeof(linebuf)); } - #ifdef HAVE_LCD_BITMAP - /* progressbar */ - if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) - { - /* the progressbar should be alone on its line */ - update_line = false; - draw_progressbar(gwps, line - data->viewports[v].first_line); - } - /* peakmeter */ - if (flags & refresh_mode & WPS_REFRESH_PEAK_METER) + if (flags & vp_refresh_mode & WPS_REFRESH_PEAK_METER) { /* the peakmeter should be alone on its line */ update_line = false; - int h = font_get(display->getfont())->height; - int peak_meter_y = display->getymargin() + (line - data->viewports[v].first_line)* h; + int h = font_get(data->viewports[v].vp.font)->height; + int peak_meter_y = (line - data->viewports[v].first_line)* h; /* The user might decide to have the peak meter in the last line so that it is only displayed if no status bar is visible. If so we neither want do draw nor enable the peak meter. */ - if (peak_meter_y + h <= display->getheight()) { + if (peak_meter_y + h <= data->viewports[v].vp.height) { /* found a line with a peak meter -> remember that we must enable it later */ enable_pm = true; peak_meter_screen(gwps->display, 0, peak_meter_y, - MIN(h, display->getheight() - peak_meter_y)); + MIN(h, data->viewports[v].vp.height - peak_meter_y)); } } #else /* HAVE_LCD_CHARCELL */ /* progressbar */ - if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) + if (flags & vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) { if (data->full_line_progressbar) draw_player_fullbar(gwps, linebuf, sizeof(linebuf)); @@ -2062,22 +2064,32 @@ } #endif - if (update_line) + if (update_line && + /* conditionals clear the line which means if the %Vd is put into the default + viewport there will be a blank line. + To get around this we dont allow any actual drawing to happen in the + deault vp if other vp's are defined */ + ((data->num_viewports>1 && v!=0) || data->num_viewports == 1)) { if (flags & WPS_REFRESH_SCROLL) { /* 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_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) + if ((vp_refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) write_line(display, &align, line - data->viewports[v].first_line, true); } else write_line(display, &align, line - data->viewports[v].first_line, false); } - } #ifdef HAVE_LCD_BITMAP + /* progressbar */ + if (vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) + { + if (data->viewports[v].pb) + draw_progressbar(gwps, data->viewports[v].pb); + } /* Now display any images in this viewport */ wps_display_images(gwps, &data->viewports[v].vp); #endif Index: apps/gui/statusbar.h =================================================================== --- apps/gui/statusbar.h (revision 17684) +++ apps/gui/statusbar.h (working copy) @@ -22,11 +22,16 @@ #include "status.h" #include "screen_access.h" +#include "events.h" #define STATUSBAR_X_POS 0 #define STATUSBAR_Y_POS 0 /* MUST be a multiple of 8 */ #define STATUSBAR_HEIGHT 8 +/* possibly a horrible misuse of the event system. + This is triggered when the statusbar setting changes */ +#define STATUSBAR_TOGGLE_EVENT (EVENT_CLASS_GUI|1) + struct status_info { int battlevel; int batt_charge_step; Index: apps/gui/viewport.c =================================================================== --- apps/gui/viewport.c (revision 17684) +++ apps/gui/viewport.c (working copy) @@ -45,8 +45,6 @@ void viewport_set_defaults(struct viewport *vp, enum screen_type screen) { - vp->xmargin = 0; - vp->ymargin = 0; vp->x = 0; vp->width = screens[screen].width; Index: apps/gui/wps_debug.c =================================================================== --- apps/gui/wps_debug.c (revision 17684) +++ apps/gui/wps_debug.c (working copy) @@ -79,11 +79,6 @@ case WPS_TOKEN_ALIGN_RIGHT: snprintf(buf, bufsize, "align right"); break; - - case WPS_TOKEN_LEFTMARGIN: - snprintf(buf, bufsize, "left margin, value: %d", - token->value.i); - break; #endif case WPS_TOKEN_SUBLINE_TIMEOUT: @@ -431,6 +426,10 @@ snprintf(buf, bufsize, "pitch value"); break; #endif + case WPS_VIEWPORT_ENABLE: + snprintf(buf, bufsize, "enable VP:%d", + token->value.i); + break; default: snprintf(buf, bufsize, "FIXME (code: %d)", Index: apps/gui/gwps.c =================================================================== --- apps/gui/gwps.c (revision 17684) +++ apps/gui/gwps.c (working copy) @@ -77,19 +77,6 @@ /* connects a wps with a statusbar*/ static void gui_wps_set_statusbar(struct gui_wps *gui_wps, struct gui_statusbar *statusbar); -#ifdef HAVE_LCD_BITMAP -static void gui_wps_set_margin(struct gui_wps *gwps) -{ - int offset = 0; - struct wps_data *data = gwps->data; - if(data->wps_sb_tag && data->show_sb_on_wps) - offset = STATUSBAR_HEIGHT; - else if ( global_settings.statusbar && !data->wps_sb_tag) - offset = STATUSBAR_HEIGHT; - gwps->display->setmargins(0, offset); -} -#endif - static void prev_track(unsigned skip_thresh) { if (!wps_state.id3 || (wps_state.id3->elapsed < skip_thresh*1000)) { @@ -152,10 +139,6 @@ status_set_audio(true); status_set_param(false); #else - FOR_NB_SCREENS(i) - { - gui_wps_set_margin(&gui_wps[i]); - } #if LCD_DEPTH > 1 show_wps_backdrop(); #endif /* LCD_DEPTH > 1 */ @@ -299,12 +282,6 @@ #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 show_remote_wps_backdrop(); #endif -#ifdef HAVE_LCD_BITMAP - FOR_NB_SCREENS(i) - { - gui_wps_set_margin(&gui_wps[i]); - } -#endif restore = true; break; @@ -558,12 +535,6 @@ #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 show_remote_wps_backdrop(); #endif -#ifdef HAVE_LCD_BITMAP - FOR_NB_SCREENS(i) - { - gui_wps_set_margin(&gui_wps[i]); - } -#endif restore = true; break; #endif /* HAVE_QUICKSCREEN */ @@ -579,12 +550,6 @@ #endif if (quick_screen_f3(BUTTON_F3)) return SYS_USB_CONNECTED; -#ifdef HAVE_LCD_BITMAP - FOR_NB_SCREENS(i) - { - gui_wps_set_margin(&gui_wps[i]); - } -#endif restore = true; break; #endif /* BUTTON_F3 */ @@ -643,12 +608,6 @@ #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 show_remote_wps_backdrop(); #endif -#ifdef HAVE_LCD_BITMAP - FOR_NB_SCREENS(i) - { - gui_wps_set_margin(&gui_wps[i]); - } -#endif restore = true; break; @@ -812,7 +771,30 @@ FOR_NB_SCREENS(i) gui_wps_set_disp(&gui_wps[i], &screens[i]); } +static void statusbar_toggle_handler(void *data) +{ + (void)data; + int i; + bool draw = global_settings.statusbar; + FOR_NB_SCREENS(i) + { + struct wps_viewport *vp = &gui_wps[i].data->viewports[0]; + if (gui_wps[i].data->wps_sb_tag) + draw = gui_wps[i].data->show_sb_on_wps; + if (!global_settings.statusbar && !draw) + { + vp->vp.y = 0; + vp->vp.height = screens[i].height; + } + else + { + vp->vp.y = STATUSBAR_HEIGHT; + vp->vp.height = screens[i].height - STATUSBAR_HEIGHT; + } + } +} + void gui_sync_wps_init(void) { int i; @@ -826,6 +808,7 @@ gui_wps_set_data(&gui_wps[i], &wps_datas[i]); gui_wps_set_statusbar(&gui_wps[i], &statusbars.statusbars[i]); } + add_event(STATUSBAR_TOGGLE_EVENT, false, statusbar_toggle_handler); #if LCD_DEPTH > 1 unload_wps_backdrop(); #endif Index: apps/gui/gwps.h =================================================================== --- apps/gui/gwps.h (revision 17684) +++ apps/gui/gwps.h (working copy) @@ -70,7 +70,13 @@ bool always_display; /* not using the preload/display mechanism */ }; -struct prog_img{ /*progressbar image*/ +struct progressbar { + /* regular pb */ + short x; + short y; + short width; + short height; + /*progressbar image*/ struct bitmap bm; bool have_bitmap_pb; }; @@ -85,6 +91,7 @@ #ifdef HAVE_LCD_BITMAP #define MAX_IMAGES (26*2) /* a-z and A-Z */ +#define MAX_PROGRESSBARS 3 /* The image buffer is big enough to store one full-screen native bitmap, plus two full-screen mono bitmaps. */ @@ -271,8 +278,11 @@ #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) /* Virtual LED */ - WPS_TOKEN_VLED_HDD + WPS_TOKEN_VLED_HDD, #endif + + /* Viewport display */ + WPS_VIEWPORT_ENABLE }; struct wps_token { @@ -323,12 +333,17 @@ long subline_expire_time; }; +#define VP_DRAW_HIDEABLE 0x1 +#define VP_DRAW_HIDDEN 0x2 +#define VP_DRAW_WASHIDDEN 0x4 struct wps_viewport { struct viewport vp; /* The LCD viewport struct */ - + struct progressbar *pb; /* Indexes of the first and last lines belonging to this viewport in the lines[] array */ int first_line, last_line; + char hidden_flags; + char label; }; /* wps_data @@ -338,17 +353,15 @@ { #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; bool wps_sb_tag; bool show_sb_on_wps; - short progress_top; - short progress_height; - short progress_start; - short progress_end; + struct progressbar progressbar[MAX_PROGRESSBARS]; + short progressbar_count; + bool peak_meter_enabled; #ifdef HAVE_ALBUMART Index: apps/gui/wps_parser.c =================================================================== --- apps/gui/wps_parser.c (revision 17684) +++ apps/gui/wps_parser.c (working copy) @@ -80,13 +80,13 @@ #ifdef HAVE_LCD_BITMAP #if LCD_DEPTH > 1 -#define MAX_BITMAPS (MAX_IMAGES+2) /* WPS images + pbar bitmap + backdrop */ +#define MAX_BITMAPS (MAX_IMAGES+MAX_PROGRESSBARS+1) /* WPS images + pbar bitmap + backdrop */ #else -#define MAX_BITMAPS (MAX_IMAGES+1) /* WPS images + pbar bitmap */ +#define MAX_BITMAPS (MAX_IMAGES+MAX_PROGRESSBARS) /* WPS images + pbar bitmap */ #endif #define PROGRESSBAR_BMP MAX_IMAGES -#define BACKDROP_BMP (MAX_IMAGES+1) +#define BACKDROP_BMP (MAX_BITMAPS-1) /* pointers to the bitmap filenames in the WPS source */ static const char *bmp_names[MAX_BITMAPS]; @@ -129,10 +129,10 @@ struct wps_token *token, struct wps_data *wps_data); #ifdef HAVE_LCD_BITMAP +static int parse_viewport_display(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); static int parse_viewport(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); -static int parse_leftmargin(const char *wps_bufptr, - struct wps_token *token, struct wps_data *wps_data); static int parse_image_special(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); static int parse_statusbar_enable(const char *wps_bufptr, @@ -269,10 +269,6 @@ { WPS_TOKEN_PLAYBACK_STATUS, "mp", WPS_REFRESH_DYNAMIC, NULL }, #ifdef HAVE_LCD_BITMAP - { WPS_TOKEN_LEFTMARGIN, "m", 0, parse_leftmargin }, -#endif - -#ifdef HAVE_LCD_BITMAP { WPS_TOKEN_PEAKMETER, "pm", WPS_REFRESH_PEAK_METER, NULL }, #else { WPS_TOKEN_PLAYER_PROGRESSBAR, "pf", @@ -317,13 +313,14 @@ parse_image_display }, { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, - { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special }, #ifdef HAVE_ALBUMART { WPS_NO_TOKEN, "Cl", 0, parse_albumart_load }, { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC, parse_albumart_conditional }, #endif + { WPS_VIEWPORT_ENABLE, "Vd", WPS_REFRESH_DYNAMIC, + parse_viewport_display }, { WPS_NO_TOKEN, "V", 0, parse_viewport }, #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) @@ -363,6 +360,11 @@ (void)token; /* Kill warnings */ wps_data->wps_sb_tag = true; wps_data->show_sb_on_wps = true; + if (wps_data->viewports[0].vp.y == 0) + { + wps_data->viewports[0].vp.y = STATUSBAR_HEIGHT; + wps_data->viewports[0].vp.height -= STATUSBAR_HEIGHT; + } return skip_end_of_line(wps_bufptr); } @@ -373,6 +375,11 @@ (void)token; /* Kill warnings */ wps_data->wps_sb_tag = true; wps_data->show_sb_on_wps = false; + if (wps_data->viewports[0].vp.y == STATUSBAR_HEIGHT) + { + wps_data->viewports[0].vp.y = 0; + wps_data->viewports[0].vp.height += STATUSBAR_HEIGHT; + } return skip_end_of_line(wps_bufptr); } @@ -489,7 +496,7 @@ ptr++; - if (!(ptr = parse_list("ssdd", '|', ptr, &id, &filename, &x, &y))) + if (!(ptr = parse_list("ssdd", NULL, '|', ptr, &id, &filename, &x, &y))) return WPS_ERROR_INVALID_PARAM; /* Check there is a terminating | */ @@ -536,6 +543,26 @@ return skip_end_of_line(wps_bufptr); } +static int parse_viewport_display(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) +{ + (void)wps_data; + char letter = wps_bufptr[0]; + + if (letter < 'a' || letter > ('a' + WPS_MAX_VIEWPORTS)) + { + /* invalid viewport tag */ + return WPS_ERROR_INVALID_PARAM; + } + + /* for these to work, this tag needs to be before %V + so set token->value.i to the letter and change that + to the viewports index when its loaded */ + token->value.i = letter; + return 1; +} + static int parse_viewport(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data) @@ -545,23 +572,38 @@ int depth; (void)token; /* Kill warnings */ + + if (wps_data->num_viewports >= WPS_MAX_VIEWPORTS) + return WPS_ERROR_INVALID_PARAM; - if (*wps_bufptr != '|') + wps_data->num_viewports++; + + /* check for the optional letter to signify its a hideable viewport */ + /* %Vl|