2005-11-18 09:03:25 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
2008-05-05 09:40:22 +00:00
|
|
|
* Copyright (C) 2002-2007 Björn Stenberg
|
|
|
|
* Copyright (C) 2007-2008 Nicolas Pennequin
|
2005-11-18 09:03:25 +00:00
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2005-11-18 09:03:25 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2009-11-01 13:08:57 +00:00
|
|
|
#include "config.h"
|
2005-11-17 20:20:01 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2009-11-01 13:08:57 +00:00
|
|
|
#include "misc.h"
|
|
|
|
#include "font.h"
|
2005-11-17 20:20:01 +00:00
|
|
|
#include "system.h"
|
2007-04-01 17:32:12 +00:00
|
|
|
#include "rbunicode.h"
|
2009-11-01 13:08:57 +00:00
|
|
|
#ifdef DEBUG
|
2006-02-02 20:42:56 +00:00
|
|
|
#include "debug.h"
|
2005-11-17 20:20:01 +00:00
|
|
|
#endif
|
2006-01-21 23:43:57 +00:00
|
|
|
#include "abrepeat.h"
|
2005-11-17 20:20:01 +00:00
|
|
|
#include "lang.h"
|
2010-01-07 07:34:15 +00:00
|
|
|
#include "language.h"
|
2009-11-01 13:36:57 +00:00
|
|
|
#include "statusbar.h"
|
2005-11-17 20:20:01 +00:00
|
|
|
#include "scrollbar.h"
|
2009-11-01 13:08:57 +00:00
|
|
|
#include "screen_access.h"
|
2010-01-13 06:02:38 +00:00
|
|
|
#include "playlist.h"
|
2010-01-13 06:24:21 +00:00
|
|
|
#include "audio.h"
|
2009-11-01 13:08:57 +00:00
|
|
|
|
2005-11-17 20:20:01 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
#include "peakmeter.h"
|
|
|
|
/* Image stuff */
|
|
|
|
#include "bmp.h"
|
2009-11-01 13:08:57 +00:00
|
|
|
#ifdef HAVE_ALBUMART
|
2007-11-11 12:29:37 +00:00
|
|
|
#include "albumart.h"
|
2005-11-17 20:20:01 +00:00
|
|
|
#endif
|
2009-11-01 13:08:57 +00:00
|
|
|
#endif
|
|
|
|
|
2007-02-14 14:40:24 +00:00
|
|
|
#include "cuesheet.h"
|
2008-03-28 11:24:24 +00:00
|
|
|
#if CONFIG_CODEC == SWCODEC
|
|
|
|
#include "playback.h"
|
|
|
|
#endif
|
2007-04-25 22:08:00 +00:00
|
|
|
#include "backdrop.h"
|
2008-12-31 05:59:26 +00:00
|
|
|
#include "viewport.h"
|
2007-04-25 22:08:00 +00:00
|
|
|
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-07-27 07:21:05 +00:00
|
|
|
#include "wps_internals.h"
|
2009-08-03 04:43:34 +00:00
|
|
|
#include "skin_engine.h"
|
2009-10-19 15:28:15 +00:00
|
|
|
#include "statusbar-skinned.h"
|
2009-08-03 04:43:34 +00:00
|
|
|
|
2009-08-06 04:33:35 +00:00
|
|
|
static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode);
|
2009-08-03 04:43:34 +00:00
|
|
|
|
|
|
|
/* 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)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-04-06 00:39:43 +00:00
|
|
|
bool retval;
|
2009-09-13 12:24:14 +00:00
|
|
|
/* This maybe shouldnt be here, but while the skin is only used to
|
2009-08-03 04:43:34 +00:00
|
|
|
* 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 */
|
|
|
|
struct mp3entry *id3 = gwps->state->id3;
|
2009-07-23 15:20:18 +00:00
|
|
|
bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false);
|
2009-10-20 23:12:20 +00:00
|
|
|
gwps->sync_data->do_full_update |= cuesheet_update;
|
2009-09-13 12:24:14 +00:00
|
|
|
|
2009-10-20 23:12:20 +00:00
|
|
|
retval = skin_redraw(gwps, gwps->sync_data->do_full_update ?
|
2009-08-03 04:43:34 +00:00
|
|
|
WPS_REFRESH_ALL : update_type);
|
2009-04-06 00:39:43 +00:00
|
|
|
return retval;
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-08-27 17:55:05 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
|
2009-08-26 00:06:27 +00:00
|
|
|
void skin_statusbar_changed(struct gui_wps *skin)
|
|
|
|
{
|
|
|
|
if (!skin)
|
|
|
|
return;
|
|
|
|
struct wps_data *data = skin->data;
|
|
|
|
const struct screen *display = skin->display;
|
2009-10-19 15:28:15 +00:00
|
|
|
const int screen = display->screen_type;
|
2009-08-26 00:06:27 +00:00
|
|
|
|
|
|
|
struct viewport *vp = &find_viewport(VP_DEFAULT_LABEL, data)->vp;
|
2009-11-04 05:10:53 +00:00
|
|
|
viewport_set_defaults(vp, screen);
|
2009-08-26 00:06:27 +00:00
|
|
|
|
|
|
|
if (data->wps_sb_tag)
|
|
|
|
{ /* fix up the default viewport */
|
|
|
|
if (data->show_sb_on_wps)
|
|
|
|
{
|
2009-10-19 15:28:15 +00:00
|
|
|
if (statusbar_position(screen) != STATUSBAR_OFF)
|
|
|
|
return; /* vp is fixed already */
|
2009-08-26 00:06:27 +00:00
|
|
|
|
2009-10-19 15:28:15 +00:00
|
|
|
vp->y = STATUSBAR_HEIGHT;
|
2009-08-26 00:06:27 +00:00
|
|
|
vp->height = display->lcdheight - STATUSBAR_HEIGHT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-10-19 15:28:15 +00:00
|
|
|
if (statusbar_position(screen) == STATUSBAR_OFF)
|
|
|
|
return; /* vp is fixed already */
|
|
|
|
vp->y = vp->x = 0;
|
2009-08-26 00:06:27 +00:00
|
|
|
vp->height = display->lcdheight;
|
2009-10-19 15:28:15 +00:00
|
|
|
vp->width = display->lcdwidth;
|
2009-08-26 00:06:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2008-06-23 06:04:17 +00:00
|
|
|
static void draw_progressbar(struct gui_wps *gwps,
|
2009-08-18 05:30:59 +00:00
|
|
|
struct skin_viewport *wps_vp)
|
2010-03-06 14:14:44 +00:00
|
|
|
{
|
2007-04-04 14:41:40 +00:00
|
|
|
struct screen *display = gwps->display;
|
|
|
|
struct wps_state *state = gwps->state;
|
2009-02-16 08:28:51 +00:00
|
|
|
struct progressbar *pb = wps_vp->pb;
|
2009-10-16 19:14:37 +00:00
|
|
|
struct mp3entry *id3 = state->id3;
|
2010-03-06 14:14:44 +00:00
|
|
|
int y = pb->y, height = pb->height;
|
|
|
|
unsigned long length, elapsed;
|
2010-03-02 08:47:45 +00:00
|
|
|
|
|
|
|
if (pb->height < 0 && !pb->have_bitmap_pb)
|
|
|
|
height = font_get(wps_vp->vp.font)->height;
|
2009-02-16 08:28:51 +00:00
|
|
|
|
2009-02-16 08:34:56 +00:00
|
|
|
if (y < 0)
|
|
|
|
{
|
|
|
|
int line_height = font_get(wps_vp->vp.font)->height;
|
|
|
|
/* center the pb in the line, but only if the line is higher than the pb */
|
|
|
|
int center = (line_height-pb->height)/2;
|
|
|
|
/* if Y was not set calculate by font height,Y is -line_number-1 */
|
2009-02-16 08:28:51 +00:00
|
|
|
y = (-y -1)*line_height + (0 > center ? 0 : center);
|
2009-02-16 08:34:56 +00:00
|
|
|
}
|
2009-02-16 08:28:51 +00:00
|
|
|
|
2010-03-06 14:14:44 +00:00
|
|
|
if (id3 && id3->length)
|
2009-10-16 19:14:37 +00:00
|
|
|
{
|
|
|
|
length = id3->length;
|
2010-03-06 14:14:44 +00:00
|
|
|
elapsed = id3->elapsed + state->ff_rewind_count;
|
2009-10-16 19:14:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-03-06 14:14:44 +00:00
|
|
|
length = 1;
|
2009-10-16 19:14:37 +00:00
|
|
|
elapsed = 0;
|
|
|
|
}
|
2009-10-19 15:28:15 +00:00
|
|
|
|
2008-06-23 06:04:17 +00:00
|
|
|
if (pb->have_bitmap_pb)
|
|
|
|
gui_bitmap_scrollbar_draw(display, pb->bm,
|
2009-10-16 19:14:37 +00:00
|
|
|
pb->x, y, pb->width, pb->bm.height,
|
2010-03-06 14:14:44 +00:00
|
|
|
length, 0, elapsed, HORIZONTAL);
|
2007-04-04 14:41:40 +00:00
|
|
|
else
|
2010-03-02 08:47:45 +00:00
|
|
|
gui_scrollbar_draw(display, pb->x, y, pb->width, height,
|
2010-03-06 14:14:44 +00:00
|
|
|
length, 0, elapsed, HORIZONTAL);
|
|
|
|
|
|
|
|
if (id3 && id3->length)
|
|
|
|
{
|
2007-04-04 14:41:40 +00:00
|
|
|
#ifdef AB_REPEAT_ENABLE
|
2010-03-06 14:14:44 +00:00
|
|
|
if (ab_repeat_mode_enabled())
|
|
|
|
ab_draw_markers(display, id3->length,
|
|
|
|
pb->x, pb->x + pb->width, y, height);
|
2005-11-17 20:20:01 +00:00
|
|
|
#endif
|
|
|
|
|
2010-03-06 14:14:44 +00:00
|
|
|
if (id3->cuesheet)
|
|
|
|
cue_draw_markers(display, id3->cuesheet, id3->length,
|
|
|
|
pb->x, pb->x + pb->width, y+1, height-2);
|
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2010-03-06 14:14:44 +00:00
|
|
|
|
2010-01-13 06:02:38 +00:00
|
|
|
bool audio_peek_track(struct mp3entry* id3, int offset);
|
|
|
|
static void draw_playlist_viewer_list(struct gui_wps *gwps,
|
|
|
|
struct playlistviewer *viewer)
|
|
|
|
{
|
2010-01-15 07:20:56 +00:00
|
|
|
struct wps_state *state = gwps->state;
|
2010-01-13 06:02:38 +00:00
|
|
|
int lines = viewport_get_nb_lines(viewer->vp);
|
|
|
|
int line_height = font_get(viewer->vp->font)->height;
|
|
|
|
int cur_playlist_pos = playlist_get_display_index();
|
|
|
|
int start_item = MAX(0, cur_playlist_pos + viewer->start_offset);
|
|
|
|
int i;
|
2010-01-15 07:20:56 +00:00
|
|
|
struct wps_token token;
|
2010-02-18 01:52:13 +00:00
|
|
|
int x, length, alignment = WPS_TOKEN_ALIGN_LEFT;
|
2010-01-13 06:02:38 +00:00
|
|
|
|
2010-01-13 06:24:21 +00:00
|
|
|
struct mp3entry *pid3;
|
|
|
|
#if CONFIG_CODEC == SWCODEC
|
|
|
|
struct mp3entry id3;
|
2010-03-06 14:14:44 +00:00
|
|
|
#endif
|
2010-01-13 06:02:38 +00:00
|
|
|
char buf[MAX_PATH*2], tempbuf[MAX_PATH];
|
2010-01-15 07:20:56 +00:00
|
|
|
unsigned int buf_used = 0;
|
2010-01-13 06:02:38 +00:00
|
|
|
|
|
|
|
gwps->display->set_viewport(viewer->vp);
|
|
|
|
for(i=start_item; (i-start_item)<lines && i<playlist_amount(); i++)
|
|
|
|
{
|
|
|
|
if (i == cur_playlist_pos)
|
|
|
|
{
|
2010-01-15 07:20:56 +00:00
|
|
|
pid3 = state->id3;
|
2010-01-13 06:02:38 +00:00
|
|
|
}
|
|
|
|
else if (i == cur_playlist_pos+1)
|
|
|
|
{
|
2010-01-15 07:20:56 +00:00
|
|
|
pid3 = state->nid3;
|
2010-01-13 06:24:21 +00:00
|
|
|
}
|
|
|
|
#if CONFIG_CODEC == SWCODEC
|
2010-01-13 06:02:38 +00:00
|
|
|
else if ((i>cur_playlist_pos) && audio_peek_track(&id3, i-cur_playlist_pos))
|
|
|
|
{
|
|
|
|
pid3 = &id3;
|
|
|
|
}
|
2010-01-13 06:24:21 +00:00
|
|
|
#endif
|
2010-01-13 06:02:38 +00:00
|
|
|
else
|
2010-01-15 07:20:56 +00:00
|
|
|
{
|
2010-01-13 06:02:38 +00:00
|
|
|
pid3 = NULL;
|
2010-01-15 07:20:56 +00:00
|
|
|
}
|
2010-03-06 14:14:44 +00:00
|
|
|
|
|
|
|
int line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO;
|
2010-01-15 07:20:56 +00:00
|
|
|
int j = 0, cur_string = 0;
|
2010-01-13 06:02:38 +00:00
|
|
|
char *filename = playlist_peek(i-cur_playlist_pos);
|
|
|
|
buf[0] = '\0';
|
2010-01-15 07:20:56 +00:00
|
|
|
buf_used = 0;
|
|
|
|
while (j < viewer->lines[line].count && (buf_used<sizeof(buf)))
|
2010-01-13 06:02:38 +00:00
|
|
|
{
|
2010-01-15 07:20:56 +00:00
|
|
|
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 (out)
|
|
|
|
{
|
|
|
|
snprintf(&buf[buf_used], sizeof(buf)-buf_used, "%s", out);
|
|
|
|
buf_used += strlen(out);
|
|
|
|
j++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
switch (viewer->lines[line].tokens[j])
|
2010-01-13 06:02:38 +00:00
|
|
|
{
|
2010-02-18 01:52:13 +00:00
|
|
|
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];
|
|
|
|
tempbuf[0] = '\0';
|
|
|
|
break;
|
2010-01-13 06:02:38 +00:00
|
|
|
case WPS_TOKEN_STRING:
|
|
|
|
case WPS_TOKEN_CHARACTER:
|
2010-01-15 07:20:56 +00:00
|
|
|
snprintf(tempbuf, sizeof(tempbuf), "%s",
|
|
|
|
viewer->lines[line].strings[cur_string]);
|
|
|
|
cur_string++;
|
2010-01-13 06:02:38 +00:00
|
|
|
break;
|
|
|
|
case WPS_TOKEN_PLAYLIST_POSITION:
|
|
|
|
snprintf(tempbuf, sizeof(tempbuf), "%d", i);
|
|
|
|
break;
|
|
|
|
case WPS_TOKEN_FILE_NAME:
|
|
|
|
get_dir(tempbuf, sizeof(tempbuf), filename, 0);
|
|
|
|
break;
|
|
|
|
case WPS_TOKEN_FILE_PATH:
|
2010-01-15 07:20:56 +00:00
|
|
|
snprintf(tempbuf, sizeof(tempbuf), "%s", filename);
|
2010-01-13 06:02:38 +00:00
|
|
|
break;
|
|
|
|
default:
|
2010-01-15 07:20:56 +00:00
|
|
|
tempbuf[0] = '\0';
|
2010-01-13 06:02:38 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-01-15 07:20:56 +00:00
|
|
|
if (tempbuf[0])
|
|
|
|
{
|
|
|
|
snprintf(&buf[buf_used], sizeof(buf)-buf_used, "%s", tempbuf);
|
|
|
|
buf_used += strlen(tempbuf);
|
|
|
|
}
|
|
|
|
j++;
|
2010-01-13 06:02:38 +00:00
|
|
|
}
|
2010-03-06 14:14:44 +00:00
|
|
|
|
2010-02-18 01:52:13 +00:00
|
|
|
int vpwidth = viewer->vp->width;
|
|
|
|
length = gwps->display->getstringsize(buf, NULL, NULL);
|
|
|
|
if (viewer->lines[line].scroll && length >= vpwidth)
|
2010-01-13 06:02:38 +00:00
|
|
|
{
|
|
|
|
gwps->display->puts_scroll(0, (i-start_item), buf );
|
|
|
|
}
|
|
|
|
else
|
2010-03-06 14:14:44 +00:00
|
|
|
{
|
2010-02-18 01:52:13 +00:00
|
|
|
if (length >= vpwidth)
|
|
|
|
x = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (alignment)
|
|
|
|
{
|
|
|
|
case WPS_TOKEN_ALIGN_CENTER:
|
|
|
|
x = (vpwidth-length)/2;
|
|
|
|
break;
|
|
|
|
case WPS_TOKEN_ALIGN_LEFT_RTL:
|
|
|
|
if (lang_is_rtl() && VP_IS_RTL(viewer->vp))
|
|
|
|
{
|
|
|
|
x = vpwidth - length;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WPS_TOKEN_ALIGN_LEFT:
|
|
|
|
x = 0;
|
|
|
|
break;
|
|
|
|
case WPS_TOKEN_ALIGN_RIGHT_RTL:
|
|
|
|
if (lang_is_rtl() && VP_IS_RTL(viewer->vp))
|
|
|
|
{
|
|
|
|
x = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WPS_TOKEN_ALIGN_RIGHT:
|
|
|
|
x = vpwidth - length;
|
|
|
|
break;
|
2010-02-18 02:37:58 +00:00
|
|
|
default:
|
|
|
|
x = 0;
|
|
|
|
break;
|
2010-02-18 01:52:13 +00:00
|
|
|
}
|
2010-03-06 14:14:44 +00:00
|
|
|
}
|
2010-02-18 01:52:13 +00:00
|
|
|
gwps->display->putsxy(x, (i-start_item)*line_height, buf );
|
2010-01-13 06:02:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
/* clears the area where the image was shown */
|
2009-08-16 18:23:00 +00:00
|
|
|
static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
|
|
|
if(!gwps)
|
|
|
|
return;
|
|
|
|
gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
2009-08-16 18:23:00 +00:00
|
|
|
gwps->display->fillrect(img->x, img->y, img->bm.width, img->subimage_height);
|
2007-04-04 14:41:40 +00:00
|
|
|
gwps->display->set_drawmode(DRMODE_SOLID);
|
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-08-16 18:23:00 +00:00
|
|
|
static void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
|
|
|
struct screen *display = gwps->display;
|
2009-08-16 18:23:00 +00:00
|
|
|
if(img->always_display)
|
2007-04-04 14:41:40 +00:00
|
|
|
display->set_drawmode(DRMODE_FG);
|
|
|
|
else
|
|
|
|
display->set_drawmode(DRMODE_SOLID);
|
|
|
|
|
|
|
|
#if LCD_DEPTH > 1
|
2009-08-16 18:23:00 +00:00
|
|
|
if(img->bm.format == FORMAT_MONO) {
|
2007-04-04 14:41:40 +00:00
|
|
|
#endif
|
2009-09-13 12:24:14 +00:00
|
|
|
display->mono_bitmap_part(img->bm.data,
|
2009-08-16 18:23:00 +00:00
|
|
|
0, img->subimage_height * subimage,
|
|
|
|
img->bm.width, img->x,
|
|
|
|
img->y, img->bm.width,
|
|
|
|
img->subimage_height);
|
2007-04-04 14:41:40 +00:00
|
|
|
#if LCD_DEPTH > 1
|
|
|
|
} else {
|
2009-08-16 18:23:00 +00:00
|
|
|
display->transparent_bitmap_part((fb_data *)img->bm.data,
|
|
|
|
0, img->subimage_height * subimage,
|
2009-09-13 12:24:14 +00:00
|
|
|
STRIDE(display->screen_type,
|
|
|
|
img->bm.width, img->bm.height),
|
2009-08-29 19:31:29 +00:00
|
|
|
img->x, img->y, img->bm.width,
|
2009-08-16 18:23:00 +00:00
|
|
|
img->subimage_height);
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
2005-11-21 23:55:39 +00:00
|
|
|
#endif
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2005-11-21 23:55:39 +00:00
|
|
|
|
2008-03-21 19:38:00 +00:00
|
|
|
static void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
|
|
|
if(!gwps || !gwps->data || !gwps->display)
|
|
|
|
return;
|
2005-11-21 23:55:39 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
struct wps_data *data = gwps->data;
|
|
|
|
struct screen *display = gwps->display;
|
2009-08-16 18:23:00 +00:00
|
|
|
struct skin_token_list *list = data->images;
|
2007-04-04 14:41:40 +00:00
|
|
|
|
2009-08-16 18:23:00 +00:00
|
|
|
while (list)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-08-16 18:23:00 +00:00
|
|
|
struct gui_img *img = (struct gui_img*)list->token->value.data;
|
|
|
|
if (img->loaded)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-08-16 18:23:00 +00:00
|
|
|
if (img->display >= 0)
|
2008-03-23 20:31:00 +00:00
|
|
|
{
|
2009-08-16 18:23:00 +00:00
|
|
|
wps_draw_image(gwps, img, img->display);
|
|
|
|
}
|
|
|
|
else if (img->always_display && img->vp == vp)
|
2008-03-23 20:31:00 +00:00
|
|
|
{
|
2009-08-16 18:23:00 +00:00
|
|
|
wps_draw_image(gwps, img, 0);
|
2008-03-23 20:31:00 +00:00
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2009-08-16 18:23:00 +00:00
|
|
|
list = list->next;
|
2005-11-21 23:55:39 +00:00
|
|
|
}
|
2009-09-13 12:24:14 +00:00
|
|
|
#ifdef HAVE_ALBUMART
|
2009-09-07 02:36:56 +00:00
|
|
|
/* now draw the AA */
|
2009-10-19 15:28:15 +00:00
|
|
|
if (data->albumart && data->albumart->vp == vp
|
2010-01-03 10:50:34 +00:00
|
|
|
&& data->albumart->draw)
|
2009-09-07 02:36:56 +00:00
|
|
|
{
|
2009-10-16 19:14:41 +00:00
|
|
|
draw_album_art(gwps, playback_current_aa_hid(data->playback_aa_slot),
|
|
|
|
false);
|
2010-01-03 10:50:34 +00:00
|
|
|
data->albumart->draw = false;
|
2009-09-07 02:36:56 +00:00
|
|
|
}
|
|
|
|
#endif
|
2009-09-13 12:24:14 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
display->set_drawmode(DRMODE_SOLID);
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
#else /* HAVE_LCD_CHARCELL */
|
|
|
|
|
2005-11-17 20:20:01 +00:00
|
|
|
static bool draw_player_progress(struct gui_wps *gwps)
|
|
|
|
{
|
|
|
|
struct wps_state *state = gwps->state;
|
2005-11-18 09:03:25 +00:00
|
|
|
struct screen *display = gwps->display;
|
2007-04-04 22:05:04 +00:00
|
|
|
unsigned char progress_pattern[7];
|
|
|
|
int pos = 0;
|
|
|
|
int i;
|
|
|
|
|
2009-10-16 19:14:37 +00:00
|
|
|
int elapsed, length;
|
|
|
|
if (LIKELY(state->id3))
|
|
|
|
{
|
|
|
|
elapsed = state->id3->elapsed;
|
|
|
|
length = state->id3->length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elapsed = 0;
|
|
|
|
length = 0;
|
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-10-16 19:14:37 +00:00
|
|
|
if (length)
|
|
|
|
pos = 36 * (elapsed + state->ff_rewind_count) / length;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 22:05:04 +00:00
|
|
|
for (i = 0; i < 7; i++, pos -= 5)
|
2005-11-17 20:20:01 +00:00
|
|
|
{
|
2007-04-04 22:05:04 +00:00
|
|
|
if (pos <= 0)
|
2008-12-12 22:19:42 +00:00
|
|
|
progress_pattern[i] = 0x1fu;
|
2007-04-04 22:05:04 +00:00
|
|
|
else if (pos >= 5)
|
2008-12-12 22:19:42 +00:00
|
|
|
progress_pattern[i] = 0x00u;
|
2005-11-17 20:20:01 +00:00
|
|
|
else
|
2008-12-12 22:19:42 +00:00
|
|
|
progress_pattern[i] = 0x1fu >> pos;
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
|
|
|
|
2007-04-04 22:05:04 +00:00
|
|
|
display->define_pattern(gwps->data->wps_progress_pat[0], progress_pattern);
|
2005-11-17 20:20:01 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
|
|
|
|
{
|
2007-04-04 23:18:35 +00:00
|
|
|
static const unsigned char numbers[10][4] = {
|
|
|
|
{0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */
|
|
|
|
{0x04, 0x0c, 0x04, 0x04}, /* 1 */
|
|
|
|
{0x0e, 0x02, 0x04, 0x0e}, /* 2 */
|
|
|
|
{0x0e, 0x02, 0x06, 0x0e}, /* 3 */
|
|
|
|
{0x08, 0x0c, 0x0e, 0x04}, /* 4 */
|
|
|
|
{0x0e, 0x0c, 0x02, 0x0c}, /* 5 */
|
|
|
|
{0x0e, 0x08, 0x0e, 0x0e}, /* 6 */
|
|
|
|
{0x0e, 0x02, 0x04, 0x08}, /* 7 */
|
|
|
|
{0x0e, 0x0e, 0x0a, 0x0e}, /* 8 */
|
|
|
|
{0x0e, 0x0e, 0x02, 0x0e}, /* 9 */
|
2005-11-17 20:20:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct wps_state *state = gwps->state;
|
2005-11-18 09:03:25 +00:00
|
|
|
struct screen *display = gwps->display;
|
|
|
|
struct wps_data *data = gwps->data;
|
2007-04-04 22:05:04 +00:00
|
|
|
unsigned char progress_pattern[7];
|
2007-04-04 23:18:35 +00:00
|
|
|
char timestr[10];
|
2007-04-04 22:05:04 +00:00
|
|
|
int time;
|
2007-04-04 23:18:35 +00:00
|
|
|
int time_idx = 0;
|
2007-04-04 22:05:04 +00:00
|
|
|
int pos = 0;
|
|
|
|
int pat_idx = 1;
|
2007-04-04 23:18:35 +00:00
|
|
|
int digit, i, j;
|
2007-04-04 22:05:04 +00:00
|
|
|
bool softchar;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-10-16 19:14:37 +00:00
|
|
|
int elapsed, length;
|
|
|
|
if (LIKELY(state->id3))
|
|
|
|
{
|
2009-10-16 20:34:54 +00:00
|
|
|
elapsed = state->id3->elapsed;
|
|
|
|
length = state->id3->length;
|
2009-10-16 19:14:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elapsed = 0;
|
|
|
|
length = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
|
2007-04-04 22:05:04 +00:00
|
|
|
return;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-10-16 19:14:37 +00:00
|
|
|
time = elapsed + state->ff_rewind_count;
|
|
|
|
if (length)
|
|
|
|
pos = 55 * time / length;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
|
|
|
memset(timestr, 0, sizeof(timestr));
|
2007-04-04 23:18:35 +00:00
|
|
|
format_time(timestr, sizeof(timestr)-2, time);
|
|
|
|
timestr[strlen(timestr)] = ':'; /* always safe */
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 22:05:04 +00:00
|
|
|
for (i = 0; i < 11; i++, pos -= 5)
|
|
|
|
{
|
|
|
|
softchar = false;
|
|
|
|
memset(progress_pattern, 0, sizeof(progress_pattern));
|
2009-09-13 12:24:14 +00:00
|
|
|
|
2007-04-04 23:18:35 +00:00
|
|
|
if ((digit = timestr[time_idx]))
|
2007-04-04 22:05:04 +00:00
|
|
|
{
|
|
|
|
softchar = true;
|
2007-04-04 23:18:35 +00:00
|
|
|
digit -= '0';
|
|
|
|
|
|
|
|
if (timestr[time_idx + 1] == ':') /* ones, left aligned */
|
2009-09-13 12:24:14 +00:00
|
|
|
{
|
2007-04-04 23:18:35 +00:00
|
|
|
memcpy(progress_pattern, numbers[digit], 4);
|
|
|
|
time_idx += 2;
|
|
|
|
}
|
|
|
|
else /* tens, shifted right */
|
|
|
|
{
|
|
|
|
for (j = 0; j < 4; j++)
|
|
|
|
progress_pattern[j] = numbers[digit][j] >> 1;
|
|
|
|
|
|
|
|
if (time_idx > 0) /* not the first group, add colon in front */
|
|
|
|
{
|
2008-12-12 22:19:42 +00:00
|
|
|
progress_pattern[1] |= 0x10u;
|
|
|
|
progress_pattern[3] |= 0x10u;
|
2007-04-04 23:18:35 +00:00
|
|
|
}
|
|
|
|
time_idx++;
|
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
|
2007-04-04 22:05:04 +00:00
|
|
|
if (pos >= 5)
|
2008-12-12 22:19:42 +00:00
|
|
|
progress_pattern[5] = progress_pattern[6] = 0x1fu;
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2007-04-04 23:18:35 +00:00
|
|
|
|
2007-04-04 22:05:04 +00:00
|
|
|
if (pos > 0 && pos < 5)
|
|
|
|
{
|
|
|
|
softchar = true;
|
2008-12-12 22:19:42 +00:00
|
|
|
progress_pattern[5] = progress_pattern[6] = (~0x1fu >> pos) & 0x1fu;
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
|
|
|
|
2007-04-04 22:05:04 +00:00
|
|
|
if (softchar && pat_idx < 8)
|
|
|
|
{
|
|
|
|
display->define_pattern(data->wps_progress_pat[pat_idx],
|
|
|
|
progress_pattern);
|
|
|
|
buf = utf8encode(data->wps_progress_pat[pat_idx], buf);
|
|
|
|
pat_idx++;
|
|
|
|
}
|
|
|
|
else if (pos <= 0)
|
|
|
|
buf = utf8encode(' ', buf);
|
2007-04-04 23:18:35 +00:00
|
|
|
else
|
2007-04-04 22:05:04 +00:00
|
|
|
buf = utf8encode(0xe115, buf); /* 2/7 _ */
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2007-04-04 22:05:04 +00:00
|
|
|
*buf = '\0';
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#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;
|
2007-04-15 03:26:26 +00:00
|
|
|
while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END)
|
2007-04-04 14:41:40 +00:00
|
|
|
ret = data->tokens[ret].value.i;
|
|
|
|
|
|
|
|
/* ret now is the index to the end token for the conditional. */
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-09-06 14:56:02 +00:00
|
|
|
/* Evaluate the conditional that is at *token_index and return whether a skip
|
|
|
|
has ocurred. *token_index is updated with the new position.
|
2007-04-04 14:41:40 +00:00
|
|
|
*/
|
2007-11-18 13:24:39 +00:00
|
|
|
static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
|
|
|
if (!gwps)
|
2007-11-18 13:24:39 +00:00
|
|
|
return false;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
struct wps_data *data = gwps->data;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-11-18 15:32:45 +00:00
|
|
|
int i, cond_end;
|
2007-11-18 13:24:39 +00:00
|
|
|
int cond_index = *token_index;
|
2008-09-24 20:03:53 +00:00
|
|
|
char result[128];
|
|
|
|
const char *value;
|
2007-11-18 13:24:39 +00:00
|
|
|
unsigned char num_options = data->tokens[cond_index].value.i & 0xFF;
|
|
|
|
unsigned char prev_val = (data->tokens[cond_index].value.i & 0xFF00) >> 8;
|
2007-04-15 02:59:34 +00:00
|
|
|
|
2007-04-08 14:00:00 +00:00
|
|
|
/* treat ?xx<true> constructs as if they had 2 options. */
|
|
|
|
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],
|
|
|
|
result, sizeof(result), &intval);
|
|
|
|
|
|
|
|
/* intval is now the number of the enum option we want to read,
|
2007-05-02 16:28:24 +00:00
|
|
|
starting from 1. If intval is -1, we check if value is empty. */
|
2007-04-08 14:00:00 +00:00
|
|
|
if (intval == -1)
|
2007-05-02 17:51:01 +00:00
|
|
|
intval = (value && *value) ? 1 : num_options;
|
2007-04-08 14:00:00 +00:00
|
|
|
else if (intval > num_options || intval < 1)
|
|
|
|
intval = num_options;
|
|
|
|
|
2007-11-18 13:24:39 +00:00
|
|
|
data->tokens[cond_index].value.i = (intval << 8) + num_options;
|
|
|
|
|
2008-09-06 14:56:02 +00:00
|
|
|
/* skip to the appropriate enum case */
|
2007-04-21 19:31:46 +00:00
|
|
|
int next = cond_index + 2;
|
2007-04-08 14:00:00 +00:00
|
|
|
for (i = 1; i < intval; i++)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2007-04-08 14:00:00 +00:00
|
|
|
next = data->tokens[next].value.i;
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2007-11-18 13:24:39 +00:00
|
|
|
*token_index = next;
|
|
|
|
|
|
|
|
if (prev_val == intval)
|
|
|
|
{
|
|
|
|
/* Same conditional case as previously. Return without clearing the
|
|
|
|
pictures */
|
|
|
|
return false;
|
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-11-18 15:32:45 +00:00
|
|
|
cond_end = find_conditional_end(data, cond_index + 2);
|
|
|
|
for (i = cond_index + 3; i < cond_end; i++)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2007-11-18 15:32:45 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
/* clear all pictures in the conditional and nested ones */
|
|
|
|
if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY)
|
2010-02-20 13:26:50 +00:00
|
|
|
clear_image_pos(gwps, find_image(data->tokens[i].value.i&0xFF, data));
|
2009-09-18 05:15:18 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_ALBUMART
|
|
|
|
if (data->albumart && data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY)
|
|
|
|
{
|
2009-10-16 19:14:41 +00:00
|
|
|
draw_album_art(gwps,
|
|
|
|
playback_current_aa_hid(data->playback_aa_slot), true);
|
2009-09-18 05:15:18 +00:00
|
|
|
data->albumart->draw = false;
|
|
|
|
}
|
2007-11-12 01:31:42 +00:00
|
|
|
#endif
|
2007-11-18 15:32:45 +00:00
|
|
|
}
|
2007-11-12 01:31:42 +00:00
|
|
|
|
2007-11-18 13:24:39 +00:00
|
|
|
return true;
|
2005-11-20 22:13:52 +00:00
|
|
|
}
|
2009-10-19 15:28:15 +00:00
|
|
|
|
2009-10-16 20:34:04 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
/* 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.
|
2005-11-20 22:13:52 +00:00
|
|
|
*/
|
2007-04-04 14:41:40 +00:00
|
|
|
static bool get_line(struct gui_wps *gwps,
|
2009-09-02 06:23:01 +00:00
|
|
|
struct skin_subline *subline,
|
2007-04-04 14:41:40 +00:00
|
|
|
struct align_pos *align,
|
|
|
|
char *linebuf,
|
2010-03-06 00:29:46 +00:00
|
|
|
int linebuf_size,
|
|
|
|
unsigned refresh_mode)
|
2005-11-20 22:13:52 +00:00
|
|
|
{
|
2007-04-04 14:41:40 +00:00
|
|
|
struct wps_data *data = gwps->data;
|
2005-11-20 22:13:52 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
char temp_buf[128];
|
|
|
|
char *buf = linebuf; /* will always point to the writing position */
|
|
|
|
char *linebuf_end = linebuf + linebuf_size - 1;
|
|
|
|
bool update = false;
|
2009-09-02 02:55:33 +00:00
|
|
|
int i;
|
2010-03-06 00:29:46 +00:00
|
|
|
(void)refresh_mode; /* silence warning on charcell */
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
/* alignment-related variables */
|
|
|
|
int cur_align;
|
|
|
|
char* cur_align_start;
|
|
|
|
cur_align_start = buf;
|
|
|
|
cur_align = WPS_ALIGN_LEFT;
|
2007-04-08 04:01:06 +00:00
|
|
|
align->left = NULL;
|
|
|
|
align->center = NULL;
|
|
|
|
align->right = NULL;
|
|
|
|
/* Process all tokens of the desired subline */
|
2009-09-02 02:55:33 +00:00
|
|
|
for (i = subline->first_token_idx;
|
|
|
|
i <= subline->last_token_idx; i++)
|
2005-11-18 09:03:25 +00:00
|
|
|
{
|
2007-04-04 14:41:40 +00:00
|
|
|
switch(data->tokens[i].type)
|
2005-11-18 09:03:25 +00:00
|
|
|
{
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_TOKEN_CONDITIONAL:
|
|
|
|
/* place ourselves in the right conditional case */
|
2007-11-18 13:24:39 +00:00
|
|
|
update |= evaluate_conditional(gwps, &i);
|
2007-04-04 14:41:40 +00:00
|
|
|
break;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
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;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY:
|
|
|
|
{
|
2009-08-18 07:17:51 +00:00
|
|
|
char n = data->tokens[i].value.i & 0xFF;
|
2008-03-23 20:31:00 +00:00
|
|
|
int subimage = data->tokens[i].value.i >> 8;
|
2009-08-16 18:23:00 +00:00
|
|
|
struct gui_img *img = find_image(n, data);
|
2008-03-23 20:31:00 +00:00
|
|
|
|
2009-08-16 18:23:00 +00:00
|
|
|
if (img && img->loaded)
|
|
|
|
img->display = subimage;
|
2007-04-04 14:41:40 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-03-06 00:29:46 +00:00
|
|
|
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;
|
2005-11-17 20:20:01 +00:00
|
|
|
#endif
|
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_TOKEN_ALIGN_LEFT:
|
2010-01-07 07:34:15 +00:00
|
|
|
case WPS_TOKEN_ALIGN_LEFT_RTL:
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_TOKEN_ALIGN_CENTER:
|
|
|
|
case WPS_TOKEN_ALIGN_RIGHT:
|
2010-01-07 07:34:15 +00:00
|
|
|
case WPS_TOKEN_ALIGN_RIGHT_RTL:
|
2007-04-04 14:41:40 +00:00
|
|
|
/* remember where the current aligned text started */
|
|
|
|
switch (cur_align)
|
|
|
|
{
|
|
|
|
case WPS_ALIGN_LEFT:
|
|
|
|
align->left = cur_align_start;
|
|
|
|
break;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_ALIGN_CENTER:
|
|
|
|
align->center = cur_align_start;
|
|
|
|
break;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_ALIGN_RIGHT:
|
|
|
|
align->right = cur_align_start;
|
2005-11-17 20:20:01 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
/* start a new alignment */
|
|
|
|
switch (data->tokens[i].type)
|
|
|
|
{
|
|
|
|
case WPS_TOKEN_ALIGN_LEFT:
|
|
|
|
cur_align = WPS_ALIGN_LEFT;
|
|
|
|
break;
|
2010-01-07 07:34:15 +00:00
|
|
|
case WPS_TOKEN_ALIGN_LEFT_RTL:
|
|
|
|
cur_align = lang_is_rtl() ? WPS_ALIGN_RIGHT :
|
|
|
|
WPS_ALIGN_LEFT;
|
|
|
|
break;
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_TOKEN_ALIGN_CENTER:
|
|
|
|
cur_align = WPS_ALIGN_CENTER;
|
|
|
|
break;
|
|
|
|
case WPS_TOKEN_ALIGN_RIGHT:
|
|
|
|
cur_align = WPS_ALIGN_RIGHT;
|
|
|
|
break;
|
2010-01-07 07:34:15 +00:00
|
|
|
case WPS_TOKEN_ALIGN_RIGHT_RTL:
|
|
|
|
cur_align = lang_is_rtl() ? WPS_ALIGN_LEFT :
|
|
|
|
WPS_ALIGN_RIGHT;
|
|
|
|
break;
|
2007-04-04 14:41:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
*buf++ = 0;
|
|
|
|
cur_align_start = buf;
|
|
|
|
break;
|
2008-06-23 06:04:17 +00:00
|
|
|
case WPS_VIEWPORT_ENABLE:
|
|
|
|
{
|
|
|
|
char label = data->tokens[i].value.i;
|
|
|
|
char temp = VP_DRAW_HIDEABLE;
|
2009-08-19 01:52:52 +00:00
|
|
|
/* viewports are allowed to share id's so find and enable
|
|
|
|
* all of them */
|
|
|
|
struct skin_token_list *list = data->viewports;
|
|
|
|
while (list)
|
2008-06-23 06:04:17 +00:00
|
|
|
{
|
2009-09-13 12:24:14 +00:00
|
|
|
struct skin_viewport *vp =
|
2009-08-19 01:52:52 +00:00
|
|
|
(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;
|
2008-06-23 06:04:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2010-01-13 06:02:38 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
case WPS_VIEWPORT_CUSTOMLIST:
|
|
|
|
draw_playlist_viewer_list(gwps, data->tokens[i].value.data);
|
|
|
|
break;
|
|
|
|
#endif
|
2007-04-04 14:41:40 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
/* get the value of the tag and copy it to the buffer */
|
2008-09-24 20:03:53 +00:00
|
|
|
const char *value = get_token_value(gwps, &data->tokens[i],
|
2007-04-08 14:00:00 +00:00
|
|
|
temp_buf, sizeof(temp_buf), NULL);
|
2007-04-04 14:41:40 +00:00
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
update = true;
|
|
|
|
while (*value && (buf < linebuf_end))
|
|
|
|
*buf++ = *value++;
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
/* close the current alignment */
|
|
|
|
switch (cur_align)
|
|
|
|
{
|
|
|
|
case WPS_ALIGN_LEFT:
|
|
|
|
align->left = cur_align_start;
|
|
|
|
break;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_ALIGN_CENTER:
|
|
|
|
align->center = cur_align_start;
|
|
|
|
break;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
case WPS_ALIGN_RIGHT:
|
|
|
|
align->right = cur_align_start;
|
|
|
|
break;
|
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
return update;
|
|
|
|
}
|
2009-09-02 06:23:01 +00:00
|
|
|
static void get_subline_timeout(struct gui_wps *gwps, struct skin_subline *subline)
|
2007-04-06 16:43:07 +00:00
|
|
|
{
|
|
|
|
struct wps_data *data = gwps->data;
|
2007-04-08 04:01:06 +00:00
|
|
|
int i;
|
2009-09-02 02:55:33 +00:00
|
|
|
subline->time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
|
2007-04-06 16:43:07 +00:00
|
|
|
|
2009-09-02 02:55:33 +00:00
|
|
|
for (i = subline->first_token_idx;
|
|
|
|
i <= subline->last_token_idx; i++)
|
2007-04-06 16:43:07 +00:00
|
|
|
{
|
|
|
|
switch(data->tokens[i].type)
|
|
|
|
{
|
|
|
|
case WPS_TOKEN_CONDITIONAL:
|
|
|
|
/* place ourselves in the right conditional case */
|
2007-11-18 13:24:39 +00:00
|
|
|
evaluate_conditional(gwps, &i);
|
2007-04-06 16:43:07 +00:00
|
|
|
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:
|
2009-09-02 02:55:33 +00:00
|
|
|
subline->time_mult = data->tokens[i].value.i;
|
2007-04-06 16:43:07 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-04-08 04:01:06 +00:00
|
|
|
/* Calculates which subline should be displayed for the specified line
|
|
|
|
Returns true iff the subline must be refreshed */
|
2009-09-02 06:23:01 +00:00
|
|
|
static bool update_curr_subline(struct gui_wps *gwps, struct skin_line *line)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-09-02 02:55:33 +00:00
|
|
|
/* shortcut this whole thing if we need to reset the line completly */
|
|
|
|
if (line->curr_subline == NULL)
|
|
|
|
{
|
2009-09-09 15:42:20 +00:00
|
|
|
line->subline_expire_time = current_tick;
|
2009-09-02 02:55:33 +00:00
|
|
|
line->curr_subline = &line->sublines;
|
|
|
|
if (!line->curr_subline->next)
|
2009-09-09 15:42:20 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2009-09-02 02:55:33 +00:00
|
|
|
return true;
|
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
/* if time to advance to next sub-line */
|
2009-09-02 02:55:33 +00:00
|
|
|
if (TIME_AFTER(current_tick, line->subline_expire_time - 1))
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-09-02 02:55:33 +00:00
|
|
|
/* 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)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-09-02 02:55:33 +00:00
|
|
|
line->subline_expire_time += 100 * HZ;
|
2009-10-12 20:22:50 +00:00
|
|
|
return false;
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
2009-09-02 02:55:33 +00:00
|
|
|
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);
|
2010-03-03 02:10:26 +00:00
|
|
|
line->subline_expire_time = current_tick + TIMEOUT_UNIT*line->curr_subline->time_mult;
|
2009-09-02 02:55:33 +00:00
|
|
|
return true;
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
2009-09-02 02:55:33 +00:00
|
|
|
return false;
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
/* 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,
|
|
|
|
struct align_pos *format_align,
|
|
|
|
int line,
|
|
|
|
bool scroll)
|
2005-11-17 20:20:01 +00:00
|
|
|
{
|
2007-11-12 21:34:01 +00:00
|
|
|
int left_width = 0, left_xpos;
|
2007-09-13 20:53:23 +00:00
|
|
|
int center_width = 0, center_xpos;
|
|
|
|
int right_width = 0, right_xpos;
|
2007-04-04 14:41:40 +00:00
|
|
|
int ypos;
|
|
|
|
int space_width;
|
|
|
|
int string_height;
|
2007-11-12 21:34:01 +00:00
|
|
|
int scroll_width;
|
2007-04-04 14:41:40 +00:00
|
|
|
|
|
|
|
/* calculate different string sizes and positions */
|
|
|
|
display->getstringsize((unsigned char *)" ", &space_width, &string_height);
|
|
|
|
if (format_align->left != 0) {
|
|
|
|
display->getstringsize((unsigned char *)format_align->left,
|
|
|
|
&left_width, &string_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (format_align->right != 0) {
|
|
|
|
display->getstringsize((unsigned char *)format_align->right,
|
|
|
|
&right_width, &string_height);
|
|
|
|
}
|
2007-09-13 20:53:23 +00:00
|
|
|
|
2007-11-12 21:34:01 +00:00
|
|
|
if (format_align->center != 0) {
|
|
|
|
display->getstringsize((unsigned char *)format_align->center,
|
|
|
|
¢er_width, &string_height);
|
|
|
|
}
|
|
|
|
|
2008-06-23 13:20:35 +00:00
|
|
|
left_xpos = 0;
|
2008-03-21 19:38:00 +00:00
|
|
|
right_xpos = (display->getwidth() - right_width);
|
|
|
|
center_xpos = (display->getwidth() + left_xpos - center_width) / 2;
|
2007-11-12 21:34:01 +00:00
|
|
|
|
2008-03-21 19:38:00 +00:00
|
|
|
scroll_width = display->getwidth() - left_xpos;
|
2007-04-04 14:41:40 +00:00
|
|
|
|
|
|
|
/* Checks for overlapping strings.
|
|
|
|
If needed the overlapping strings will be merged, separated by a
|
|
|
|
space */
|
|
|
|
|
|
|
|
/* CASE 1: left and centered string overlap */
|
|
|
|
/* there is a left string, need to merge left and center */
|
|
|
|
if ((left_width != 0 && center_width != 0) &&
|
2007-11-12 21:34:01 +00:00
|
|
|
(left_xpos + left_width + space_width > center_xpos)) {
|
2007-04-04 14:41:40 +00:00
|
|
|
/* replace the former separator '\0' of left and
|
|
|
|
center string with a space */
|
|
|
|
*(--format_align->center) = ' ';
|
|
|
|
/* calculate the new width and position of the merged string */
|
|
|
|
left_width = left_width + space_width + center_width;
|
|
|
|
/* there is no centered string anymore */
|
|
|
|
center_width = 0;
|
|
|
|
}
|
|
|
|
/* there is no left string, move center to left */
|
|
|
|
if ((left_width == 0 && center_width != 0) &&
|
2007-11-12 21:34:01 +00:00
|
|
|
(left_xpos + left_width > center_xpos)) {
|
2007-04-04 14:41:40 +00:00
|
|
|
/* move the center string to the left string */
|
|
|
|
format_align->left = format_align->center;
|
|
|
|
/* calculate the new width and position of the string */
|
|
|
|
left_width = center_width;
|
|
|
|
/* there is no centered string anymore */
|
|
|
|
center_width = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* CASE 2: centered and right string overlap */
|
|
|
|
/* there is a right string, need to merge center and right */
|
|
|
|
if ((center_width != 0 && right_width != 0) &&
|
|
|
|
(center_xpos + center_width + space_width > right_xpos)) {
|
|
|
|
/* replace the former separator '\0' of center and
|
|
|
|
right string with a space */
|
|
|
|
*(--format_align->right) = ' ';
|
|
|
|
/* move the center string to the right after merge */
|
|
|
|
format_align->right = format_align->center;
|
|
|
|
/* calculate the new width and position of the merged string */
|
|
|
|
right_width = center_width + space_width + right_width;
|
2008-03-21 19:38:00 +00:00
|
|
|
right_xpos = (display->getwidth() - right_width);
|
2007-04-04 14:41:40 +00:00
|
|
|
/* there is no centered string anymore */
|
|
|
|
center_width = 0;
|
|
|
|
}
|
|
|
|
/* there is no right string, move center to right */
|
|
|
|
if ((center_width != 0 && right_width == 0) &&
|
|
|
|
(center_xpos + center_width > right_xpos)) {
|
|
|
|
/* move the center string to the right string */
|
|
|
|
format_align->right = format_align->center;
|
|
|
|
/* calculate the new width and position of the string */
|
|
|
|
right_width = center_width;
|
2008-03-21 19:38:00 +00:00
|
|
|
right_xpos = (display->getwidth() - right_width);
|
2007-04-04 14:41:40 +00:00
|
|
|
/* there is no centered string anymore */
|
|
|
|
center_width = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* CASE 3: left and right overlap
|
|
|
|
There is no center string anymore, either there never
|
|
|
|
was one or it has been merged in case 1 or 2 */
|
|
|
|
/* there is a left string, need to merge left and right */
|
|
|
|
if ((left_width != 0 && center_width == 0 && right_width != 0) &&
|
2007-11-12 21:34:01 +00:00
|
|
|
(left_xpos + left_width + space_width > right_xpos)) {
|
2007-04-04 14:41:40 +00:00
|
|
|
/* replace the former separator '\0' of left and
|
|
|
|
right string with a space */
|
|
|
|
*(--format_align->right) = ' ';
|
|
|
|
/* calculate the new width and position of the string */
|
|
|
|
left_width = left_width + space_width + right_width;
|
|
|
|
/* there is no right string anymore */
|
|
|
|
right_width = 0;
|
|
|
|
}
|
|
|
|
/* there is no left string, move right to left */
|
|
|
|
if ((left_width == 0 && center_width == 0 && right_width != 0) &&
|
2007-09-13 20:53:23 +00:00
|
|
|
(left_width > right_xpos)) {
|
2007-04-04 14:41:40 +00:00
|
|
|
/* move the right string to the left string */
|
|
|
|
format_align->left = format_align->right;
|
|
|
|
/* calculate the new width and position of the string */
|
|
|
|
left_width = right_width;
|
|
|
|
/* there is no right string anymore */
|
|
|
|
right_width = 0;
|
|
|
|
}
|
|
|
|
|
2008-06-23 13:20:35 +00:00
|
|
|
ypos = (line * string_height);
|
2007-04-04 14:41:40 +00:00
|
|
|
|
|
|
|
|
2009-09-13 12:24:14 +00:00
|
|
|
if (scroll && ((left_width > scroll_width) ||
|
2007-11-12 21:34:01 +00:00
|
|
|
(center_width > scroll_width) ||
|
|
|
|
(right_width > scroll_width)))
|
2005-11-17 20:20:01 +00:00
|
|
|
{
|
2007-04-04 14:41:40 +00:00
|
|
|
display->puts_scroll(0, line,
|
|
|
|
(unsigned char *)format_align->left);
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef HAVE_LCD_BITMAP
|
2007-04-04 14:41:40 +00:00
|
|
|
/* clear the line first */
|
|
|
|
display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
2008-03-21 19:38:00 +00:00
|
|
|
display->fillrect(left_xpos, ypos, display->getwidth(), string_height);
|
2007-04-04 14:41:40 +00:00
|
|
|
display->set_drawmode(DRMODE_SOLID);
|
2005-11-17 20:20:01 +00:00
|
|
|
#endif
|
2007-04-04 14:41:40 +00:00
|
|
|
|
|
|
|
/* Nasty hack: we output an empty scrolling string,
|
|
|
|
which will reset the scroller for that line */
|
|
|
|
display->puts_scroll(0, line, (unsigned char *)"");
|
|
|
|
|
|
|
|
/* print aligned strings */
|
|
|
|
if (left_width != 0)
|
|
|
|
{
|
2007-11-12 21:34:01 +00:00
|
|
|
display->putsxy(left_xpos, ypos,
|
2007-04-04 14:41:40 +00:00
|
|
|
(unsigned char *)format_align->left);
|
|
|
|
}
|
|
|
|
if (center_width != 0)
|
|
|
|
{
|
|
|
|
display->putsxy(center_xpos, ypos,
|
|
|
|
(unsigned char *)format_align->center);
|
|
|
|
}
|
|
|
|
if (right_width != 0)
|
|
|
|
{
|
|
|
|
display->putsxy(right_xpos, ypos,
|
|
|
|
(unsigned char *)format_align->right);
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-06 04:33:35 +00:00
|
|
|
static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
|
2005-11-17 20:20:01 +00:00
|
|
|
{
|
2007-04-04 14:41:40 +00:00
|
|
|
struct wps_data *data = gwps->data;
|
|
|
|
struct screen *display = gwps->display;
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-10-16 19:14:37 +00:00
|
|
|
if (!data || !display || !gwps->state)
|
2007-04-04 14:41:40 +00:00
|
|
|
return false;
|
2009-09-13 12:24:14 +00:00
|
|
|
|
2009-03-23 03:08:56 +00:00
|
|
|
unsigned flags;
|
2007-04-04 14:41:40 +00:00
|
|
|
char linebuf[MAX_PATH];
|
2007-02-14 14:40:24 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
struct align_pos align;
|
|
|
|
align.left = NULL;
|
|
|
|
align.center = NULL;
|
|
|
|
align.right = NULL;
|
2009-09-13 12:24:14 +00:00
|
|
|
|
|
|
|
|
2009-09-02 02:55:33 +00:00
|
|
|
struct skin_token_list *viewport_list;
|
2007-02-14 14:40:24 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
bool update_line, new_subline_refresh;
|
2007-02-14 14:40:24 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
2007-02-14 14:40:24 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
/* to find out wether the peak meter is enabled we
|
|
|
|
assume it wasn't until we find a line that contains
|
|
|
|
the peak meter. We can't use peak_meter_enabled itself
|
|
|
|
because that would mean to turn off the meter thread
|
|
|
|
temporarily. (That shouldn't matter unless yield
|
|
|
|
or sleep is called but who knows...)
|
|
|
|
*/
|
|
|
|
bool enable_pm = false;
|
2007-02-14 14:40:24 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* reset to first subline if refresh all flag is set */
|
|
|
|
if (refresh_mode == WPS_REFRESH_ALL)
|
|
|
|
{
|
2009-09-02 06:23:01 +00:00
|
|
|
struct skin_line *line;
|
2009-10-19 15:28:15 +00:00
|
|
|
struct skin_viewport *skin_viewport = find_viewport(VP_DEFAULT_LABEL, data);
|
2010-01-29 07:52:13 +00:00
|
|
|
|
2009-10-19 15:28:15 +00:00
|
|
|
if (!(skin_viewport->hidden_flags & VP_NEVER_VISIBLE))
|
|
|
|
{
|
|
|
|
display->set_viewport(&skin_viewport->vp);
|
|
|
|
display->clear_viewport();
|
|
|
|
}
|
2009-09-13 12:24:14 +00:00
|
|
|
|
|
|
|
for (viewport_list = data->viewports;
|
2009-09-02 02:55:33 +00:00
|
|
|
viewport_list; viewport_list = viewport_list->next)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-10-19 15:28:15 +00:00
|
|
|
skin_viewport =
|
|
|
|
(struct skin_viewport *)viewport_list->token->value.data;
|
2009-09-02 02:55:33 +00:00
|
|
|
for(line = skin_viewport->lines; line; line = line->next)
|
|
|
|
{
|
|
|
|
line->curr_subline = NULL;
|
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
#ifdef HAVE_LCD_CHARCELLS
|
2009-09-02 03:02:00 +00:00
|
|
|
int i;
|
2007-04-04 14:41:40 +00:00
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
{
|
2010-03-06 14:14:44 +00:00
|
|
|
if (data->wps_progress_pat[i] == 0)
|
|
|
|
data->wps_progress_pat[i] = display->get_locked_pattern();
|
2005-11-17 20:20:01 +00:00
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
#endif
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2009-12-21 06:35:31 +00:00
|
|
|
/* 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)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-12-21 06:35:31 +00:00
|
|
|
for (viewport_list = data->viewports;
|
|
|
|
viewport_list; viewport_list = viewport_list->next)
|
2007-02-28 23:43:38 +00:00
|
|
|
{
|
2009-12-21 06:35:31 +00:00
|
|
|
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;
|
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2008-06-23 06:04:17 +00:00
|
|
|
}
|
2009-09-07 02:36:56 +00:00
|
|
|
int viewport_count = 0;
|
2009-09-13 12:24:14 +00:00
|
|
|
for (viewport_list = data->viewports;
|
2009-09-07 02:36:56 +00:00
|
|
|
viewport_list; viewport_list = viewport_list->next, viewport_count++)
|
2008-06-23 06:04:17 +00:00
|
|
|
{
|
2009-09-13 12:24:14 +00:00
|
|
|
struct skin_viewport *skin_viewport =
|
2009-08-18 05:30:59 +00:00
|
|
|
(struct skin_viewport *)viewport_list->token->value.data;
|
2009-03-23 03:08:56 +00:00
|
|
|
unsigned vp_refresh_mode = refresh_mode;
|
2009-10-19 15:28:15 +00:00
|
|
|
|
2009-08-18 05:30:59 +00:00
|
|
|
display->set_viewport(&skin_viewport->vp);
|
2007-02-14 14:40:24 +00:00
|
|
|
|
2009-10-19 15:28:15 +00:00
|
|
|
int hidden_vp = 0;
|
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
2008-03-21 19:38:00 +00:00
|
|
|
/* Set images to not to be displayed */
|
2009-08-16 18:23:00 +00:00
|
|
|
struct skin_token_list *imglist = data->images;
|
|
|
|
while (imglist)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-09-13 12:24:14 +00:00
|
|
|
struct gui_img *img = (struct gui_img *)imglist->token->value.data;
|
2009-08-16 18:23:00 +00:00
|
|
|
img->display = -1;
|
|
|
|
imglist = imglist->next;
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
2008-03-21 19:38:00 +00:00
|
|
|
#endif
|
2008-06-23 06:04:17 +00:00
|
|
|
/* dont redraw the viewport if its disabled */
|
2009-10-19 15:28:15 +00:00
|
|
|
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))
|
2008-06-23 06:04:17 +00:00
|
|
|
{
|
2009-08-18 05:30:59 +00:00
|
|
|
if (!(skin_viewport->hidden_flags&VP_DRAW_WASHIDDEN))
|
|
|
|
display->scroll_stop(&skin_viewport->vp);
|
|
|
|
skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN;
|
2008-06-23 06:04:17 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-08-18 05:30:59 +00:00
|
|
|
else if (((skin_viewport->hidden_flags&
|
2008-06-23 06:04:17 +00:00
|
|
|
(VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))
|
|
|
|
== (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)))
|
|
|
|
{
|
|
|
|
vp_refresh_mode = WPS_REFRESH_ALL;
|
2009-08-18 05:30:59 +00:00
|
|
|
skin_viewport->hidden_flags = VP_DRAW_HIDEABLE;
|
2008-06-23 06:04:17 +00:00
|
|
|
}
|
2009-10-19 15:28:15 +00:00
|
|
|
|
2008-06-23 06:04:17 +00:00
|
|
|
if (vp_refresh_mode == WPS_REFRESH_ALL)
|
|
|
|
{
|
|
|
|
display->clear_viewport();
|
|
|
|
}
|
2009-09-13 12:24:14 +00:00
|
|
|
|
2009-09-02 02:55:33 +00:00
|
|
|
/* loop over the lines for this viewport */
|
2009-09-02 06:23:01 +00:00
|
|
|
struct skin_line *line;
|
2009-09-02 02:55:33 +00:00
|
|
|
int line_count = 0;
|
2009-09-13 12:24:14 +00:00
|
|
|
|
2009-09-02 02:55:33 +00:00
|
|
|
for (line = skin_viewport->lines; line; line = line->next, line_count++)
|
2007-04-04 14:41:40 +00:00
|
|
|
{
|
2009-09-02 06:23:01 +00:00
|
|
|
struct skin_subline *subline;
|
2008-03-21 19:38:00 +00:00
|
|
|
memset(linebuf, 0, sizeof(linebuf));
|
2007-04-04 14:41:40 +00:00
|
|
|
update_line = false;
|
|
|
|
|
2008-03-21 19:38:00 +00:00
|
|
|
/* get current subline for the line */
|
2008-03-22 00:31:22 +00:00
|
|
|
new_subline_refresh = update_curr_subline(gwps, line);
|
2009-09-02 02:55:33 +00:00
|
|
|
subline = line->curr_subline;
|
|
|
|
flags = line->curr_subline->line_type;
|
2008-03-21 19:38:00 +00:00
|
|
|
|
2008-06-23 06:04:17 +00:00
|
|
|
if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode)
|
2009-10-19 15:28:15 +00:00
|
|
|
|| new_subline_refresh || hidden_vp)
|
2008-03-21 19:38:00 +00:00
|
|
|
{
|
|
|
|
/* get_line tells us if we need to update the line */
|
2010-03-06 00:29:46 +00:00
|
|
|
update_line = get_line(gwps, subline, &align,
|
|
|
|
linebuf, sizeof(linebuf), vp_refresh_mode);
|
2008-03-21 19:38:00 +00:00
|
|
|
}
|
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
/* peakmeter */
|
2008-06-23 06:04:17 +00:00
|
|
|
if (flags & vp_refresh_mode & WPS_REFRESH_PEAK_METER)
|
2008-03-21 19:38:00 +00:00
|
|
|
{
|
|
|
|
/* the peakmeter should be alone on its line */
|
|
|
|
update_line = false;
|
|
|
|
|
2009-08-18 05:30:59 +00:00
|
|
|
int h = font_get(skin_viewport->vp.font)->height;
|
2009-09-02 02:55:33 +00:00
|
|
|
int peak_meter_y = line_count* h;
|
2008-03-21 19:38:00 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2009-09-02 02:55:33 +00:00
|
|
|
if (peak_meter_y + h <= skin_viewport->vp.y+skin_viewport->vp.height) {
|
2008-03-21 19:38:00 +00:00
|
|
|
/* found a line with a peak meter -> remember that we must
|
|
|
|
enable it later */
|
|
|
|
enable_pm = true;
|
2008-08-11 22:12:40 +00:00
|
|
|
peak_meter_enabled = true;
|
2008-03-21 19:38:00 +00:00
|
|
|
peak_meter_screen(gwps->display, 0, peak_meter_y,
|
2009-09-02 02:55:33 +00:00
|
|
|
MIN(h, skin_viewport->vp.y+skin_viewport->vp.height - peak_meter_y));
|
2008-03-21 19:38:00 +00:00
|
|
|
}
|
2008-08-11 22:12:40 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
peak_meter_enabled = false;
|
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#else /* HAVE_LCD_CHARCELL */
|
|
|
|
|
2008-03-21 19:38:00 +00:00
|
|
|
/* progressbar */
|
2008-06-23 06:04:17 +00:00
|
|
|
if (flags & vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
|
2008-03-21 19:38:00 +00:00
|
|
|
{
|
|
|
|
if (data->full_line_progressbar)
|
|
|
|
draw_player_fullbar(gwps, linebuf, sizeof(linebuf));
|
|
|
|
else
|
|
|
|
draw_player_progress(gwps);
|
|
|
|
}
|
2007-04-04 14:41:40 +00:00
|
|
|
#endif
|
|
|
|
|
2009-10-19 15:28:15 +00:00
|
|
|
if (update_line && !hidden_vp &&
|
2008-06-23 06:04:17 +00:00
|
|
|
/* 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 */
|
2009-08-18 05:30:59 +00:00
|
|
|
((skin_viewport->label != VP_DEFAULT_LABEL && viewport_list->next) ||
|
|
|
|
!viewport_list->next))
|
2007-04-09 14:06:38 +00:00
|
|
|
{
|
2008-03-21 19:38:00 +00:00
|
|
|
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 */
|
2008-06-23 06:04:17 +00:00
|
|
|
if ((vp_refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh)
|
2009-09-02 02:55:33 +00:00
|
|
|
write_line(display, &align, line_count, true);
|
2008-03-21 19:38:00 +00:00
|
|
|
}
|
|
|
|
else
|
2009-09-02 02:55:33 +00:00
|
|
|
write_line(display, &align, line_count, false);
|
2007-04-09 14:06:38 +00:00
|
|
|
}
|
2007-02-14 14:40:24 +00:00
|
|
|
}
|
2008-03-21 19:38:00 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
2008-06-23 06:04:17 +00:00
|
|
|
/* progressbar */
|
|
|
|
if (vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
|
|
|
|
{
|
2009-08-18 05:30:59 +00:00
|
|
|
if (skin_viewport->pb)
|
2009-02-16 08:28:51 +00:00
|
|
|
{
|
2009-08-18 05:30:59 +00:00
|
|
|
draw_progressbar(gwps, skin_viewport);
|
2009-02-16 08:28:51 +00:00
|
|
|
}
|
2008-06-23 06:04:17 +00:00
|
|
|
}
|
2008-03-21 19:38:00 +00:00
|
|
|
/* Now display any images in this viewport */
|
2009-10-19 15:28:15 +00:00
|
|
|
if (!hidden_vp)
|
|
|
|
wps_display_images(gwps, &skin_viewport->vp);
|
2008-03-21 19:38:00 +00:00
|
|
|
#endif
|
2007-02-14 14:40:24 +00:00
|
|
|
}
|
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
data->peak_meter_enabled = enable_pm;
|
|
|
|
#endif
|
2008-03-21 19:38:00 +00:00
|
|
|
/* Restore the default viewport */
|
|
|
|
display->set_viewport(NULL);
|
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
display->update();
|
2005-11-17 20:20:01 +00:00
|
|
|
|
2007-04-04 14:41:40 +00:00
|
|
|
return true;
|
|
|
|
}
|