From 2d31d77a8ba231cb03ec35863c4c4ce2024f6509 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Thu, 29 Jul 2010 12:37:48 +0000 Subject: FS#11470 - new skin code, finally svn uses the new parser from the theme editor. This means that a skin that passes the editor WILL pass svn and checkwps (unless the target runs out of skin buffer or something. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27613 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/skin_engine/skin_display.c | 728 +++++------------------------------- 1 file changed, 88 insertions(+), 640 deletions(-) (limited to 'apps/gui/skin_engine/skin_display.c') diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 3d3a654c30..559ae8519f 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -69,25 +69,22 @@ #include "skin_engine.h" #include "statusbar-skinned.h" -static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode); +void skin_render(struct gui_wps *gwps, unsigned refresh_mode); /* update a skinned screen, update_type is WPS_REFRESH_* values. * Usually it should only be WPS_REFRESH_NON_STATIC * A full update will be done if required (state.do_full_update == true) */ -bool skin_update(struct gui_wps *gwps, unsigned int update_type) +void skin_update(struct gui_wps *gwps, unsigned int update_type) { - bool retval; - /* This maybe shouldnt be here, but while the skin is only used to - * display the music screen this is better than whereever we are being - * called from. This is also safe for skined screen which dont use the id3 */ + /* This maybe shouldnt be here, + * This is also safe for skined screen which dont use the id3 */ struct mp3entry *id3 = gwps->state->id3; bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false); gwps->sync_data->do_full_update |= cuesheet_update; - retval = skin_redraw(gwps, gwps->sync_data->do_full_update ? - WPS_REFRESH_ALL : update_type); - return retval; + skin_render(gwps, gwps->sync_data->do_full_update ? + SKIN_REFRESH_ALL : update_type); } #ifdef HAVE_LCD_BITMAP @@ -124,8 +121,7 @@ void skin_statusbar_changed(struct gui_wps *skin) } } -static void draw_progressbar(struct gui_wps *gwps, - struct progressbar *pb) +void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) { struct screen *display = gwps->display; struct viewport *vp = pb->vp; @@ -143,17 +139,17 @@ static void draw_progressbar(struct gui_wps *gwps, /* center the pb in the line, but only if the line is higher than the pb */ int center = (line_height-height)/2; /* if Y was not set calculate by font height,Y is -line_number-1 */ - y = (-y -1)*line_height + (0 > center ? 0 : center); + y = line*line_height + (0 > center ? 0 : center); } - if (pb->type == WPS_TOKEN_VOLUMEBAR) + if (pb->type == SKIN_TOKEN_VOLUMEBAR) { int minvol = sound_min(SOUND_VOLUME); int maxvol = sound_max(SOUND_VOLUME); length = maxvol-minvol; elapsed = global_settings.volume-minvol; } - else if (pb->type == WPS_TOKEN_BATTERY_PERCENTBAR) + else if (pb->type == SKIN_TOKEN_BATTERY_PERCENTBAR) { length = 100; elapsed = battery_level(); @@ -185,7 +181,7 @@ static void draw_progressbar(struct gui_wps *gwps, gui_scrollbar_draw(display, pb->x, y, pb->width, height, length, 0, elapsed, HORIZONTAL); - if (pb->type == WPS_TOKEN_PROGRESSBAR) + if (pb->type == SKIN_TOKEN_PROGRESSBAR) { if (id3 && id3->length) { @@ -208,8 +204,7 @@ static void draw_progressbar(struct gui_wps *gwps, } } -static void draw_playlist_viewer_list(struct gui_wps *gwps, - struct playlistviewer *viewer) +void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer) { struct wps_state *state = gwps->state; int lines = viewport_get_nb_lines(viewer->vp); @@ -217,8 +212,9 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, int cur_pos, max; int start_item; int i; - struct wps_token token; - int x, length, alignment = WPS_TOKEN_ALIGN_LEFT; + bool scroll = false; + struct wps_token *token; + int x, length, alignment = SKIN_TOKEN_ALIGN_LEFT; struct mp3entry *pid3; char buf[MAX_PATH*2], tempbuf[MAX_PATH]; @@ -281,51 +277,58 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, } line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO; } - int j = 0, cur_string = 0; unsigned int line_len = 0; + if (viewer->lines[line]->children_count == 0) + return; + struct skin_element *element = viewer->lines[line]->children[0]; buf[0] = '\0'; - while (j < viewer->lines[line].count && line_len < sizeof(buf)) + while (element && line_len < sizeof(buf)) { const char *out = NULL; - token.type = viewer->lines[line].tokens[j]; - token.value.i = 0; - token.next = false; - out = get_id3_token(&token, pid3, tempbuf, sizeof(tempbuf), -1, NULL); + if (element->type == TEXT) + { + line_len = strlcat(buf, (char*)element->data, sizeof(buf)); + element = element->next; + continue; + } + if (element->type != TAG) + { + element = element->next; + continue; + } + if (element->tag->type == SKIN_TOKEN_SUBLINE_SCROLL) + scroll = true; + token = (struct wps_token*)element->data; + out = get_id3_token(token, pid3, tempbuf, sizeof(tempbuf), -1, NULL); #if CONFIG_TUNER if (!out) - out = get_radio_token(&token, i-cur_pos, + out = get_radio_token(token, i-cur_pos, tempbuf, sizeof(tempbuf), -1, NULL); #endif if (out) { line_len = strlcat(buf, out, sizeof(buf)); - j++; + element = element->next; continue; } - switch (viewer->lines[line].tokens[j]) + switch (token->type) { - case WPS_TOKEN_ALIGN_CENTER: - case WPS_TOKEN_ALIGN_LEFT: - case WPS_TOKEN_ALIGN_LEFT_RTL: - case WPS_TOKEN_ALIGN_RIGHT: - case WPS_TOKEN_ALIGN_RIGHT_RTL: - alignment = viewer->lines[line].tokens[j]; + case SKIN_TOKEN_ALIGN_CENTER: + case SKIN_TOKEN_ALIGN_LEFT: + case SKIN_TOKEN_ALIGN_LEFT_RTL: + case SKIN_TOKEN_ALIGN_RIGHT: + case SKIN_TOKEN_ALIGN_RIGHT_RTL: + alignment = token->type; tempbuf[0] = '\0'; break; - case WPS_TOKEN_STRING: - case WPS_TOKEN_CHARACTER: - snprintf(tempbuf, sizeof(tempbuf), "%s", - viewer->lines[line].strings[cur_string]); - cur_string++; - break; - case WPS_TOKEN_PLAYLIST_POSITION: + case SKIN_TOKEN_PLAYLIST_POSITION: snprintf(tempbuf, sizeof(tempbuf), "%d", i); break; - case WPS_TOKEN_FILE_NAME: + case SKIN_TOKEN_FILE_NAME: get_dir(tempbuf, sizeof(tempbuf), filename, 0); break; - case WPS_TOKEN_FILE_PATH: + case SKIN_TOKEN_FILE_PATH: snprintf(tempbuf, sizeof(tempbuf), "%s", filename); break; default: @@ -336,12 +339,12 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, { line_len = strlcat(buf, tempbuf, sizeof(buf)); } - j++; + element = element->next; } int vpwidth = viewer->vp->width; length = gwps->display->getstringsize(buf, NULL, NULL); - if (viewer->lines[line].scroll && length >= vpwidth) + if (scroll && length >= vpwidth) { gwps->display->puts_scroll(0, (i-start_item), buf ); } @@ -353,25 +356,25 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, { switch (alignment) { - case WPS_TOKEN_ALIGN_CENTER: + case SKIN_TOKEN_ALIGN_CENTER: x = (vpwidth-length)/2; break; - case WPS_TOKEN_ALIGN_LEFT_RTL: + case SKIN_TOKEN_ALIGN_LEFT_RTL: if (lang_is_rtl() && VP_IS_RTL(viewer->vp)) { x = vpwidth - length; break; } - case WPS_TOKEN_ALIGN_LEFT: + case SKIN_TOKEN_ALIGN_LEFT: x = 0; break; - case WPS_TOKEN_ALIGN_RIGHT_RTL: + case SKIN_TOKEN_ALIGN_RIGHT_RTL: if (lang_is_rtl() && VP_IS_RTL(viewer->vp)) { x = 0; break; } - case WPS_TOKEN_ALIGN_RIGHT: + case SKIN_TOKEN_ALIGN_RIGHT: x = vpwidth - length; break; default: @@ -386,7 +389,7 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, /* clears the area where the image was shown */ -static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) +void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) { if(!gwps) return; @@ -395,7 +398,7 @@ static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) gwps->display->set_drawmode(DRMODE_SOLID); } -static void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) +void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) { struct screen *display = gwps->display; if(img->always_display) @@ -423,7 +426,8 @@ static void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subima #endif } -static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) + +void wps_display_images(struct gui_wps *gwps, struct viewport* vp) { if(!gwps || !gwps->data || !gwps->display) return; @@ -451,18 +455,10 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) #ifdef HAVE_ALBUMART /* now draw the AA */ if (data->albumart && data->albumart->vp == vp - && data->albumart->draw) + && data->albumart->draw_handle >= 0) { - int handle = playback_current_aa_hid(data->playback_aa_slot); -#if CONFIG_TUNER - if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) - { - struct dim dim = {data->albumart->width, data->albumart->height}; - handle = radio_get_art_hid(&dim); - } -#endif - draw_album_art(gwps, handle, false); - data->albumart->draw = false; + draw_album_art(gwps, data->albumart->draw_handle, false); + data->albumart->draw_handle = -1; } #endif @@ -471,7 +467,7 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) #else /* HAVE_LCD_CHARCELL */ -static bool draw_player_progress(struct gui_wps *gwps) +bool draw_player_progress(struct gui_wps *gwps) { struct wps_state *state = gwps->state; struct screen *display = gwps->display; @@ -508,7 +504,7 @@ static bool draw_player_progress(struct gui_wps *gwps) return true; } -static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) +void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) { static const unsigned char numbers[10][4] = { {0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */ @@ -613,44 +609,25 @@ static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) #endif /* HAVE_LCD_CHARCELL */ -/* Return the index to the end token for the conditional token at index. - The conditional token can be either a start token or a separator - (i.e. option) token. -*/ -static int find_conditional_end(struct wps_data *data, int index) -{ - int ret = index; - while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END) - ret = data->tokens[ret].value.i; - - /* ret now is the index to the end token for the conditional. */ - return ret; -} - /* Evaluate the conditional that is at *token_index and return whether a skip has ocurred. *token_index is updated with the new position. */ -static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) +int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional, int num_options) { if (!gwps) return false; - struct wps_data *data = gwps->data; - - int i, cond_end; - int cond_index = *token_index; char result[128]; const char *value; - unsigned char num_options = data->tokens[cond_index].value.i & 0xFF; - unsigned char prev_val = (data->tokens[cond_index].value.i & 0xFF00) >> 8; - /* treat ?xx constructs as if they had 2 options. */ + /* treat ?xx constructs as if they had 2 options. + * (i.e ?xx) */ if (num_options < 2) num_options = 2; int intval = num_options; /* get_token_value needs to know the number of options in the enum */ - value = get_token_value(gwps, &data->tokens[cond_index + 1], + value = get_token_value(gwps, conditional->token, result, sizeof(result), &intval); /* intval is now the number of the enum option we want to read, @@ -659,334 +636,18 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) intval = (value && *value) ? 1 : num_options; else if (intval > num_options || intval < 1) intval = num_options; - - data->tokens[cond_index].value.i = (intval << 8) + num_options; - - /* skip to the appropriate enum case */ - int next = cond_index + 2; - for (i = 1; i < intval; i++) - { - next = data->tokens[next].value.i; - } - *token_index = next; - - if (prev_val == intval) - { - /* Same conditional case as previously. Return without clearing the - pictures */ - return false; - } - - cond_end = find_conditional_end(data, cond_index + 2); - for (i = cond_index + 3; i < cond_end; i++) - { -#ifdef HAVE_LCD_BITMAP - /* clear all pictures in the conditional and nested ones */ - if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY) - clear_image_pos(gwps, find_image(data->tokens[i].value.i&0xFF, data)); - else if (data->tokens[i].type == WPS_TOKEN_VOLUMEBAR || - data->tokens[i].type == WPS_TOKEN_PROGRESSBAR || - data->tokens[i].type == WPS_TOKEN_BATTERY_PERCENTBAR ) - { - struct progressbar *bar = (struct progressbar*)data->tokens[i].value.data; - bar->draw = false; - } - else if (data->tokens[i].type == WPS_TOKEN_PEAKMETER) - { - data->peak_meter_enabled = false; - } -#endif -#ifdef HAVE_ALBUMART - if (data->albumart && data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY) - { - draw_album_art(gwps, - playback_current_aa_hid(data->playback_aa_slot), true); - data->albumart->draw = false; - } -#endif - } - - return true; -} - - -/* Read a (sub)line to the given alignment format buffer. - linebuf is the buffer where the data is actually stored. - align is the alignment format that'll be used to display the text. - The return value indicates whether the line needs to be updated. -*/ -static bool get_line(struct gui_wps *gwps, - struct skin_subline *subline, - struct align_pos *align, - char *linebuf, - int linebuf_size, - unsigned refresh_mode) -{ - struct wps_data *data = gwps->data; - - char temp_buf[128]; - char *buf = linebuf; /* will always point to the writing position */ - char *linebuf_end = linebuf + linebuf_size - 1; - bool update = false; - int i; - (void)refresh_mode; /* silence warning on charcell */ - - /* alignment-related variables */ - int cur_align; - char* cur_align_start; - cur_align_start = buf; - cur_align = WPS_ALIGN_LEFT; - align->left = NULL; - align->center = NULL; - align->right = NULL; - /* Process all tokens of the desired subline */ - for (i = subline->first_token_idx; - i <= subline->last_token_idx; i++) - { - switch(data->tokens[i].type) - { - case WPS_TOKEN_CONDITIONAL: - /* place ourselves in the right conditional case */ - update |= evaluate_conditional(gwps, &i); - break; - - case WPS_TOKEN_CONDITIONAL_OPTION: - /* we've finished in the curent conditional case, - skip to the end of the conditional structure */ - i = find_conditional_end(data, i); - break; -#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) - case WPS_TOKEN_VIEWPORT_FGCOLOUR: - { - struct viewport_colour *col = data->tokens[i].value.data; - col->vp->fg_pattern = col->colour; - } - break; - case WPS_TOKEN_VIEWPORT_BGCOLOUR: - { - struct viewport_colour *col = data->tokens[i].value.data; - col->vp->bg_pattern = col->colour; - } - break; -#endif -#ifdef HAVE_LCD_BITMAP - case WPS_TOKEN_PEAKMETER: - data->peak_meter_enabled = true; - break; - case WPS_TOKEN_VOLUMEBAR: - case WPS_TOKEN_BATTERY_PERCENTBAR: - case WPS_TOKEN_PROGRESSBAR: - { - struct progressbar *bar = (struct progressbar*)data->tokens[i].value.data; - bar->draw = true; - } - break; - case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: - { - char n = data->tokens[i].value.i & 0xFF; - int subimage = data->tokens[i].value.i >> 8; - struct gui_img *img = find_image(n, data); - - if (img && img->loaded) - img->display = subimage; - break; - } - case WPS_TOKEN_DRAW_INBUILTBAR: - gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]), - refresh_mode == WPS_REFRESH_ALL, - data->tokens[i].value.data); - break; -#endif - - case WPS_TOKEN_ALIGN_LEFT: - case WPS_TOKEN_ALIGN_LEFT_RTL: - case WPS_TOKEN_ALIGN_CENTER: - case WPS_TOKEN_ALIGN_RIGHT: - case WPS_TOKEN_ALIGN_RIGHT_RTL: - /* remember where the current aligned text started */ - switch (cur_align) - { - case WPS_ALIGN_LEFT: - align->left = cur_align_start; - break; - - case WPS_ALIGN_CENTER: - align->center = cur_align_start; - break; - - case WPS_ALIGN_RIGHT: - align->right = cur_align_start; - break; - } - /* start a new alignment */ - switch (data->tokens[i].type) - { - case WPS_TOKEN_ALIGN_LEFT: - cur_align = WPS_ALIGN_LEFT; - break; - case WPS_TOKEN_ALIGN_LEFT_RTL: - cur_align = lang_is_rtl() ? WPS_ALIGN_RIGHT : - WPS_ALIGN_LEFT; - break; - case WPS_TOKEN_ALIGN_CENTER: - cur_align = WPS_ALIGN_CENTER; - break; - case WPS_TOKEN_ALIGN_RIGHT: - cur_align = WPS_ALIGN_RIGHT; - break; - case WPS_TOKEN_ALIGN_RIGHT_RTL: - cur_align = lang_is_rtl() ? WPS_ALIGN_LEFT : - WPS_ALIGN_RIGHT; - break; - default: - break; - } - *buf++ = 0; - cur_align_start = buf; - break; - case WPS_VIEWPORT_ENABLE: - { - char label = data->tokens[i].value.i; - char temp = VP_DRAW_HIDEABLE; - /* viewports are allowed to share id's so find and enable - * all of them */ - struct skin_token_list *list = data->viewports; - while (list) - { - struct skin_viewport *vp = - (struct skin_viewport *)list->token->value.data; - if (vp->label == label) - { - if (vp->hidden_flags&VP_DRAW_WASHIDDEN) - temp |= VP_DRAW_WASHIDDEN; - vp->hidden_flags = temp; - } - list = list->next; - } - } - break; -#ifdef HAVE_LCD_BITMAP - case WPS_TOKEN_UIVIEWPORT_ENABLE: - sb_set_info_vp(gwps->display->screen_type, - data->tokens[i].value.i|VP_INFO_LABEL); - break; - case WPS_VIEWPORT_CUSTOMLIST: - draw_playlist_viewer_list(gwps, data->tokens[i].value.data); - break; -#endif - default: - { - /* get the value of the tag and copy it to the buffer */ - const char *value = get_token_value(gwps, &data->tokens[i], - temp_buf, sizeof(temp_buf), NULL); - if (value) - { - update = true; - while (*value && (buf < linebuf_end)) - *buf++ = *value++; - } - break; - } - } - } - - /* close the current alignment */ - switch (cur_align) - { - case WPS_ALIGN_LEFT: - align->left = cur_align_start; - break; - - case WPS_ALIGN_CENTER: - align->center = cur_align_start; - break; - - case WPS_ALIGN_RIGHT: - align->right = cur_align_start; - break; - } - - return update; -} -static void get_subline_timeout(struct gui_wps *gwps, struct skin_subline *subline) -{ - struct wps_data *data = gwps->data; - int i; - subline->time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; - - for (i = subline->first_token_idx; - i <= subline->last_token_idx; i++) - { - switch(data->tokens[i].type) - { - case WPS_TOKEN_CONDITIONAL: - /* place ourselves in the right conditional case */ - evaluate_conditional(gwps, &i); - break; - - case WPS_TOKEN_CONDITIONAL_OPTION: - /* we've finished in the curent conditional case, - skip to the end of the conditional structure */ - i = find_conditional_end(data, i); - break; - - case WPS_TOKEN_SUBLINE_TIMEOUT: - subline->time_mult = data->tokens[i].value.i; - break; - - default: - break; - } - } + + conditional->last_value = intval -1; + return intval -1; } -/* Calculates which subline should be displayed for the specified line - Returns true iff the subline must be refreshed */ -static bool update_curr_subline(struct gui_wps *gwps, struct skin_line *line) -{ - /* shortcut this whole thing if we need to reset the line completly */ - if (line->curr_subline == NULL) - { - line->subline_expire_time = current_tick; - line->curr_subline = &line->sublines; - if (!line->curr_subline->next) - { - line->subline_expire_time += 100*HZ; - } - else - { - get_subline_timeout(gwps, line->curr_subline); - line->subline_expire_time += TIMEOUT_UNIT*line->curr_subline->time_mult; - } - return true; - } - /* if time to advance to next sub-line */ - if (TIME_AFTER(current_tick, line->subline_expire_time - 1)) - { - /* if there is only one subline, there is no need to search for a new one */ - if (&line->sublines == line->curr_subline && - line->curr_subline->next == NULL) - { - line->subline_expire_time += 100 * HZ; - return false; - } - if (line->curr_subline->next) - line->curr_subline = line->curr_subline->next; - else - line->curr_subline = &line->sublines; - get_subline_timeout(gwps, line->curr_subline); - line->subline_expire_time = current_tick + TIMEOUT_UNIT*line->curr_subline->time_mult; - return true; - } - return false; -} /* Display a line appropriately according to its alignment format. format_align contains the text, separated between left, center and right. line is the index of the line on the screen. scroll indicates whether the line is a scrolling one or not. */ -static void write_line(struct screen *display, +void write_line(struct screen *display, struct align_pos *format_align, int line, bool scroll) @@ -1143,244 +804,30 @@ static void write_line(struct screen *display, } } -static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) +#ifdef HAVE_LCD_BITMAP +void draw_peakmeters(struct gui_wps *gwps, int line_number, + struct viewport *viewport) { struct wps_data *data = gwps->data; - struct screen *display = gwps->display; - - if (!data || !display || !gwps->state) - return false; - - unsigned flags; - char linebuf[MAX_PATH]; - - struct align_pos align; - align.left = NULL; - align.center = NULL; - align.right = NULL; - - - struct skin_token_list *viewport_list; - - bool update_line, new_subline_refresh; - - /* reset to first subline if refresh all flag is set */ - if (refresh_mode == WPS_REFRESH_ALL) + if (!data->peak_meter_enabled) { - struct skin_line *line; - struct skin_viewport *skin_viewport = find_viewport(VP_DEFAULT_LABEL, data); - - if (!(skin_viewport->hidden_flags & VP_NEVER_VISIBLE)) - { - display->set_viewport(&skin_viewport->vp); - display->clear_viewport(); - } - - for (viewport_list = data->viewports; - viewport_list; viewport_list = viewport_list->next) - { - skin_viewport = - (struct skin_viewport *)viewport_list->token->value.data; - for(line = skin_viewport->lines; line; line = line->next) - { - line->curr_subline = NULL; - } - } + peak_meter_enable(false); } - -#ifdef HAVE_LCD_CHARCELLS - int i; - for (i = 0; i < 8; i++) - { - if (data->wps_progress_pat[i] == 0) - data->wps_progress_pat[i] = display->get_locked_pattern(); - } -#endif - - /* disable any viewports which are conditionally displayed. - * If we are only refreshing the peak meter then don't change the viewport - * enabled flags as this will stop scrolling. viewports cant be - * toggled in this refresh mode anyway (FS#10215)*/ - if (refresh_mode != WPS_REFRESH_PEAK_METER) - { - for (viewport_list = data->viewports; - viewport_list; viewport_list = viewport_list->next) - { - struct skin_viewport *skin_viewport = - (struct skin_viewport *)viewport_list->token->value.data; - if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) - { - continue; - } - if (skin_viewport->hidden_flags&VP_DRAW_HIDEABLE) - { - if (skin_viewport->hidden_flags&VP_DRAW_HIDDEN) - skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN; - else - skin_viewport->hidden_flags |= VP_DRAW_HIDDEN; - } - } - } - for (viewport_list = data->viewports; - viewport_list; viewport_list = viewport_list->next) + else { - struct skin_viewport *skin_viewport = - (struct skin_viewport *)viewport_list->token->value.data; - unsigned vp_refresh_mode = refresh_mode; -#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) - skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour; - skin_viewport->vp.bg_pattern = skin_viewport->start_bgcolour; -#endif - display->set_viewport(&skin_viewport->vp); - - int hidden_vp = 0; + int h = font_get(viewport->font)->height; + int peak_meter_y = line_number * h; -#ifdef HAVE_LCD_BITMAP - /* Set images to not to be displayed */ - struct skin_token_list *imglist = data->images; - while (imglist) - { - struct gui_img *img = (struct gui_img *)imglist->token->value.data; - img->display = -1; - imglist = imglist->next; - } -#endif - /* dont redraw the viewport if its disabled */ - if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) - { /* don't draw anything into this one */ - vp_refresh_mode = 0; hidden_vp = true; - } - else if ((skin_viewport->hidden_flags&VP_DRAW_HIDDEN)) - { - if (!(skin_viewport->hidden_flags&VP_DRAW_WASHIDDEN)) - display->scroll_stop(&skin_viewport->vp); - skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN; - continue; - } - else if (((skin_viewport->hidden_flags& - (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)) - == (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))) - { - vp_refresh_mode = WPS_REFRESH_ALL; - skin_viewport->hidden_flags = VP_DRAW_HIDEABLE; - } - - if (vp_refresh_mode == WPS_REFRESH_ALL) - { - display->clear_viewport(); + /* 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 <= viewport->y+viewport->height) { + peak_meter_enable(true); + peak_meter_screen(gwps->display, 0, peak_meter_y, + MIN(h, viewport->y+viewport->height - peak_meter_y)); } - - /* loop over the lines for this viewport */ - struct skin_line *line; - /* %V() doesnt eat the \n which means the first line of text - * is actually going to be one line down. so set line_count to -1 - * unless we are using the default viewport which doesnt have this problem */ - int line_count = skin_viewport->label==VP_DEFAULT_LABEL?0:-1; - - for (line = skin_viewport->lines; line; line = line->next, line_count++) - { - struct skin_subline *subline; - memset(linebuf, 0, sizeof(linebuf)); - update_line = false; - - /* get current subline for the line */ - new_subline_refresh = update_curr_subline(gwps, line); - subline = line->curr_subline; - flags = line->curr_subline->line_type; - - if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode) - || new_subline_refresh || hidden_vp) - { - /* get_line tells us if we need to update the line */ - update_line = get_line(gwps, subline, &align, - linebuf, sizeof(linebuf), vp_refresh_mode); - } -#ifdef HAVE_LCD_BITMAP - /* peakmeter */ - if (flags & vp_refresh_mode & WPS_REFRESH_PEAK_METER) - { - if (!data->peak_meter_enabled) - { - peak_meter_enable(false); - } - else - { - /* the peakmeter should be alone on its line */ - update_line = false; - - int h = font_get(skin_viewport->vp.font)->height; - int peak_meter_y = line_count* 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 <= skin_viewport->vp.y+skin_viewport->vp.height) { - peak_meter_enable(true); - peak_meter_screen(gwps->display, 0, peak_meter_y, - MIN(h, skin_viewport->vp.y+skin_viewport->vp.height - peak_meter_y)); - } - } - } - -#else /* HAVE_LCD_CHARCELL */ - - /* progressbar */ - if (flags & vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) - { - if (data->full_line_progressbar) - draw_player_fullbar(gwps, linebuf, sizeof(linebuf)); - else - draw_player_progress(gwps); - } -#endif - - if (line_count>= 0 && update_line && !hidden_vp && - /* 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 */ - ((skin_viewport->label != VP_DEFAULT_LABEL && viewport_list->next) || - !viewport_list->next)) - { - 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 ((vp_refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) - write_line(display, &align, line_count, true); - } - else - write_line(display, &align, line_count, false); - } - } -#ifdef HAVE_LCD_BITMAP - /* progressbar */ - if (vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) - { - struct skin_token_list *bar = gwps->data->progressbars; - while (bar) - { - struct progressbar *thisbar = (struct progressbar*)bar->token->value.data; - if (thisbar->vp == &skin_viewport->vp && thisbar->draw) - { - draw_progressbar(gwps, thisbar); - } - bar = bar->next; - } - } - /* Now display any images in this viewport */ - if (!hidden_vp) - wps_display_images(gwps, &skin_viewport->vp); -#endif } - - /* Restore the default viewport */ - display->set_viewport(NULL); - - display->update(); - - return true; } bool skin_has_sbs(enum screen_type screen, struct wps_data *data) @@ -1396,6 +843,7 @@ bool skin_has_sbs(enum screen_type screen, struct wps_data *data) #endif return draw; } +#endif /* do the button loop as often as required for the peak meters to update * with a good refresh rate. @@ -1434,7 +882,7 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout) FOR_NB_SCREENS(i) { if(gwps[i].data->peak_meter_enabled) - skin_update(&gwps[i], WPS_REFRESH_PEAK_METER); + skin_update(&gwps[i], SKIN_REFRESH_PEAK_METER); next_refresh += HZ / PEAK_METER_FPS; } } -- cgit