summaryrefslogtreecommitdiffstats
path: root/apps/gui/skin_engine/skin_display.c
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2010-07-29 12:37:48 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2010-07-29 12:37:48 +0000
commit2d31d77a8ba231cb03ec35863c4c4ce2024f6509 (patch)
treeb85ca1bede3e83695619064ee9a323f0a8da1865 /apps/gui/skin_engine/skin_display.c
parente436483b66a931fef6436e9cd3e69eb2b3ff1f7b (diff)
downloadrockbox-2d31d77a8ba231cb03ec35863c4c4ce2024f6509.tar.gz
rockbox-2d31d77a8ba231cb03ec35863c4c4ce2024f6509.zip
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
Diffstat (limited to 'apps/gui/skin_engine/skin_display.c')
-rw-r--r--apps/gui/skin_engine/skin_display.c728
1 files changed, 88 insertions, 640 deletions
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<true> constructs as if they had 2 options. */
+ /* treat ?xx<true> constructs as if they had 2 options.
+ * (i.e ?xx<true|false>) */
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;
}
}