summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine/skin_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/skin_engine/skin_display.c')
-rw-r--r--apps/gui/skin_engine/skin_display.c196
1 files changed, 63 insertions, 133 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index 409984494c..4aeafb595d 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -391,41 +391,6 @@ static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
391 391
392#endif /* HAVE_LCD_CHARCELL */ 392#endif /* HAVE_LCD_CHARCELL */
393 393
394/* Returns the index of the subline in the subline array
395 line - 0-based line number
396 subline - 0-based subline number within the line
397 */
398static int subline_index(struct wps_data *data, int line, int subline)
399{
400 return data->lines[line].first_subline_idx + subline;
401}
402
403/* Returns the index of the first subline's token in the token array
404 line - 0-based line number
405 subline - 0-based subline number within the line
406 */
407static int first_token_index(struct wps_data *data, int line, int subline)
408{
409 int first_subline_idx = data->lines[line].first_subline_idx;
410 return data->sublines[first_subline_idx + subline].first_token_idx;
411}
412
413int skin_last_token_index(struct wps_data *data, int line, int subline)
414{
415 int first_subline_idx = data->lines[line].first_subline_idx;
416 int idx = first_subline_idx + subline;
417 if (idx < data->num_sublines - 1)
418 {
419 /* This subline ends where the next begins */
420 return data->sublines[idx+1].first_token_idx - 1;
421 }
422 else
423 {
424 /* The last subline goes to the end */
425 return data->num_tokens - 1;
426 }
427}
428
429/* Return the index to the end token for the conditional token at index. 394/* Return the index to the end token for the conditional token at index.
430 The conditional token can be either a start token or a separator 395 The conditional token can be either a start token or a separator
431 (i.e. option) token. 396 (i.e. option) token.
@@ -541,7 +506,7 @@ struct skin_viewport* find_viewport(char label, struct wps_data *data)
541 The return value indicates whether the line needs to be updated. 506 The return value indicates whether the line needs to be updated.
542*/ 507*/
543static bool get_line(struct gui_wps *gwps, 508static bool get_line(struct gui_wps *gwps,
544 int line, int subline, 509 struct wps_subline *subline,
545 struct align_pos *align, 510 struct align_pos *align,
546 char *linebuf, 511 char *linebuf,
547 int linebuf_size) 512 int linebuf_size)
@@ -551,8 +516,8 @@ static bool get_line(struct gui_wps *gwps,
551 char temp_buf[128]; 516 char temp_buf[128];
552 char *buf = linebuf; /* will always point to the writing position */ 517 char *buf = linebuf; /* will always point to the writing position */
553 char *linebuf_end = linebuf + linebuf_size - 1; 518 char *linebuf_end = linebuf + linebuf_size - 1;
554 int i, last_token_idx;
555 bool update = false; 519 bool update = false;
520 int i;
556 521
557 /* alignment-related variables */ 522 /* alignment-related variables */
558 int cur_align; 523 int cur_align;
@@ -562,11 +527,9 @@ static bool get_line(struct gui_wps *gwps,
562 align->left = NULL; 527 align->left = NULL;
563 align->center = NULL; 528 align->center = NULL;
564 align->right = NULL; 529 align->right = NULL;
565
566 /* Process all tokens of the desired subline */ 530 /* Process all tokens of the desired subline */
567 last_token_idx = skin_last_token_index(data, line, subline); 531 for (i = subline->first_token_idx;
568 for (i = first_token_index(data, line, subline); 532 i <= subline->last_token_idx; i++)
569 i <= last_token_idx; i++)
570 { 533 {
571 switch(data->tokens[i].type) 534 switch(data->tokens[i].type)
572 { 535 {
@@ -685,18 +648,14 @@ static bool get_line(struct gui_wps *gwps,
685 648
686 return update; 649 return update;
687} 650}
688 651static void get_subline_timeout(struct gui_wps *gwps, struct wps_subline *subline)
689static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
690{ 652{
691 struct wps_data *data = gwps->data; 653 struct wps_data *data = gwps->data;
692 int i; 654 int i;
693 int subline_idx = subline_index(data, line, subline); 655 subline->time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
694 int last_token_idx = skin_last_token_index(data, line, subline);
695 656
696 data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; 657 for (i = subline->first_token_idx;
697 658 i <= subline->last_token_idx; i++)
698 for (i = first_token_index(data, line, subline);
699 i <= last_token_idx; i++)
700 { 659 {
701 switch(data->tokens[i].type) 660 switch(data->tokens[i].type)
702 { 661 {
@@ -712,7 +671,7 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
712 break; 671 break;
713 672
714 case WPS_TOKEN_SUBLINE_TIMEOUT: 673 case WPS_TOKEN_SUBLINE_TIMEOUT:
715 data->sublines[subline_idx].time_mult = data->tokens[i].value.i; 674 subline->time_mult = data->tokens[i].value.i;
716 break; 675 break;
717 676
718 default: 677 default:
@@ -723,77 +682,37 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
723 682
724/* Calculates which subline should be displayed for the specified line 683/* Calculates which subline should be displayed for the specified line
725 Returns true iff the subline must be refreshed */ 684 Returns true iff the subline must be refreshed */
726static bool update_curr_subline(struct gui_wps *gwps, int line) 685static bool update_curr_subline(struct gui_wps *gwps, struct wps_line *line)
727{ 686{
728 struct wps_data *data = gwps->data; 687 /* shortcut this whole thing if we need to reset the line completly */
729 688 if (line->curr_subline == NULL)
730 int search, search_start, num_sublines; 689 {
731 bool reset_subline; 690 int next_refresh = current_tick;
732 bool new_subline_refresh; 691 line->curr_subline = &line->sublines;
733 bool only_one_subline; 692 if (!line->curr_subline->next)
734 693 next_refresh += 100*HZ;
735 num_sublines = data->lines[line].num_sublines; 694 line->subline_expire_time = next_refresh;
736 reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET); 695 return true;
737 new_subline_refresh = false; 696 }
738 only_one_subline = false;
739
740 /* if time to advance to next sub-line */ 697 /* if time to advance to next sub-line */
741 if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) || 698 if (TIME_AFTER(current_tick, line->subline_expire_time - 1))
742 reset_subline)
743 { 699 {
744 /* search all sublines until the next subline with time > 0 700 /* if there is only one subline, there is no need to search for a new one */
745 is found or we get back to the subline we started with */ 701 if (&line->sublines == line->curr_subline &&
746 if (reset_subline) 702 line->curr_subline->next == NULL)
747 search_start = 0;
748 else
749 search_start = data->lines[line].curr_subline;
750
751 for (search = 0; search < num_sublines; search++)
752 { 703 {
753 data->lines[line].curr_subline++; 704 line->subline_expire_time += 100 * HZ;
754 705 return true;
755 /* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */
756 if (data->lines[line].curr_subline == num_sublines)
757 {
758 if (data->lines[line].curr_subline == 1)
759 only_one_subline = true;
760 data->lines[line].curr_subline = 0;
761 }
762
763 /* if back where we started after search or
764 only one subline is defined on the line */
765 if (((search > 0) &&
766 (data->lines[line].curr_subline == search_start)) ||
767 only_one_subline)
768 {
769 /* no other subline with a time > 0 exists */
770 data->lines[line].subline_expire_time = (reset_subline ?
771 current_tick :
772 data->lines[line].subline_expire_time) + 100 * HZ;
773 break;
774 }
775 else
776 {
777 /* get initial time multiplier for this subline */
778 get_subline_timeout(gwps, line, data->lines[line].curr_subline);
779
780 int subline_idx = subline_index(data, line,
781 data->lines[line].curr_subline);
782
783 /* only use this subline if subline time > 0 */
784 if (data->sublines[subline_idx].time_mult > 0)
785 {
786 new_subline_refresh = true;
787 data->lines[line].subline_expire_time = (reset_subline ?
788 current_tick : data->lines[line].subline_expire_time) +
789 TIMEOUT_UNIT*data->sublines[subline_idx].time_mult;
790 break;
791 }
792 }
793 } 706 }
707 if (line->curr_subline->next)
708 line->curr_subline = line->curr_subline->next;
709 else
710 line->curr_subline = &line->sublines;
711 get_subline_timeout(gwps, line->curr_subline);
712 line->subline_expire_time += TIMEOUT_UNIT*line->curr_subline->time_mult;
713 return true;
794 } 714 }
795 715 return false;
796 return new_subline_refresh;
797} 716}
798 717
799/* Display a line appropriately according to its alignment format. 718/* Display a line appropriately according to its alignment format.
@@ -971,8 +890,7 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
971 890
972 if (!id3) 891 if (!id3)
973 return false; 892 return false;
974 893
975 int line, i, subline_idx;
976 unsigned flags; 894 unsigned flags;
977 char linebuf[MAX_PATH]; 895 char linebuf[MAX_PATH];
978 896
@@ -980,6 +898,9 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
980 align.left = NULL; 898 align.left = NULL;
981 align.center = NULL; 899 align.center = NULL;
982 align.right = NULL; 900 align.right = NULL;
901
902
903 struct skin_token_list *viewport_list;
983 904
984 bool update_line, new_subline_refresh; 905 bool update_line, new_subline_refresh;
985 906
@@ -999,12 +920,20 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
999 /* reset to first subline if refresh all flag is set */ 920 /* reset to first subline if refresh all flag is set */
1000 if (refresh_mode == WPS_REFRESH_ALL) 921 if (refresh_mode == WPS_REFRESH_ALL)
1001 { 922 {
923 struct wps_line *line;
924
1002 display->set_viewport(&find_viewport(VP_DEFAULT_LABEL, data)->vp); 925 display->set_viewport(&find_viewport(VP_DEFAULT_LABEL, data)->vp);
1003 display->clear_viewport(); 926 display->clear_viewport();
1004 927
1005 for (i = 0; i <= data->num_lines; i++) 928 for (viewport_list = data->viewports;
929 viewport_list; viewport_list = viewport_list->next)
1006 { 930 {
1007 data->lines[i].curr_subline = SUBLINE_RESET; 931 struct skin_viewport *skin_viewport =
932 (struct skin_viewport *)viewport_list->token->value.data;
933 for(line = skin_viewport->lines; line; line = line->next)
934 {
935 line->curr_subline = NULL;
936 }
1008 } 937 }
1009 } 938 }
1010 939
@@ -1017,7 +946,6 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
1017#endif 946#endif
1018 947
1019 /* disable any viewports which are conditionally displayed */ 948 /* disable any viewports which are conditionally displayed */
1020 struct skin_token_list *viewport_list;
1021 for (viewport_list = data->viewports; 949 for (viewport_list = data->viewports;
1022 viewport_list; viewport_list = viewport_list->next) 950 viewport_list; viewport_list = viewport_list->next)
1023 { 951 {
@@ -1069,25 +997,27 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
1069 { 997 {
1070 display->clear_viewport(); 998 display->clear_viewport();
1071 } 999 }
1000
1001 /* loop over the lines for this viewport */
1002 struct wps_line *line;
1003 int line_count = 0;
1072 1004
1073 for (line = skin_viewport->first_line; 1005 for (line = skin_viewport->lines; line; line = line->next, line_count++)
1074 line <= skin_viewport->last_line; line++)
1075 { 1006 {
1007 struct wps_subline *subline;
1076 memset(linebuf, 0, sizeof(linebuf)); 1008 memset(linebuf, 0, sizeof(linebuf));
1077 update_line = false; 1009 update_line = false;
1078 1010
1079 /* get current subline for the line */ 1011 /* get current subline for the line */
1080 new_subline_refresh = update_curr_subline(gwps, line); 1012 new_subline_refresh = update_curr_subline(gwps, line);
1081 1013 subline = line->curr_subline;
1082 subline_idx = subline_index(data, line, 1014 flags = line->curr_subline->line_type;
1083 data->lines[line].curr_subline);
1084 flags = data->sublines[subline_idx].line_type;
1085 1015
1086 if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode) 1016 if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode)
1087 || new_subline_refresh) 1017 || new_subline_refresh)
1088 { 1018 {
1089 /* get_line tells us if we need to update the line */ 1019 /* get_line tells us if we need to update the line */
1090 update_line = get_line(gwps, line, data->lines[line].curr_subline, 1020 update_line = get_line(gwps, subline,
1091 &align, linebuf, sizeof(linebuf)); 1021 &align, linebuf, sizeof(linebuf));
1092 } 1022 }
1093#ifdef HAVE_LCD_BITMAP 1023#ifdef HAVE_LCD_BITMAP
@@ -1098,19 +1028,19 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
1098 update_line = false; 1028 update_line = false;
1099 1029
1100 int h = font_get(skin_viewport->vp.font)->height; 1030 int h = font_get(skin_viewport->vp.font)->height;
1101 int peak_meter_y = (line - skin_viewport->first_line)* h; 1031 int peak_meter_y = line_count* h;
1102 1032
1103 /* The user might decide to have the peak meter in the last 1033 /* The user might decide to have the peak meter in the last
1104 line so that it is only displayed if no status bar is 1034 line so that it is only displayed if no status bar is
1105 visible. If so we neither want do draw nor enable the 1035 visible. If so we neither want do draw nor enable the
1106 peak meter. */ 1036 peak meter. */
1107 if (peak_meter_y + h <= display->getheight()) { 1037 if (peak_meter_y + h <= skin_viewport->vp.y+skin_viewport->vp.height) {
1108 /* found a line with a peak meter -> remember that we must 1038 /* found a line with a peak meter -> remember that we must
1109 enable it later */ 1039 enable it later */
1110 enable_pm = true; 1040 enable_pm = true;
1111 peak_meter_enabled = true; 1041 peak_meter_enabled = true;
1112 peak_meter_screen(gwps->display, 0, peak_meter_y, 1042 peak_meter_screen(gwps->display, 0, peak_meter_y,
1113 MIN(h, display->getheight() - peak_meter_y)); 1043 MIN(h, skin_viewport->vp.y+skin_viewport->vp.height - peak_meter_y));
1114 } 1044 }
1115 else 1045 else
1116 { 1046 {
@@ -1143,10 +1073,10 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
1143 /* if the line is a scrolling one we don't want to update 1073 /* if the line is a scrolling one we don't want to update
1144 too often, so that it has the time to scroll */ 1074 too often, so that it has the time to scroll */
1145 if ((vp_refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) 1075 if ((vp_refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh)
1146 write_line(display, &align, line - skin_viewport->first_line, true); 1076 write_line(display, &align, line_count, true);
1147 } 1077 }
1148 else 1078 else
1149 write_line(display, &align, line - skin_viewport->first_line, false); 1079 write_line(display, &align, line_count, false);
1150 } 1080 }
1151 } 1081 }
1152 1082