diff options
Diffstat (limited to 'apps/gui/skin_engine/skin_display.c')
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 196 |
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 | */ | ||
398 | static 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 | */ | ||
407 | static 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 | |||
413 | int 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 | */ |
543 | static bool get_line(struct gui_wps *gwps, | 508 | static 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 | 651 | static void get_subline_timeout(struct gui_wps *gwps, struct wps_subline *subline) | |
689 | static 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 */ |
726 | static bool update_curr_subline(struct gui_wps *gwps, int line) | 685 | static 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 | ||