summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine/skin_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/skin_engine/skin_render.c')
-rw-r--r--apps/gui/skin_engine/skin_render.c112
1 files changed, 107 insertions, 5 deletions
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}