summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/gui/skin_engine/skin_display.c190
-rw-r--r--apps/gui/skin_engine/skin_display.h3
-rw-r--r--apps/gui/skin_engine/skin_parser.c3
-rw-r--r--apps/gui/skin_engine/skin_render.c112
-rw-r--r--apps/gui/skin_engine/skin_tokens.c114
-rw-r--r--apps/gui/skin_engine/wps_internals.h13
6 files changed, 198 insertions, 237 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index d0044b14d8..53b568ad53 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -205,191 +205,6 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
205 } 205 }
206} 206}
207 207
208void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer)
209{
210 struct wps_state *state = gwps->state;
211 int lines = viewport_get_nb_lines(viewer->vp);
212 int line_height = font_get(viewer->vp->font)->height;
213 int cur_pos, max;
214 int start_item;
215 int i;
216 bool scroll = false;
217 struct wps_token *token;
218 int x, length, alignment = SKIN_TOKEN_ALIGN_LEFT;
219
220 struct mp3entry *pid3;
221 char buf[MAX_PATH*2], tempbuf[MAX_PATH], filename_buf[MAX_PATH + 1];
222 const char *filename;
223#if CONFIG_TUNER
224 if (current_screen() == GO_TO_FM)
225 {
226 cur_pos = radio_current_preset();
227 start_item = cur_pos + viewer->start_offset;
228 max = start_item+radio_preset_count();
229 }
230 else
231#endif
232 {
233 cur_pos = playlist_get_display_index();
234 max = playlist_amount()+1;
235 start_item = MAX(0, cur_pos + viewer->start_offset);
236 }
237
238 gwps->display->set_viewport(viewer->vp);
239 for(i=start_item; (i-start_item)<lines && i<max; i++)
240 {
241 int line;
242#if CONFIG_TUNER
243 if (current_screen() == GO_TO_FM)
244 {
245 pid3 = NULL;
246 line = TRACK_HAS_INFO;
247 filename = "";
248 }
249 else
250#endif
251 {
252 filename = playlist_peek(i-cur_pos, filename_buf,
253 sizeof(filename_buf));
254 if (i == cur_pos)
255 {
256 pid3 = state->id3;
257 }
258 else if (i == cur_pos+1)
259 {
260 pid3 = state->nid3;
261 }
262#if CONFIG_CODEC == SWCODEC
263 else if (i>cur_pos)
264 {
265#ifdef HAVE_TC_RAMCACHE
266 if (tagcache_fill_tags(&viewer->tempid3, filename))
267 {
268 pid3 = &viewer->tempid3;
269 }
270 else
271#endif
272 if (!audio_peek_track(&pid3, i-cur_pos))
273 pid3 = NULL;
274 }
275#endif
276 else
277 {
278 pid3 = NULL;
279 }
280 line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO;
281 }
282 unsigned int line_len = 0;
283 if (viewer->lines[line]->children_count == 0)
284 return;
285 struct skin_element *element = viewer->lines[line]->children[0];
286 buf[0] = '\0';
287 while (element && line_len < sizeof(buf))
288 {
289 const char *out = NULL;
290 if (element->type == TEXT)
291 {
292 line_len = strlcat(buf, (char*)element->data, sizeof(buf));
293 element = element->next;
294 continue;
295 }
296 if (element->type != TAG)
297 {
298 element = element->next;
299 continue;
300 }
301 if (element->tag->type == SKIN_TOKEN_SUBLINE_SCROLL)
302 scroll = true;
303 token = (struct wps_token*)element->data;
304 out = get_id3_token(token, pid3, tempbuf, sizeof(tempbuf), -1, NULL);
305#if CONFIG_TUNER
306 if (!out)
307 out = get_radio_token(token, i-cur_pos,
308 tempbuf, sizeof(tempbuf), -1, NULL);
309#endif
310 if (out)
311 {
312 line_len = strlcat(buf, out, sizeof(buf));
313 element = element->next;
314 continue;
315 }
316
317 switch (token->type)
318 {
319 case SKIN_TOKEN_ALIGN_CENTER:
320 case SKIN_TOKEN_ALIGN_LEFT:
321 case SKIN_TOKEN_ALIGN_LEFT_RTL:
322 case SKIN_TOKEN_ALIGN_RIGHT:
323 case SKIN_TOKEN_ALIGN_RIGHT_RTL:
324 alignment = token->type;
325 tempbuf[0] = '\0';
326 break;
327 case SKIN_TOKEN_PLAYLIST_POSITION:
328 snprintf(tempbuf, sizeof(tempbuf), "%d", i);
329 break;
330 case SKIN_TOKEN_FILE_NAME:
331 get_dir(tempbuf, sizeof(tempbuf), filename, 0);
332 break;
333 case SKIN_TOKEN_FILE_PATH:
334 snprintf(tempbuf, sizeof(tempbuf), "%s", filename);
335 break;
336 default:
337 tempbuf[0] = '\0';
338 break;
339 }
340 if (tempbuf[0])
341 {
342 line_len = strlcat(buf, tempbuf, sizeof(buf));
343 }
344 element = element->next;
345 }
346
347 int vpwidth = viewer->vp->width;
348 length = gwps->display->getstringsize(buf, NULL, NULL);
349 if (scroll && length >= vpwidth)
350 {
351 gwps->display->puts_scroll(0, (i-start_item), buf );
352 }
353 else
354 {
355 if (length >= vpwidth)
356 x = 0;
357 else
358 {
359 switch (alignment)
360 {
361 case SKIN_TOKEN_ALIGN_CENTER:
362 x = (vpwidth-length)/2;
363 break;
364 case SKIN_TOKEN_ALIGN_LEFT_RTL:
365 if (lang_is_rtl() && VP_IS_RTL(viewer->vp))
366 {
367 x = vpwidth - length;
368 break;
369 }
370 case SKIN_TOKEN_ALIGN_LEFT:
371 x = 0;
372 break;
373 case SKIN_TOKEN_ALIGN_RIGHT_RTL:
374 if (lang_is_rtl() && VP_IS_RTL(viewer->vp))
375 {
376 x = 0;
377 break;
378 }
379 case SKIN_TOKEN_ALIGN_RIGHT:
380 x = vpwidth - length;
381 break;
382 default:
383 x = 0;
384 break;
385 }
386 }
387 gwps->display->putsxy(x, (i-start_item)*line_height, buf );
388 }
389 }
390}
391
392
393/* clears the area where the image was shown */ 208/* clears the area where the image was shown */
394void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) 209void clear_image_pos(struct gui_wps *gwps, struct gui_img *img)
395{ 210{
@@ -618,7 +433,8 @@ void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
618/* Evaluate the conditional that is at *token_index and return whether a skip 433/* Evaluate the conditional that is at *token_index and return whether a skip
619 has ocurred. *token_index is updated with the new position. 434 has ocurred. *token_index is updated with the new position.
620*/ 435*/
621int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional, int num_options) 436int evaluate_conditional(struct gui_wps *gwps, int offset,
437 struct conditional *conditional, int num_options)
622{ 438{
623 if (!gwps) 439 if (!gwps)
624 return false; 440 return false;
@@ -633,7 +449,7 @@ int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional,
633 449
634 int intval = num_options; 450 int intval = num_options;
635 /* get_token_value needs to know the number of options in the enum */ 451 /* get_token_value needs to know the number of options in the enum */
636 value = get_token_value(gwps, conditional->token, 452 value = get_token_value(gwps, conditional->token, offset,
637 result, sizeof(result), &intval); 453 result, sizeof(result), &intval);
638 454
639 /* intval is now the number of the enum option we want to read, 455 /* intval is now the number of the enum option we want to read,
diff --git a/apps/gui/skin_engine/skin_display.h b/apps/gui/skin_engine/skin_display.h
index 81274a7391..67b7bfdf27 100644
--- a/apps/gui/skin_engine/skin_display.h
+++ b/apps/gui/skin_engine/skin_display.h
@@ -44,7 +44,8 @@ void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size);
44/* Evaluate the conditional that is at *token_index and return whether a skip 44/* Evaluate the conditional that is at *token_index and return whether a skip
45 has ocurred. *token_index is updated with the new position. 45 has ocurred. *token_index is updated with the new position.
46*/ 46*/
47int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional, int num_options); 47int evaluate_conditional(struct gui_wps *gwps, int offset,
48 struct conditional *conditional, int num_options);
48/* Display a line appropriately according to its alignment format. 49/* Display a line appropriately according to its alignment format.
49 format_align contains the text, separated between left, center and right. 50 format_align contains the text, separated between left, center and right.
50 line is the index of the line on the screen. 51 line is the index of the line on the screen.
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 8bc7edf9c3..8fca8724f6 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -385,8 +385,7 @@ static int parse_playlistview(struct skin_element *element,
385 viewer->vp = &curr_vp->vp; 385 viewer->vp = &curr_vp->vp;
386 viewer->show_icons = true; 386 viewer->show_icons = true;
387 viewer->start_offset = element->params[0].data.number; 387 viewer->start_offset = element->params[0].data.number;
388 viewer->lines[0] = element->params[1].data.code; 388 viewer->line = element->params[1].data.code;
389 viewer->lines[1] = element->params[2].data.code;
390 389
391 token->value.data = (void*)viewer; 390 token->value.data = (void*)viewer;
392 391
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 3cc506b800..18b37ca22f 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -39,8 +39,12 @@
39#if CONFIG_TUNER 39#if CONFIG_TUNER
40#include "radio.h" 40#include "radio.h"
41#endif 41#endif
42#include "viewport.h"
43#include "cuesheet.h"
42#include "language.h" 44#include "language.h"
43#include "playback.h" 45#include "playback.h"
46#include "playlist.h"
47#include "misc.h"
44 48
45 49
46#define MAX_LINE 1024 50#define MAX_LINE 1024
@@ -59,11 +63,18 @@ struct skin_draw_info {
59 63
60 char *buf; 64 char *buf;
61 size_t buf_size; 65 size_t buf_size;
66
67 int offset; /* used by the playlist viewer */
62}; 68};
63 69
64typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info); 70typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info);
65bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info); 71bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info);
66 72
73static void skin_render_playlistviewer(struct playlistviewer* viewer,
74 struct gui_wps *gwps,
75 struct skin_viewport* skin_viewport,
76 unsigned long refresh_type);
77
67 78
68static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, 79static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
69 struct skin_element *element, struct viewport* vp) 80 struct skin_element *element, struct viewport* vp)
@@ -159,7 +170,8 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
159 char buf[16]; 170 char buf[16];
160 const char *out; 171 const char *out;
161 int a = img->num_subimages; 172 int a = img->num_subimages;
162 out = get_token_value(gwps, id->token, buf, sizeof(buf), &a); 173 out = get_token_value(gwps, id->token, info->offset,
174 buf, sizeof(buf), &a);
163 175
164 /* NOTE: get_token_value() returns values starting at 1! */ 176 /* NOTE: get_token_value() returns values starting at 1! */
165 if (a == -1) 177 if (a == -1)
@@ -207,7 +219,8 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
207 break; 219 break;
208 case SKIN_TOKEN_VIEWPORT_CUSTOMLIST: 220 case SKIN_TOKEN_VIEWPORT_CUSTOMLIST:
209 if (do_refresh) 221 if (do_refresh)
210 draw_playlist_viewer_list(gwps, token->value.data); 222 skin_render_playlistviewer(token->value.data, gwps,
223 info->skin_vp, info->refresh_type);
211 break; 224 break;
212 225
213#endif /* HAVE_LCD_BITMAP */ 226#endif /* HAVE_LCD_BITMAP */
@@ -377,7 +390,8 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
377 case CONDITIONAL: 390 case CONDITIONAL:
378 conditional = (struct conditional*)child->data; 391 conditional = (struct conditional*)child->data;
379 last_value = conditional->last_value; 392 last_value = conditional->last_value;
380 value = evaluate_conditional(info->gwps, conditional, child->children_count); 393 value = evaluate_conditional(info->gwps, info->offset,
394 conditional, child->children_count);
381 395
382 if (value != 1 && value >= child->children_count) 396 if (value != 1 && value >= child->children_count)
383 value = child->children_count-1; 397 value = child->children_count-1;
@@ -435,7 +449,8 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
435 if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp)) 449 if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp))
436 { 450 {
437 const char *value = get_token_value(info->gwps, child->data, 451 const char *value = get_token_value(info->gwps, child->data,
438 tempbuf, sizeof(tempbuf), NULL); 452 info->offset, tempbuf,
453 sizeof(tempbuf), NULL);
439 if (value) 454 if (value)
440 { 455 {
441 needs_update = needs_update || 456 needs_update = needs_update ||
@@ -520,7 +535,8 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
520 .no_line_break = false, 535 .no_line_break = false,
521 .line_scrolls = false, 536 .line_scrolls = false,
522 .refresh_type = refresh_type, 537 .refresh_type = refresh_type,
523 .skin_vp = skin_viewport 538 .skin_vp = skin_viewport,
539 .offset = 0
524 }; 540 };
525 541
526 struct align_pos * align = &info.align; 542 struct align_pos * align = &info.align;
@@ -647,3 +663,89 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
647 display->set_viewport(NULL); 663 display->set_viewport(NULL);
648 display->update(); 664 display->update();
649} 665}
666
667
668static void skin_render_playlistviewer(struct playlistviewer* viewer,
669 struct gui_wps *gwps,
670 struct skin_viewport* skin_viewport,
671 unsigned long refresh_type)
672{
673 struct screen *display = gwps->display;
674 char linebuf[MAX_LINE];
675 skin_render_func func = skin_render_line;
676 struct skin_element* line;
677 struct skin_draw_info info = {
678 .gwps = gwps,
679 .buf = linebuf,
680 .buf_size = sizeof(linebuf),
681 .line_number = 0,
682 .no_line_break = false,
683 .line_scrolls = false,
684 .refresh_type = refresh_type,
685 .skin_vp = skin_viewport,
686 .offset = viewer->start_offset
687 };
688
689 struct align_pos * align = &info.align;
690 bool needs_update;
691 int cur_pos, start_item, max;
692 int nb_lines = viewport_get_nb_lines(viewer->vp);
693#if CONFIG_TUNER
694 if (current_screen() == GO_TO_FM)
695 {
696 cur_pos = radio_current_preset();
697 start_item = cur_pos + viewer->start_offset;
698 max = start_item+radio_preset_count();
699 }
700 else
701#endif
702 {
703 struct cuesheet *cue = gwps->state->id3 ? gwps->state->id3->cuesheet:NULL;
704 cur_pos = playlist_get_display_index();
705 max = playlist_amount()+1;
706 if (cue)
707 max += cue->track_count;
708 start_item = MAX(0, cur_pos + viewer->start_offset);
709 }
710 if (max-start_item > nb_lines)
711 max = start_item + nb_lines;
712
713 line = viewer->line;
714 while (start_item < max)
715 {
716 linebuf[0] = '\0';
717 info.no_line_break = false;
718 info.line_scrolls = false;
719 info.force_redraw = false;
720
721 info.cur_align_start = info.buf;
722 align->left = info.buf;
723 align->center = NULL;
724 align->right = NULL;
725
726
727 if (line->type == LINE_ALTERNATOR)
728 func = skin_render_alternator;
729 else if (line->type == LINE)
730 func = skin_render_line;
731
732 needs_update = func(line, &info);
733
734 /* only update if the line needs to be, and there is something to write */
735 if (refresh_type && needs_update)
736 {
737 if (info.line_scrolls)
738 {
739 /* if the line is a scrolling one we don't want to update
740 too often, so that it has the time to scroll */
741 if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw)
742 write_line(display, align, info.line_number, true);
743 }
744 else
745 write_line(display, align, info.line_number, false);
746 }
747 info.line_number++;
748 info.offset++;
749 start_item++;
750 }
751}
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index ebe9ac50b1..8218358769 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -53,6 +53,7 @@
53#include "tdspeed.h" 53#include "tdspeed.h"
54#endif 54#endif
55#include "viewport.h" 55#include "viewport.h"
56#include "tagcache.h"
56 57
57#include "wps_internals.h" 58#include "wps_internals.h"
58#include "root_menu.h" 59#include "root_menu.h"
@@ -192,9 +193,39 @@ const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3,
192 return NULL; 193 return NULL;
193} 194}
194 195
196const char* get_filename_token(struct wps_token *token, char* filename,
197 char *buf, int buf_size)
198{
199 if (filename)
200 {
201 switch (token->type)
202 {
203 case SKIN_TOKEN_FILE_PATH:
204 return filename;
205 case SKIN_TOKEN_FILE_NAME:
206 if (get_dir(buf, buf_size, filename, 0)) {
207 /* Remove extension */
208 char* sep = strrchr(buf, '.');
209 if (NULL != sep) {
210 *sep = 0;
211 }
212 return buf;
213 }
214 return NULL;
215 case SKIN_TOKEN_FILE_NAME_WITH_EXTENSION:
216 return get_dir(buf, buf_size, filename, 0);
217 case SKIN_TOKEN_FILE_DIRECTORY:
218 return get_dir(buf, buf_size, filename, token->value.i);
219 default:
220 return NULL;
221 }
222 }
223 return NULL;
224}
225
195/* All tokens which only need the info to return a value go in here */ 226/* All tokens which only need the info to return a value go in here */
196const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, 227const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
197 char *buf, int buf_size, int limit, int *intval) 228 char *filename, char *buf, int buf_size, int limit, int *intval)
198{ 229{
199 struct wps_state *state = &wps_state; 230 struct wps_state *state = &wps_state;
200 if (id3) 231 if (id3)
@@ -260,8 +291,6 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
260 return NULL; 291 return NULL;
261 case SKIN_TOKEN_METADATA_COMMENT: 292 case SKIN_TOKEN_METADATA_COMMENT:
262 return id3->comment; 293 return id3->comment;
263 case SKIN_TOKEN_FILE_PATH:
264 return id3->path;
265 case SKIN_TOKEN_FILE_BITRATE: 294 case SKIN_TOKEN_FILE_BITRATE:
266 if(id3->bitrate) 295 if(id3->bitrate)
267 snprintf(buf, buf_size, "%d", id3->bitrate); 296 snprintf(buf, buf_size, "%d", id3->bitrate);
@@ -328,25 +357,11 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
328 id3->frequency / 1000, 357 id3->frequency / 1000,
329 (id3->frequency % 1000) / 100); 358 (id3->frequency % 1000) / 100);
330 return buf; 359 return buf;
331 case SKIN_TOKEN_FILE_NAME: 360 case SKIN_TOKEN_FILE_VBR:
332 if (get_dir(buf, buf_size, id3->path, 0)) { 361 return (id3->vbr) ? "(avg)" : NULL;
333 /* Remove extension */
334 char* sep = strrchr(buf, '.');
335 if (NULL != sep) {
336 *sep = 0;
337 }
338 return buf;
339 }
340 return NULL;
341 case SKIN_TOKEN_FILE_NAME_WITH_EXTENSION:
342 return get_dir(buf, buf_size, id3->path, 0);
343 case SKIN_TOKEN_FILE_SIZE: 362 case SKIN_TOKEN_FILE_SIZE:
344 snprintf(buf, buf_size, "%ld", id3->filesize / 1024); 363 snprintf(buf, buf_size, "%ld", id3->filesize / 1024);
345 return buf; 364 return buf;
346 case SKIN_TOKEN_FILE_VBR:
347 return (id3->vbr) ? "(avg)" : NULL;
348 case SKIN_TOKEN_FILE_DIRECTORY:
349 return get_dir(buf, buf_size, id3->path, token->value.i);
350 365
351#ifdef HAVE_TAGCACHE 366#ifdef HAVE_TAGCACHE
352 case SKIN_TOKEN_DATABASE_PLAYCOUNT: 367 case SKIN_TOKEN_DATABASE_PLAYCOUNT:
@@ -367,7 +382,7 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
367#endif 382#endif
368 383
369 default: 384 default:
370 return NULL; 385 return get_filename_token(token, id3->path, buf, buf_size);
371 } 386 }
372 } 387 }
373 else /* id3 == NULL, handle the error based on the expected return type */ 388 else /* id3 == NULL, handle the error based on the expected return type */
@@ -388,7 +403,7 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
388 *intval = 0; 403 *intval = 0;
389 return "0"; 404 return "0";
390 default: 405 default:
391 return NULL; 406 return get_filename_token(token, filename, buf, buf_size);
392 } 407 }
393 } 408 }
394 return buf; 409 return buf;
@@ -498,6 +513,41 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
498} 513}
499#endif 514#endif
500 515
516static struct mp3entry* get_mp3entry_from_offset(struct gui_wps *gwps,
517 int offset, char **filename)
518{
519 struct mp3entry* pid3 = NULL;
520 struct cuesheet *cue = gwps->state->id3 ? gwps->state->id3->cuesheet:NULL;
521 const char *fname = NULL;
522 if (cue && cue->curr_track_idx + offset < cue->track_count)
523 pid3 = gwps->state->id3;
524 else if (offset == 0)
525 pid3 = gwps->state->id3;
526 else if (offset == 1)
527 pid3 = gwps->state->nid3;
528 else
529 {
530 static struct mp3entry tempid3;
531 static char filename_buf[MAX_PATH + 1];
532 fname = playlist_peek(offset, filename_buf, sizeof(filename_buf));
533 *filename = (char*)fname;
534#if CONFIG_CODEC == SWCODEC
535#ifdef HAVE_TC_RAMCACHE
536 if (tagcache_fill_tags(&tempid3, fname))
537 {
538 pid3 = &tempid3;
539 }
540 else
541#endif
542 {
543 if (!audio_peek_track(&pid3, offset))
544 pid3 = NULL;
545 }
546#endif
547 }
548 return pid3;
549}
550
501/* Return the tags value as text. buf should be used as temp storage if needed. 551/* Return the tags value as text. buf should be used as temp storage if needed.
502 552
503 intval is used with conditionals/enums: when this function is called, 553 intval is used with conditionals/enums: when this function is called,
@@ -508,7 +558,7 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
508 When not treating a conditional/enum, intval should be NULL. 558 When not treating a conditional/enum, intval should be NULL.
509*/ 559*/
510const char *get_token_value(struct gui_wps *gwps, 560const char *get_token_value(struct gui_wps *gwps,
511 struct wps_token *token, 561 struct wps_token *token, int offset,
512 char *buf, int buf_size, 562 char *buf, int buf_size,
513 int *intval) 563 int *intval)
514{ 564{
@@ -520,15 +570,14 @@ const char *get_token_value(struct gui_wps *gwps,
520 struct mp3entry *id3; /* Think very carefully about using this. 570 struct mp3entry *id3; /* Think very carefully about using this.
521 maybe get_id3_token() is the better place? */ 571 maybe get_id3_token() is the better place? */
522 const char *out_text = NULL; 572 const char *out_text = NULL;
573 char *filename = NULL;
523 574
524 if (!data || !state) 575 if (!data || !state)
525 return NULL; 576 return NULL;
526 577
527 578 id3 = get_mp3entry_from_offset(gwps, token->next? 1: offset, &filename);
528 if (token->next) 579 if (id3)
529 id3 = state->nid3; 580 filename = id3->path;
530 else
531 id3 = state->id3;
532 581
533#if CONFIG_RTC 582#if CONFIG_RTC
534 struct tm* tm = NULL; 583 struct tm* tm = NULL;
@@ -552,17 +601,18 @@ const char *get_token_value(struct gui_wps *gwps,
552 *intval = -1; 601 *intval = -1;
553 } 602 }
554 603
555 if (state->id3 && state->id3->cuesheet) 604 if (id3 && id3 == state->id3 && id3->cuesheet )
556 { 605 {
557 out_text = get_cuesheetid3_token(token, state->id3, token->next?1:0, buf, buf_size); 606 out_text = get_cuesheetid3_token(token, id3,
607 token->next?1:offset, buf, buf_size);
558 if (out_text) 608 if (out_text)
559 return out_text; 609 return out_text;
560 } 610 }
561 out_text = get_id3_token(token, id3, buf, buf_size, limit, intval); 611 out_text = get_id3_token(token, id3, filename, buf, buf_size, limit, intval);
562 if (out_text) 612 if (out_text)
563 return out_text; 613 return out_text;
564#if CONFIG_TUNER 614#if CONFIG_TUNER
565 out_text = get_radio_token(token, 0, buf, buf_size, limit, intval); 615 out_text = get_radio_token(token, offset, buf, buf_size, limit, intval);
566 if (out_text) 616 if (out_text)
567 return out_text; 617 return out_text;
568#endif 618#endif
@@ -596,7 +646,7 @@ const char *get_token_value(struct gui_wps *gwps,
596 return playlist_name(NULL, buf, buf_size); 646 return playlist_name(NULL, buf, buf_size);
597 647
598 case SKIN_TOKEN_PLAYLIST_POSITION: 648 case SKIN_TOKEN_PLAYLIST_POSITION:
599 snprintf(buf, buf_size, "%d", playlist_get_display_index()); 649 snprintf(buf, buf_size, "%d", playlist_get_display_index()+offset);
600 return buf; 650 return buf;
601 651
602 case SKIN_TOKEN_PLAYLIST_SHUFFLE: 652 case SKIN_TOKEN_PLAYLIST_SHUFFLE:
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index e1516bd8fd..ccae11b91a 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -194,18 +194,11 @@ struct touchregion {
194}; 194};
195#endif 195#endif
196 196
197enum info_line_type {
198 TRACK_HAS_INFO = 0,
199 TRACK_HAS_NO_INFO
200};
201struct playlistviewer { 197struct playlistviewer {
202 struct viewport *vp; 198 struct viewport *vp;
203 bool show_icons; 199 bool show_icons;
204 int start_offset; 200 int start_offset;
205#ifdef HAVE_TC_RAMCACHE 201 struct skin_element *line;
206 struct mp3entry tempid3;
207#endif
208 struct skin_element *lines[2];
209}; 202};
210 203
211 204
@@ -334,7 +327,7 @@ char *get_image_filename(const char *start, const char* bmpdir,
334/***** wps_tokens.c ******/ 327/***** wps_tokens.c ******/
335 328
336const char *get_token_value(struct gui_wps *gwps, 329const char *get_token_value(struct gui_wps *gwps,
337 struct wps_token *token, 330 struct wps_token *token, int offset,
338 char *buf, int buf_size, 331 char *buf, int buf_size,
339 int *intval); 332 int *intval);
340 333
@@ -342,7 +335,7 @@ const char *get_token_value(struct gui_wps *gwps,
342const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3, 335const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3,
343 int offset_tracks, char *buf, int buf_size); 336 int offset_tracks, char *buf, int buf_size);
344const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, 337const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
345 char *buf, int buf_size, int limit, int *intval); 338 char *filename, char *buf, int buf_size, int limit, int *intval);
346#if CONFIG_TUNER 339#if CONFIG_TUNER
347const char *get_radio_token(struct wps_token *token, int preset_offset, 340const char *get_radio_token(struct wps_token *token, int preset_offset,
348 char *buf, int buf_size, int limit, int *intval); 341 char *buf, int buf_size, int limit, int *intval);