diff options
Diffstat (limited to 'apps/gui')
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 95 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 118 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.c | 2 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.h | 2 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 20 |
5 files changed, 236 insertions, 1 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index b8cc75e10a..e781d43372 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include "statusbar.h" | 35 | #include "statusbar.h" |
36 | #include "scrollbar.h" | 36 | #include "scrollbar.h" |
37 | #include "screen_access.h" | 37 | #include "screen_access.h" |
38 | #include "playlist.h" | ||
39 | #include "playback.h" | ||
38 | 40 | ||
39 | #ifdef HAVE_LCD_BITMAP | 41 | #ifdef HAVE_LCD_BITMAP |
40 | #include "peakmeter.h" | 42 | #include "peakmeter.h" |
@@ -163,6 +165,94 @@ static void draw_progressbar(struct gui_wps *gwps, | |||
163 | cue_draw_markers(display, state->id3->cuesheet, length, | 165 | cue_draw_markers(display, state->id3->cuesheet, length, |
164 | pb->x, pb->x + pb->width, y+1, pb->height-2); | 166 | pb->x, pb->x + pb->width, y+1, pb->height-2); |
165 | } | 167 | } |
168 | bool audio_peek_track(struct mp3entry* id3, int offset); | ||
169 | static void draw_playlist_viewer_list(struct gui_wps *gwps, | ||
170 | struct playlistviewer *viewer) | ||
171 | { | ||
172 | int lines = viewport_get_nb_lines(viewer->vp); | ||
173 | int line_height = font_get(viewer->vp->font)->height; | ||
174 | int cur_playlist_pos = playlist_get_display_index(); | ||
175 | int start_item = MAX(0, cur_playlist_pos + viewer->start_offset); | ||
176 | int i; | ||
177 | |||
178 | struct mp3entry *pid3, id3; | ||
179 | char buf[MAX_PATH*2], tempbuf[MAX_PATH]; | ||
180 | |||
181 | |||
182 | gwps->display->set_viewport(viewer->vp); | ||
183 | for(i=start_item; (i-start_item)<lines && i<playlist_amount(); i++) | ||
184 | { | ||
185 | if (i == cur_playlist_pos) | ||
186 | { | ||
187 | pid3 = audio_current_track(); | ||
188 | } | ||
189 | else if (i == cur_playlist_pos+1) | ||
190 | { | ||
191 | pid3 = audio_next_track(); | ||
192 | } | ||
193 | else if ((i>cur_playlist_pos) && audio_peek_track(&id3, i-cur_playlist_pos)) | ||
194 | { | ||
195 | pid3 = &id3; | ||
196 | } | ||
197 | else | ||
198 | pid3 = NULL; | ||
199 | |||
200 | int line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO; | ||
201 | int token = 0, cur_string = 0; | ||
202 | char *filename = playlist_peek(i-cur_playlist_pos); | ||
203 | buf[0] = '\0'; | ||
204 | while (token < viewer->lines[line].count) | ||
205 | { | ||
206 | switch (viewer->lines[line].tokens[token]) | ||
207 | { | ||
208 | case WPS_TOKEN_STRING: | ||
209 | case WPS_TOKEN_CHARACTER: | ||
210 | strcat(buf, viewer->lines[line].strings[cur_string++]); | ||
211 | break; | ||
212 | case WPS_TOKEN_PLAYLIST_POSITION: | ||
213 | snprintf(tempbuf, sizeof(tempbuf), "%d", i); | ||
214 | strcat(buf, tempbuf); | ||
215 | break; | ||
216 | case WPS_TOKEN_FILE_NAME: | ||
217 | get_dir(tempbuf, sizeof(tempbuf), filename, 0); | ||
218 | strcat(buf, tempbuf); | ||
219 | break; | ||
220 | case WPS_TOKEN_FILE_PATH: | ||
221 | strcat(buf, filename); | ||
222 | break; | ||
223 | case WPS_TOKEN_METADATA_ARTIST: | ||
224 | if (pid3) | ||
225 | strcat(buf, pid3->artist ? pid3->artist : ""); | ||
226 | break; | ||
227 | case WPS_TOKEN_METADATA_TRACK_TITLE: | ||
228 | if (pid3) | ||
229 | strcat(buf, pid3->title ? pid3->title : ""); | ||
230 | break; | ||
231 | case WPS_TOKEN_TRACK_LENGTH: | ||
232 | if (pid3) | ||
233 | { | ||
234 | format_time(tempbuf, sizeof(tempbuf), pid3->length); | ||
235 | strcat(buf, tempbuf); | ||
236 | } | ||
237 | break; | ||
238 | |||
239 | default: | ||
240 | break; | ||
241 | } | ||
242 | token++; | ||
243 | } | ||
244 | |||
245 | if (viewer->lines[line].scroll) | ||
246 | { | ||
247 | gwps->display->puts_scroll(0, (i-start_item), buf ); | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | gwps->display->putsxy(0, (i-start_item)*line_height, buf ); | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | |||
166 | 256 | ||
167 | /* clears the area where the image was shown */ | 257 | /* clears the area where the image was shown */ |
168 | static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) | 258 | static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) |
@@ -595,6 +685,11 @@ static bool get_line(struct gui_wps *gwps, | |||
595 | } | 685 | } |
596 | } | 686 | } |
597 | break; | 687 | break; |
688 | #ifdef HAVE_LCD_BITMAP | ||
689 | case WPS_VIEWPORT_CUSTOMLIST: | ||
690 | draw_playlist_viewer_list(gwps, data->tokens[i].value.data); | ||
691 | break; | ||
692 | #endif | ||
598 | default: | 693 | default: |
599 | { | 694 | { |
600 | /* get the value of the tag and copy it to the buffer */ | 695 | /* get the value of the tag and copy it to the buffer */ |
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index c7bca24d1e..7efd169092 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c | |||
@@ -160,6 +160,8 @@ int parse_languagedirection(const char *wps_bufptr, | |||
160 | #ifdef HAVE_LCD_BITMAP | 160 | #ifdef HAVE_LCD_BITMAP |
161 | static int parse_viewport_display(const char *wps_bufptr, | 161 | static int parse_viewport_display(const char *wps_bufptr, |
162 | struct wps_token *token, struct wps_data *wps_data); | 162 | struct wps_token *token, struct wps_data *wps_data); |
163 | static int parse_playlistview(const char *wps_bufptr, | ||
164 | struct wps_token *token, struct wps_data *wps_data); | ||
163 | static int parse_viewport(const char *wps_bufptr, | 165 | static int parse_viewport(const char *wps_bufptr, |
164 | struct wps_token *token, struct wps_data *wps_data); | 166 | struct wps_token *token, struct wps_data *wps_data); |
165 | static int parse_statusbar_enable(const char *wps_bufptr, | 167 | static int parse_statusbar_enable(const char *wps_bufptr, |
@@ -373,6 +375,9 @@ static const struct wps_tag all_tags[] = { | |||
373 | 375 | ||
374 | { WPS_VIEWPORT_ENABLE, "Vd", WPS_REFRESH_DYNAMIC, | 376 | { WPS_VIEWPORT_ENABLE, "Vd", WPS_REFRESH_DYNAMIC, |
375 | parse_viewport_display }, | 377 | parse_viewport_display }, |
378 | #ifdef HAVE_LCD_BITMAP | ||
379 | { WPS_VIEWPORT_CUSTOMLIST, "Vp", WPS_REFRESH_STATIC, parse_playlistview }, | ||
380 | #endif | ||
376 | { WPS_NO_TOKEN, "V", 0, parse_viewport }, | 381 | { WPS_NO_TOKEN, "V", 0, parse_viewport }, |
377 | 382 | ||
378 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | 383 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) |
@@ -714,6 +719,119 @@ static int parse_viewport_display(const char *wps_bufptr, | |||
714 | return 1; | 719 | return 1; |
715 | } | 720 | } |
716 | 721 | ||
722 | #ifdef HAVE_LCD_BITMAP | ||
723 | int parse_playlistview_text(struct playlistviewer *viewer, | ||
724 | enum info_line_type line, char* text) | ||
725 | { | ||
726 | int cur_string = 0; | ||
727 | const struct wps_tag *tag; | ||
728 | int taglen = 0; | ||
729 | const char *start = text; | ||
730 | if (*text != '|') | ||
731 | return -1; | ||
732 | text++; | ||
733 | viewer->lines[line].count = 0; | ||
734 | viewer->lines[line].scroll = false; | ||
735 | while (*text != '|') | ||
736 | { | ||
737 | if (*text == '%') /* it is a token of some type */ | ||
738 | { | ||
739 | text++; | ||
740 | taglen = 0; | ||
741 | switch(*text) | ||
742 | { | ||
743 | case '%': | ||
744 | case '<': | ||
745 | case '|': | ||
746 | case '>': | ||
747 | case ';': | ||
748 | case '#': | ||
749 | /* escaped characters */ | ||
750 | viewer->lines[line].tokens[viewer->lines[line].count++] = WPS_TOKEN_CHARACTER; | ||
751 | viewer->lines[line].strings[cur_string][0] = *text; | ||
752 | viewer->lines[line].strings[cur_string++][0] = '\0'; | ||
753 | break; | ||
754 | default: | ||
755 | for (tag = all_tags; | ||
756 | strncmp(text, tag->name, strlen(tag->name)) != 0; | ||
757 | tag++) ; | ||
758 | /* %s isnt stored as a tag so manually check for it */ | ||
759 | if (tag->type == WPS_NO_TOKEN) | ||
760 | { | ||
761 | if (!strncmp(tag->name, "s", 1)) | ||
762 | { | ||
763 | viewer->lines[line].scroll = true; | ||
764 | taglen = 1; | ||
765 | } | ||
766 | } | ||
767 | else if (tag->type == WPS_TOKEN_UNKNOWN) | ||
768 | { | ||
769 | int i = 0; | ||
770 | /* just copy the string */ | ||
771 | viewer->lines[line].tokens[viewer->lines[line].count++] = WPS_TOKEN_STRING; | ||
772 | while (i<(MAX_PLAYLISTLINE_STRLEN-1) && text[i] != '|' && text[i] != '%') | ||
773 | { | ||
774 | viewer->lines[line].strings[cur_string][i] = text[i]; | ||
775 | i++; | ||
776 | } | ||
777 | viewer->lines[line].strings[cur_string][i] = '\0'; | ||
778 | cur_string++; | ||
779 | taglen = i; | ||
780 | } | ||
781 | else | ||
782 | { | ||
783 | taglen = strlen(tag->name); | ||
784 | viewer->lines[line].tokens[viewer->lines[line].count++] = tag->type; | ||
785 | } | ||
786 | text += taglen; | ||
787 | } | ||
788 | } | ||
789 | else | ||
790 | { | ||
791 | /* regular string */ | ||
792 | int i = 0; | ||
793 | /* just copy the string */ | ||
794 | viewer->lines[line].tokens[viewer->lines[line].count++] = WPS_TOKEN_STRING; | ||
795 | while (i<(MAX_PLAYLISTLINE_STRLEN-1) && text[i] != '|' && text[i] != '%') | ||
796 | { | ||
797 | viewer->lines[line].strings[cur_string][i] = text[i]; | ||
798 | i++; | ||
799 | } | ||
800 | viewer->lines[line].strings[cur_string][i] = '\0'; | ||
801 | cur_string++; | ||
802 | text += i; | ||
803 | } | ||
804 | } | ||
805 | return text - start; | ||
806 | } | ||
807 | |||
808 | |||
809 | static int parse_playlistview(const char *wps_bufptr, | ||
810 | struct wps_token *token, struct wps_data *wps_data) | ||
811 | { | ||
812 | (void)wps_data; | ||
813 | /* %Vp|<use icons>|<start offset>|info line text|no info text| */ | ||
814 | struct playlistviewer *viewer = skin_buffer_alloc(sizeof(struct playlistviewer)); | ||
815 | char *ptr = strchr(wps_bufptr, '|'); | ||
816 | int length; | ||
817 | if (!viewer || !ptr) | ||
818 | return WPS_ERROR_INVALID_PARAM; | ||
819 | viewer->vp = &curr_vp->vp; | ||
820 | viewer->show_icons = true; | ||
821 | viewer->start_offset = atoi(ptr+1); | ||
822 | token->value.data = (void*)viewer; | ||
823 | ptr = strchr(ptr+1, '|'); | ||
824 | length = parse_playlistview_text(viewer, TRACK_HAS_INFO, ptr); | ||
825 | if (length < 0) | ||
826 | return WPS_ERROR_INVALID_PARAM; | ||
827 | length = parse_playlistview_text(viewer, TRACK_HAS_NO_INFO, ptr+length); | ||
828 | if (length < 0) | ||
829 | return WPS_ERROR_INVALID_PARAM; | ||
830 | |||
831 | return skip_end_of_line(wps_bufptr); | ||
832 | } | ||
833 | #endif | ||
834 | |||
717 | static int parse_viewport(const char *wps_bufptr, | 835 | static int parse_viewport(const char *wps_bufptr, |
718 | struct wps_token *token, | 836 | struct wps_token *token, |
719 | struct wps_data *wps_data) | 837 | struct wps_data *wps_data) |
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 794d7f4456..9b54361321 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c | |||
@@ -81,7 +81,7 @@ static char* get_codectype(const struct mp3entry* id3) | |||
81 | * | 81 | * |
82 | * Returns buf if the desired level was found, NULL otherwise. | 82 | * Returns buf if the desired level was found, NULL otherwise. |
83 | */ | 83 | */ |
84 | static char* get_dir(char* buf, int buf_size, const char* path, int level) | 84 | char* get_dir(char* buf, int buf_size, const char* path, int level) |
85 | { | 85 | { |
86 | const char* sep; | 86 | const char* sep; |
87 | const char* last_sep; | 87 | const char* last_sep; |
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h index 25acfdacef..5778f95808 100644 --- a/apps/gui/skin_engine/skin_tokens.h +++ b/apps/gui/skin_engine/skin_tokens.h | |||
@@ -54,6 +54,7 @@ enum wps_token_type { | |||
54 | 54 | ||
55 | /* Viewport display */ | 55 | /* Viewport display */ |
56 | WPS_VIEWPORT_ENABLE, | 56 | WPS_VIEWPORT_ENABLE, |
57 | WPS_VIEWPORT_CUSTOMLIST, | ||
57 | 58 | ||
58 | /* Battery */ | 59 | /* Battery */ |
59 | TOKEN_MARKER_BATTERY, | 60 | TOKEN_MARKER_BATTERY, |
@@ -237,6 +238,7 @@ struct skin_token_list { | |||
237 | struct skin_token_list *next; | 238 | struct skin_token_list *next; |
238 | }; | 239 | }; |
239 | 240 | ||
241 | char* get_dir(char* buf, int buf_size, const char* path, int level); | ||
240 | 242 | ||
241 | #endif | 243 | #endif |
242 | 244 | ||
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index bd0c1c01c7..362f3947e7 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h | |||
@@ -225,6 +225,26 @@ struct touchregion { | |||
225 | }; | 225 | }; |
226 | #endif | 226 | #endif |
227 | 227 | ||
228 | #define MAX_PLAYLISTLINE_TOKENS 16 | ||
229 | #define MAX_PLAYLISTLINE_STRINGS 8 | ||
230 | #define MAX_PLAYLISTLINE_STRLEN 8 | ||
231 | enum info_line_type { | ||
232 | TRACK_HAS_INFO = 0, | ||
233 | TRACK_HAS_NO_INFO | ||
234 | }; | ||
235 | struct playlistviewer { | ||
236 | struct viewport *vp; | ||
237 | bool show_icons; | ||
238 | int start_offset; | ||
239 | struct { | ||
240 | enum wps_token_type tokens[MAX_PLAYLISTLINE_TOKENS]; | ||
241 | char strings[MAX_PLAYLISTLINE_STRINGS][MAX_PLAYLISTLINE_STRLEN]; | ||
242 | int count; | ||
243 | bool scroll; | ||
244 | } lines[2]; | ||
245 | }; | ||
246 | |||
247 | |||
228 | 248 | ||
229 | #ifdef HAVE_ALBUMART | 249 | #ifdef HAVE_ALBUMART |
230 | struct skin_albumart { | 250 | struct skin_albumart { |