summaryrefslogtreecommitdiff
path: root/apps/gui
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui')
-rw-r--r--apps/gui/skin_engine/skin_display.c95
-rw-r--r--apps/gui/skin_engine/skin_parser.c118
-rw-r--r--apps/gui/skin_engine/skin_tokens.c2
-rw-r--r--apps/gui/skin_engine/skin_tokens.h2
-rw-r--r--apps/gui/skin_engine/wps_internals.h20
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}
168bool audio_peek_track(struct mp3entry* id3, int offset);
169static 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 */
168static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) 258static 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
161static int parse_viewport_display(const char *wps_bufptr, 161static 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);
163static int parse_playlistview(const char *wps_bufptr,
164 struct wps_token *token, struct wps_data *wps_data);
163static int parse_viewport(const char *wps_bufptr, 165static 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);
165static int parse_statusbar_enable(const char *wps_bufptr, 167static 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
723int 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
809static 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
717static int parse_viewport(const char *wps_bufptr, 835static 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 */
84static char* get_dir(char* buf, int buf_size, const char* path, int level) 84char* 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
241char* 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
231enum info_line_type {
232 TRACK_HAS_INFO = 0,
233 TRACK_HAS_NO_INFO
234};
235struct 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
230struct skin_albumart { 250struct skin_albumart {