diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2010-08-14 15:17:59 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2010-08-14 15:17:59 +0000 |
commit | dc3778a685835ff6db12db9e784af01de2165656 (patch) | |
tree | fa81e777554fb3970f0a29888d02ccdde283b706 | |
parent | ff8d43ddad6e26f14218c212503c551f5a7d6b26 (diff) | |
download | rockbox-dc3778a685835ff6db12db9e784af01de2165656.tar.gz rockbox-dc3778a685835ff6db12db9e784af01de2165656.zip |
Rework the skin playlist viewer so it uses the same drawing code as everything else. This should mean that all text tags now work as expected. The 2nd code param is no longer needed so drop it (you can use conditionals and sublines and stuff in the one code param.
example: %Vp(1, %?it<%in -%it|%fn>) <- show the next tracks strating from the first next track and show info if it is avilable or the filename.
Basic cuesheet support here, and will load upcoming track tags from the database if you have load to ram enabled.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27814 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 190 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_display.h | 3 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 3 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_render.c | 112 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.c | 114 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 13 | ||||
-rw-r--r-- | lib/skin_parser/tag_table.c | 2 |
7 files changed, 199 insertions, 238 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 | ||
208 | void 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 */ |
394 | void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) | 209 | void 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 | */ |
621 | int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional, int num_options) | 436 | int 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 | */ |
47 | int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional, int num_options); | 47 | int 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 | ||
64 | typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info); | 70 | typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info); |
65 | bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info); | 71 | bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info); |
66 | 72 | ||
73 | static 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 | ||
68 | static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | 79 | static 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 | |||
668 | static 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 | ||
196 | const 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 */ |
196 | const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | 227 | const 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 | ||
516 | static 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 | */ |
510 | const char *get_token_value(struct gui_wps *gwps, | 560 | const 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 | ||
197 | enum info_line_type { | ||
198 | TRACK_HAS_INFO = 0, | ||
199 | TRACK_HAS_NO_INFO | ||
200 | }; | ||
201 | struct playlistviewer { | 197 | struct 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 | ||
336 | const char *get_token_value(struct gui_wps *gwps, | 329 | const 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, | |||
342 | const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3, | 335 | const 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); |
344 | const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | 337 | const 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 |
347 | const char *get_radio_token(struct wps_token *token, int preset_offset, | 340 | const 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); |
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 4f201ec911..e7e30b1609 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c | |||
@@ -178,7 +178,7 @@ static const struct tag_info legal_tags[] = | |||
178 | { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S", SKIN_REFRESH_STATIC }, | 178 | { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S", SKIN_REFRESH_STATIC }, |
179 | { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S", SKIN_REFRESH_STATIC }, | 179 | { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S", SKIN_REFRESH_STATIC }, |
180 | 180 | ||
181 | { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "ICC", SKIN_REFRESH_DYNAMIC|NOBREAK }, | 181 | { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "IC", SKIN_REFRESH_DYNAMIC|NOBREAK }, |
182 | { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , "", SKIN_REFRESH_DYNAMIC }, | 182 | { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , "", SKIN_REFRESH_DYNAMIC }, |
183 | { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , "", SKIN_REFRESH_DYNAMIC }, | 183 | { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , "", SKIN_REFRESH_DYNAMIC }, |
184 | 184 | ||