diff options
author | Kevin Ferrare <kevin@rockbox.org> | 2005-11-16 02:12:25 +0000 |
---|---|---|
committer | Kevin Ferrare <kevin@rockbox.org> | 2005-11-16 02:12:25 +0000 |
commit | 8517ed8939b7323be8371cd902544154ade984b9 (patch) | |
tree | 230698c2817e2d6b8dd7862295deeb2aa2b72b9f /apps/playlist_viewer.c | |
parent | 5d8c1529a735254d2cc17e47d294b8835ba575b0 (diff) | |
download | rockbox-8517ed8939b7323be8371cd902544154ade984b9.tar.gz rockbox-8517ed8939b7323be8371cd902544154ade984b9.zip |
Multi screen support for playlist viewer, some fixes in other gui files
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7901 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playlist_viewer.c')
-rw-r--r-- | apps/playlist_viewer.c | 929 |
1 files changed, 315 insertions, 614 deletions
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index 70c1cf8995..58f27409b1 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c | |||
@@ -17,7 +17,10 @@ | |||
17 | * KIND, either express or implied. | 17 | * KIND, either express or implied. |
18 | * | 18 | * |
19 | ****************************************************************************/ | 19 | ****************************************************************************/ |
20 | 20 | /* | |
21 | * Kevin Ferrare 2005/10/16 | ||
22 | * multi-screen support, rewrote a lot of code | ||
23 | */ | ||
21 | #include <string.h> | 24 | #include <string.h> |
22 | #include <sprintf.h> | 25 | #include <sprintf.h> |
23 | #include "playlist.h" | 26 | #include "playlist.h" |
@@ -35,76 +38,24 @@ | |||
35 | #include "misc.h" | 38 | #include "misc.h" |
36 | #include "action.h" | 39 | #include "action.h" |
37 | 40 | ||
38 | #ifdef HAVE_LCD_BITMAP | ||
39 | #include "widgets.h" | ||
40 | #endif | ||
41 | |||
42 | #include "lang.h" | 41 | #include "lang.h" |
43 | 42 | ||
44 | #include "playlist_viewer.h" | 43 | #include "playlist_viewer.h" |
45 | 44 | #include "icon.h" | |
46 | /* Defines for LCD display purposes. Taken from tree.c */ | 45 | #include "list.h" |
47 | #ifdef HAVE_LCD_BITMAP | 46 | #include "statusbar.h" |
48 | #define CURSOR_X (global_settings.scrollbar && \ | 47 | #include "splash.h" |
49 | viewer.num_tracks>viewer.num_display_lines?1:0) | ||
50 | #define CURSOR_Y 0 | ||
51 | #define CURSOR_WIDTH (global_settings.invert_cursor ? 0 : 4) | ||
52 | |||
53 | #define ICON_WIDTH ((viewer.char_width > 6) ? viewer.char_width : 6) | ||
54 | |||
55 | #define MARGIN_X ((global_settings.scrollbar && \ | ||
56 | viewer.num_tracks > viewer.num_display_lines ? \ | ||
57 | SCROLLBAR_WIDTH : 0) + CURSOR_WIDTH + \ | ||
58 | (global_settings.playlist_viewer_icons ? \ | ||
59 | ICON_WIDTH : 0)) | ||
60 | #define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0) | ||
61 | |||
62 | #define LINE_X 0 | ||
63 | #define LINE_Y (global_settings.statusbar ? 1 : 0) | ||
64 | |||
65 | #define SCROLLBAR_X 0 | ||
66 | #define SCROLLBAR_Y lcd_getymargin() | ||
67 | #define SCROLLBAR_WIDTH 6 | ||
68 | #else | ||
69 | #define MARGIN_X 0 | ||
70 | #define MARGIN_Y 0 | ||
71 | #define LINE_X 2 | ||
72 | #define LINE_Y 0 | ||
73 | #define CURSOR_X 0 | ||
74 | #define CURSOR_Y 0 | ||
75 | #endif | ||
76 | 48 | ||
77 | /* Maximum number of tracks we can have loaded at one time */ | 49 | /* Maximum number of tracks we can have loaded at one time */ |
78 | #define MAX_PLAYLIST_ENTRIES 200 | 50 | #define MAX_PLAYLIST_ENTRIES 40 |
51 | |||
52 | /* The number of items between the selected one and the end/start of | ||
53 | * the buffer under which the buffer must reload */ | ||
54 | #define MIN_BUFFER_MARGIN screens[0].nb_lines | ||
79 | 55 | ||
80 | /* Default playlist name for saving */ | 56 | /* Default playlist name for saving */ |
81 | #define DEFAULT_VIEWER_PLAYLIST_NAME "/viewer.m3u" | 57 | #define DEFAULT_VIEWER_PLAYLIST_NAME "/viewer.m3u" |
82 | 58 | ||
83 | /* Index of track on display line _pos */ | ||
84 | #define INDEX(_pos) (viewer.first_display_index - viewer.first_index + (_pos)) | ||
85 | |||
86 | /* Global playlist viewer settings */ | ||
87 | struct playlist_viewer_info { | ||
88 | struct playlist_info* playlist; /* playlist being viewed */ | ||
89 | char *name_buffer; /* Buffer used to store track names */ | ||
90 | int buffer_size; /* Size of name buffer */ | ||
91 | |||
92 | int num_display_lines; /* Number of lines on lcd */ | ||
93 | int line_height; /* Height (in pixels) of display line */ | ||
94 | int char_width; /* Width (in pixels) of a character */ | ||
95 | |||
96 | int num_tracks; /* Number of tracks in playlist */ | ||
97 | int current_playing_track; /* Index of current playing track */ | ||
98 | |||
99 | int num_loaded; /* Number of track entries loaded in viewer */ | ||
100 | int first_index; /* Index of first loaded track */ | ||
101 | int last_index; /* Index of last loaded track */ | ||
102 | int first_display_index; /* Index of first track on display */ | ||
103 | int last_display_index; /* Index of last track on display */ | ||
104 | int cursor_pos; /* Line number of cursor */ | ||
105 | |||
106 | int move_track; /* Playlist index of track to move or -1 */ | ||
107 | }; | ||
108 | 59 | ||
109 | /* Information about a specific track */ | 60 | /* Information about a specific track */ |
110 | struct playlist_entry { | 61 | struct playlist_entry { |
@@ -115,22 +66,60 @@ struct playlist_entry { | |||
115 | bool skipped; /* Is track marked as bad? */ | 66 | bool skipped; /* Is track marked as bad? */ |
116 | }; | 67 | }; |
117 | 68 | ||
118 | static struct playlist_viewer_info viewer; | 69 | enum direction |
119 | static struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES]; | 70 | { |
71 | FORWARD, | ||
72 | BACKWARD | ||
73 | }; | ||
74 | |||
75 | struct playlist_buffer | ||
76 | { | ||
77 | char *name_buffer; /* Buffer used to store track names */ | ||
78 | int buffer_size; /* Size of name buffer */ | ||
79 | |||
80 | int first_index; /* Real index of first track loaded inside | ||
81 | the buffer */ | ||
82 | |||
83 | enum direction direction; /* Direction of the buffer (if the buffer | ||
84 | was loaded BACKWARD, the last track in | ||
85 | the buffer has a real index < to the | ||
86 | real index of the the first track)*/ | ||
87 | |||
88 | struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES]; | ||
89 | int num_loaded; /* Number of track entries loaded in buffer */ | ||
90 | }; | ||
91 | |||
92 | /* Global playlist viewer settings */ | ||
93 | struct playlist_viewer { | ||
94 | struct playlist_info* playlist; /* playlist being viewed */ | ||
95 | int num_tracks; /* Number of tracks in playlist */ | ||
96 | int current_playing_track; /* Index of current playing track */ | ||
97 | int selected_track; /* The selected track, relative (first is 0)*/ | ||
98 | int move_track; /* Playlist index of track to move or -1 */ | ||
99 | struct playlist_buffer buffer; | ||
100 | }; | ||
101 | |||
102 | static struct playlist_viewer viewer; | ||
120 | 103 | ||
121 | /* Used when viewing playlists on disk */ | 104 | /* Used when viewing playlists on disk */ |
122 | static struct playlist_info temp_playlist; | 105 | static struct playlist_info temp_playlist; |
123 | 106 | ||
124 | static bool initialize(char* filename, bool reload); | 107 | void playlist_buffer_init(struct playlist_buffer * pb, char * names_buffer, |
125 | static void load_playlist_entries(int start_index); | 108 | int names_buffer_size); |
126 | static void load_playlist_entries_r(int end_index); | 109 | void playlist_buffer_load_entries(struct playlist_buffer * pb, int index, |
127 | static int load_entry(int index, int pos, char* p, int size); | 110 | enum direction direction); |
111 | int playlist_entry_load(struct playlist_entry *entry, int index, | ||
112 | char* name_buffer, int remaining_size); | ||
113 | |||
114 | struct playlist_entry * playlist_buffer_get_track(struct playlist_buffer * pb, | ||
115 | int index); | ||
116 | |||
117 | static bool playlist_viewer_init(struct playlist_viewer * viewer, | ||
118 | char* filename, bool reload); | ||
119 | |||
128 | static void format_name(char* dest, const char* src); | 120 | static void format_name(char* dest, const char* src); |
129 | static void format_line(const struct playlist_entry* track, char* str, int len); | 121 | static void format_line(const struct playlist_entry* track, char* str, int len); |
130 | static void display_playlist(void); | 122 | |
131 | static void update_display_line(int line, bool scroll); | ||
132 | static void scroll_display(int lines); | ||
133 | static void update_first_index(void); | ||
134 | static bool update_playlist(bool force); | 123 | static bool update_playlist(bool force); |
135 | static int onplay_menu(int index); | 124 | static int onplay_menu(int index); |
136 | static bool viewer_menu(void); | 125 | static bool viewer_menu(void); |
@@ -139,8 +128,148 @@ static bool show_indices(void); | |||
139 | static bool track_display(void); | 128 | static bool track_display(void); |
140 | static bool save_playlist(void); | 129 | static bool save_playlist(void); |
141 | 130 | ||
131 | void playlist_buffer_init(struct playlist_buffer * pb, char * names_buffer, | ||
132 | int names_buffer_size) | ||
133 | { | ||
134 | pb->name_buffer=names_buffer; | ||
135 | pb->buffer_size=names_buffer_size; | ||
136 | pb->first_index=0; | ||
137 | pb->num_loaded=0; | ||
138 | } | ||
139 | /* | ||
140 | * Loads the entries following 'index' in the playlist buffer | ||
141 | */ | ||
142 | void playlist_buffer_load_entries(struct playlist_buffer * pb, int index, | ||
143 | enum direction direction) | ||
144 | { | ||
145 | int num_entries = viewer.num_tracks; | ||
146 | char* p = pb->name_buffer; | ||
147 | int remaining = pb->buffer_size; | ||
148 | int i; | ||
149 | |||
150 | pb->first_index = index; | ||
151 | if (num_entries > MAX_PLAYLIST_ENTRIES) | ||
152 | num_entries = MAX_PLAYLIST_ENTRIES; | ||
153 | |||
154 | for(i=0; i<num_entries; i++) | ||
155 | { | ||
156 | int len = playlist_entry_load(&(pb->tracks[i]), index, p, remaining); | ||
157 | if (len < 0) | ||
158 | { | ||
159 | /* Out of name buffer space */ | ||
160 | num_entries = i; | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | p += len; | ||
165 | remaining -= len; | ||
166 | |||
167 | if(direction==FORWARD) | ||
168 | index++; | ||
169 | else | ||
170 | index--; | ||
171 | index+=viewer.num_tracks; | ||
172 | index%=viewer.num_tracks; | ||
173 | } | ||
174 | pb->direction=direction; | ||
175 | pb->num_loaded = i; | ||
176 | } | ||
177 | |||
178 | void playlist_buffer_load_entries_screen(struct playlist_buffer * pb, | ||
179 | enum direction direction) | ||
180 | { | ||
181 | if(direction==FORWARD) | ||
182 | { | ||
183 | int min_start=viewer.selected_track-2*screens[0].nb_lines; | ||
184 | if(min_start<0) | ||
185 | min_start=0; | ||
186 | playlist_buffer_load_entries(pb, min_start, FORWARD); | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | int max_start=viewer.selected_track+2*screens[0].nb_lines; | ||
191 | max_start%=viewer.num_tracks; | ||
192 | playlist_buffer_load_entries(pb, max_start, BACKWARD); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | int playlist_entry_load(struct playlist_entry *entry, int index, | ||
197 | char* name_buffer, int remaining_size) | ||
198 | { | ||
199 | struct playlist_track_info info; | ||
200 | int len; | ||
201 | |||
202 | /* Playlist viewer orders songs based on display index. We need to | ||
203 | convert to real playlist index to access track */ | ||
204 | index = (index + playlist_get_first_index(viewer.playlist)) % | ||
205 | viewer.num_tracks; | ||
206 | if (playlist_get_track_info(viewer.playlist, index, &info) < 0) | ||
207 | return -1; | ||
208 | |||
209 | len = strlen(info.filename) + 1; | ||
210 | |||
211 | if (len <= remaining_size) | ||
212 | { | ||
213 | strcpy(name_buffer, info.filename); | ||
214 | |||
215 | entry->name = name_buffer; | ||
216 | entry->index = info.index; | ||
217 | entry->display_index = info.display_index; | ||
218 | entry->queued = info.attr & PLAYLIST_ATTR_QUEUED; | ||
219 | entry->skipped = info.attr & PLAYLIST_ATTR_SKIPPED; | ||
220 | return len; | ||
221 | } | ||
222 | return -1; | ||
223 | } | ||
224 | |||
225 | int playlist_buffer_get_index(struct playlist_buffer * pb, int index ) | ||
226 | { | ||
227 | int buffer_index; | ||
228 | if(pb->direction==FORWARD) | ||
229 | { | ||
230 | if(index>=pb->first_index) | ||
231 | buffer_index=index-pb->first_index; | ||
232 | else /* rotation : track0 in buffer + requested track */ | ||
233 | buffer_index=(viewer.num_tracks-pb->first_index)+(index); | ||
234 | } | ||
235 | else | ||
236 | { | ||
237 | if(index<=pb->first_index) | ||
238 | buffer_index=pb->first_index-index; | ||
239 | else /* rotation : track0 in buffer + dist from the last track | ||
240 | to the requested track (num_tracks-requested track) */ | ||
241 | buffer_index=(pb->first_index)+(viewer.num_tracks-index); | ||
242 | } | ||
243 | return(buffer_index); | ||
244 | } | ||
245 | |||
246 | #define distance(a, b) \ | ||
247 | a>b? (a) - (b) : (b) - (a) | ||
248 | bool playlist_buffer_needs_reload(struct playlist_buffer * pb, int track_index) | ||
249 | { | ||
250 | if(pb->num_loaded==viewer.num_tracks) | ||
251 | return(false); | ||
252 | int selected_index=playlist_buffer_get_index(pb, track_index); | ||
253 | int first_buffer_index=playlist_buffer_get_index(pb, pb->first_index); | ||
254 | int distance_beginning=distance(selected_index, first_buffer_index); | ||
255 | if(distance_beginning<MIN_BUFFER_MARGIN) | ||
256 | return(true); | ||
257 | |||
258 | if(pb->num_loaded - distance_beginning < MIN_BUFFER_MARGIN) | ||
259 | return(true); | ||
260 | return(false); | ||
261 | } | ||
262 | |||
263 | struct playlist_entry * playlist_buffer_get_track(struct playlist_buffer * pb, | ||
264 | int index) | ||
265 | { | ||
266 | int buffer_index=playlist_buffer_get_index(pb, index); | ||
267 | return(&(pb->tracks[buffer_index])); | ||
268 | } | ||
269 | |||
142 | /* Initialize the playlist viewer. */ | 270 | /* Initialize the playlist viewer. */ |
143 | static bool initialize(char* filename, bool reload) | 271 | static bool playlist_viewer_init(struct playlist_viewer * viewer, |
272 | char* filename, bool reload) | ||
144 | { | 273 | { |
145 | char* buffer; | 274 | char* buffer; |
146 | int buffer_size; | 275 | int buffer_size; |
@@ -155,15 +284,15 @@ static bool initialize(char* filename, bool reload) | |||
155 | return false; | 284 | return false; |
156 | 285 | ||
157 | if (!filename) | 286 | if (!filename) |
158 | viewer.playlist = NULL; | 287 | viewer->playlist = NULL; |
159 | else | 288 | else |
160 | { | 289 | { |
161 | /* Viewing playlist on disk */ | 290 | /* Viewing playlist on disk */ |
162 | char *dir, *file, *temp_ptr; | 291 | char *dir, *file, *temp_ptr; |
163 | char *index_buffer = NULL; | 292 | char *index_buffer = NULL; |
164 | int index_buffer_size = 0; | 293 | int index_buffer_size = 0; |
165 | 294 | ||
166 | viewer.playlist = &temp_playlist; | 295 | viewer->playlist = &temp_playlist; |
167 | 296 | ||
168 | /* Separate directory from filename */ | 297 | /* Separate directory from filename */ |
169 | temp_ptr = strrchr(filename+1,'/'); | 298 | temp_ptr = strrchr(filename+1,'/'); |
@@ -187,7 +316,7 @@ static bool initialize(char* filename, bool reload) | |||
187 | index_buffer = buffer; | 316 | index_buffer = buffer; |
188 | } | 317 | } |
189 | 318 | ||
190 | playlist_create_ex(viewer.playlist, dir, file, index_buffer, | 319 | playlist_create_ex(viewer->playlist, dir, file, index_buffer, |
191 | index_buffer_size, buffer+index_buffer_size, | 320 | index_buffer_size, buffer+index_buffer_size, |
192 | buffer_size-index_buffer_size); | 321 | buffer_size-index_buffer_size); |
193 | 322 | ||
@@ -197,201 +326,18 @@ static bool initialize(char* filename, bool reload) | |||
197 | buffer += index_buffer_size; | 326 | buffer += index_buffer_size; |
198 | buffer_size -= index_buffer_size; | 327 | buffer_size -= index_buffer_size; |
199 | } | 328 | } |
329 | playlist_buffer_init(&viewer->buffer, buffer, buffer_size ); | ||
200 | 330 | ||
201 | viewer.name_buffer = buffer; | 331 | viewer->move_track = -1; |
202 | viewer.buffer_size = buffer_size; | ||
203 | |||
204 | #ifdef HAVE_LCD_BITMAP | ||
205 | { | ||
206 | char icon_chars[] = "MQ"; /* characters used as icons */ | ||
207 | unsigned int i; | ||
208 | |||
209 | viewer.char_width = 0; | ||
210 | viewer.line_height = 0; | ||
211 | |||
212 | /* Use icon characters to calculate largest possible width/height so | ||
213 | that we set proper margins */ | ||
214 | for (i=0; i<sizeof(icon_chars); i++) | ||
215 | { | ||
216 | char str[2]; | ||
217 | int w, h; | ||
218 | |||
219 | snprintf(str, sizeof(str), "%c", icon_chars[i]); | ||
220 | lcd_getstringsize(str, &w, &h); | ||
221 | |||
222 | if (w > viewer.char_width) | ||
223 | viewer.char_width = w; | ||
224 | |||
225 | if (h > viewer.line_height) | ||
226 | { | ||
227 | viewer.line_height = h; | ||
228 | viewer.num_display_lines = (LCD_HEIGHT - MARGIN_Y)/h; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | #else | ||
233 | viewer.num_display_lines = 2; | ||
234 | viewer.char_width = 1; | ||
235 | viewer.line_height = 1; | ||
236 | #endif | ||
237 | |||
238 | viewer.move_track = -1; | ||
239 | 332 | ||
240 | if (!reload) | 333 | if (!reload) |
241 | { | 334 | viewer->selected_track = 0; |
242 | viewer.cursor_pos = 0; | ||
243 | |||
244 | if (!viewer.playlist) | ||
245 | /* Start displaying at current playing track */ | ||
246 | viewer.first_display_index = playlist_get_display_index() - 1; | ||
247 | else | ||
248 | viewer.first_display_index = 0; | ||
249 | |||
250 | update_first_index(); | ||
251 | } | ||
252 | 335 | ||
253 | if (!update_playlist(true)) | 336 | if (!update_playlist(true)) |
254 | return false; | 337 | return false; |
255 | |||
256 | return true; | 338 | return true; |
257 | } | 339 | } |
258 | 340 | ||
259 | /* Load tracks starting at start_index */ | ||
260 | static void load_playlist_entries(int start_index) | ||
261 | { | ||
262 | int num_entries = viewer.num_tracks - start_index; | ||
263 | char* p = viewer.name_buffer; | ||
264 | int remaining = viewer.buffer_size; | ||
265 | int i; | ||
266 | |||
267 | viewer.first_index = start_index; | ||
268 | |||
269 | if (num_entries > MAX_PLAYLIST_ENTRIES) | ||
270 | num_entries = MAX_PLAYLIST_ENTRIES; | ||
271 | |||
272 | for(i=0; i<num_entries; i++, start_index++) | ||
273 | { | ||
274 | int len = load_entry(start_index, i, p, remaining); | ||
275 | if (len < 0) | ||
276 | { | ||
277 | /* Out of name buffer space */ | ||
278 | num_entries = i; | ||
279 | break; | ||
280 | } | ||
281 | |||
282 | p += len; | ||
283 | remaining -= len; | ||
284 | } | ||
285 | |||
286 | viewer.num_loaded = num_entries; | ||
287 | viewer.last_index = viewer.first_index + (viewer.num_loaded - 1); | ||
288 | } | ||
289 | |||
290 | /* Load tracks in reverse, ending at end_index */ | ||
291 | static void load_playlist_entries_r(int end_index) | ||
292 | { | ||
293 | int num_entries = end_index; | ||
294 | char* p = viewer.name_buffer; | ||
295 | int remaining = viewer.buffer_size; | ||
296 | int i; | ||
297 | |||
298 | viewer.last_index = end_index; | ||
299 | |||
300 | if (num_entries >= MAX_PLAYLIST_ENTRIES) | ||
301 | num_entries = MAX_PLAYLIST_ENTRIES-1; | ||
302 | |||
303 | for(i=num_entries; i>=0; i--, end_index--) | ||
304 | { | ||
305 | int len = load_entry(end_index, i, p, remaining); | ||
306 | if (len < 0) | ||
307 | { | ||
308 | int j; | ||
309 | |||
310 | /* Out of name buffer space */ | ||
311 | num_entries -= i; | ||
312 | |||
313 | /* Shift loaded tracks up such that first track is index 0 */ | ||
314 | for (j=0; j<num_entries; j++, i++) | ||
315 | { | ||
316 | tracks[j].name = tracks[i].name; | ||
317 | tracks[j].index = tracks[i].index; | ||
318 | tracks[j].display_index = tracks[i].display_index; | ||
319 | tracks[j].queued = tracks[i].queued; | ||
320 | } | ||
321 | |||
322 | break; | ||
323 | } | ||
324 | |||
325 | p += len; | ||
326 | remaining -= len; | ||
327 | } | ||
328 | |||
329 | viewer.first_index = viewer.last_index - num_entries; | ||
330 | |||
331 | num_entries++; | ||
332 | if (!viewer.first_index && | ||
333 | num_entries < viewer.num_tracks && | ||
334 | num_entries < MAX_PLAYLIST_ENTRIES) | ||
335 | { | ||
336 | /* Lets see if we can load more data at the end of the list */ | ||
337 | int max = viewer.num_tracks; | ||
338 | if (max > MAX_PLAYLIST_ENTRIES) | ||
339 | max = MAX_PLAYLIST_ENTRIES; | ||
340 | |||
341 | for (i = num_entries; i<max; i++) | ||
342 | { | ||
343 | int len = load_entry(num_entries, num_entries, p, remaining); | ||
344 | if (len < 0) | ||
345 | /* Out of name buffer space */ | ||
346 | break; | ||
347 | |||
348 | p += len; | ||
349 | remaining -= len; | ||
350 | |||
351 | num_entries++; | ||
352 | viewer.last_index++; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | viewer.num_loaded = num_entries; | ||
357 | } | ||
358 | |||
359 | /* Load track at playlist index. pos is the position in the tracks array and | ||
360 | p is a pointer to the name buffer (max size), Returns -1 if buffer is | ||
361 | full. */ | ||
362 | static int load_entry(int index, int pos, char* p, int size) | ||
363 | { | ||
364 | struct playlist_track_info info; | ||
365 | int len; | ||
366 | int result = 0; | ||
367 | |||
368 | /* Playlist viewer orders songs based on display index. We need to | ||
369 | convert to real playlist index to access track */ | ||
370 | index = (index + playlist_get_first_index(viewer.playlist)) % | ||
371 | viewer.num_tracks; | ||
372 | if (playlist_get_track_info(viewer.playlist, index, &info) < 0) | ||
373 | return -1; | ||
374 | |||
375 | len = strlen(info.filename) + 1; | ||
376 | |||
377 | if (len <= size) | ||
378 | { | ||
379 | strcpy(p, info.filename); | ||
380 | |||
381 | tracks[pos].name = p; | ||
382 | tracks[pos].index = info.index; | ||
383 | tracks[pos].display_index = info.display_index; | ||
384 | tracks[pos].queued = info.attr & PLAYLIST_ATTR_QUEUED; | ||
385 | tracks[pos].skipped = info.attr & PLAYLIST_ATTR_SKIPPED; | ||
386 | |||
387 | result = len; | ||
388 | } | ||
389 | else | ||
390 | result = -1; | ||
391 | |||
392 | return result; | ||
393 | } | ||
394 | |||
395 | /* Format trackname for display purposes */ | 341 | /* Format trackname for display purposes */ |
396 | static void format_name(char* dest, const char* src) | 342 | static void format_name(char* dest, const char* src) |
397 | { | 343 | { |
@@ -403,10 +349,10 @@ static void format_name(char* dest, const char* src) | |||
403 | /* Only display the mp3 filename */ | 349 | /* Only display the mp3 filename */ |
404 | char* p = strrchr(src, '/'); | 350 | char* p = strrchr(src, '/'); |
405 | int len; | 351 | int len; |
406 | 352 | ||
407 | strcpy(dest, p+1); | 353 | strcpy(dest, p+1); |
408 | len = strlen(dest); | 354 | len = strlen(dest); |
409 | 355 | ||
410 | /* Remove the extension */ | 356 | /* Remove the extension */ |
411 | if (!strcasecmp(&dest[len-4], ".mp3") || | 357 | if (!strcasecmp(&dest[len-4], ".mp3") || |
412 | !strcasecmp(&dest[len-4], ".mp2") || | 358 | !strcasecmp(&dest[len-4], ".mp2") || |
@@ -441,205 +387,6 @@ static void format_line(const struct playlist_entry* track, char* str, int len) | |||
441 | 387 | ||
442 | } | 388 | } |
443 | 389 | ||
444 | /* Display tracks on screen */ | ||
445 | static void display_playlist(void) | ||
446 | { | ||
447 | int i; | ||
448 | int num_display_tracks = | ||
449 | viewer.last_display_index - viewer.first_display_index; | ||
450 | |||
451 | lcd_clear_display(); | ||
452 | |||
453 | #ifdef HAVE_LCD_BITMAP | ||
454 | lcd_setmargins(MARGIN_X, MARGIN_Y); | ||
455 | lcd_setfont(FONT_UI); | ||
456 | #endif | ||
457 | |||
458 | for (i=0; i<=num_display_tracks; i++) | ||
459 | { | ||
460 | if (global_settings.playlist_viewer_icons) | ||
461 | { | ||
462 | /* Icons */ | ||
463 | if (tracks[INDEX(i)].index == viewer.current_playing_track) | ||
464 | { | ||
465 | /* Current playing track */ | ||
466 | #ifdef HAVE_LCD_BITMAP | ||
467 | int offset=0; | ||
468 | if ( viewer.line_height > 8 ) | ||
469 | offset = (viewer.line_height - 8) / 2; | ||
470 | lcd_mono_bitmap(bitmap_icons_6x8[Icon_Audio], | ||
471 | CURSOR_X * 6 + CURSOR_WIDTH, | ||
472 | MARGIN_Y+(i*viewer.line_height) + offset, 6, 8); | ||
473 | #else | ||
474 | lcd_putc(LINE_X-1, i, Icon_Audio); | ||
475 | #endif | ||
476 | } | ||
477 | else if (tracks[INDEX(i)].index == viewer.move_track) | ||
478 | { | ||
479 | /* Track we are moving */ | ||
480 | #ifdef HAVE_LCD_BITMAP | ||
481 | lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, | ||
482 | MARGIN_Y+(i*viewer.line_height), "M"); | ||
483 | #else | ||
484 | lcd_putc(LINE_X-1, i, 'M'); | ||
485 | #endif | ||
486 | } | ||
487 | else if (tracks[INDEX(i)].queued) | ||
488 | { | ||
489 | /* Queued track */ | ||
490 | #ifdef HAVE_LCD_BITMAP | ||
491 | lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, | ||
492 | MARGIN_Y+(i*viewer.line_height), "Q"); | ||
493 | #else | ||
494 | lcd_putc(LINE_X-1, i, 'Q'); | ||
495 | #endif | ||
496 | } | ||
497 | } | ||
498 | |||
499 | update_display_line(i, false); | ||
500 | } | ||
501 | |||
502 | #ifdef HAVE_LCD_BITMAP | ||
503 | if (global_settings.scrollbar && | ||
504 | (viewer.num_tracks > viewer.num_display_lines)) | ||
505 | scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1, | ||
506 | LCD_HEIGHT - SCROLLBAR_Y, viewer.num_tracks-1, | ||
507 | viewer.first_display_index, viewer.last_display_index, | ||
508 | VERTICAL); | ||
509 | #endif | ||
510 | |||
511 | put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, true); | ||
512 | status_draw(true); | ||
513 | } | ||
514 | |||
515 | /* Scroll cursor or display by num lines */ | ||
516 | static void scroll_display(int lines) | ||
517 | { | ||
518 | int new_index = viewer.first_display_index + viewer.cursor_pos + lines; | ||
519 | bool pagescroll = false; | ||
520 | bool wrap = false; | ||
521 | |||
522 | put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, false); | ||
523 | |||
524 | if (lines > 1 || lines < -1) | ||
525 | pagescroll = true; | ||
526 | |||
527 | if (new_index < 0) | ||
528 | { | ||
529 | /* Wrap around if not pageup */ | ||
530 | if (pagescroll) | ||
531 | new_index = 0; | ||
532 | else | ||
533 | { | ||
534 | new_index += viewer.num_tracks; | ||
535 | viewer.cursor_pos = viewer.num_display_lines-1; | ||
536 | wrap = true; | ||
537 | } | ||
538 | } | ||
539 | else if (new_index >= viewer.num_tracks) | ||
540 | { | ||
541 | /* Wrap around if not pagedown */ | ||
542 | if (pagescroll) | ||
543 | new_index = viewer.num_tracks - 1; | ||
544 | else | ||
545 | { | ||
546 | new_index -= viewer.num_tracks; | ||
547 | viewer.cursor_pos = 0; | ||
548 | wrap = true; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | if (new_index >= viewer.first_display_index && | ||
553 | new_index <= viewer.last_display_index) | ||
554 | { | ||
555 | /* Just update the cursor */ | ||
556 | viewer.cursor_pos = new_index - viewer.first_display_index; | ||
557 | } | ||
558 | else | ||
559 | { | ||
560 | /* New track is outside of display */ | ||
561 | if (wrap) | ||
562 | viewer.first_display_index = new_index; | ||
563 | else | ||
564 | viewer.first_display_index = viewer.first_display_index + lines; | ||
565 | |||
566 | if (viewer.first_display_index < 0) | ||
567 | viewer.first_display_index = 0; | ||
568 | |||
569 | viewer.last_display_index = | ||
570 | viewer.first_display_index + (viewer.num_display_lines - 1); | ||
571 | if (viewer.last_display_index >= viewer.num_tracks) | ||
572 | { | ||
573 | /* display as many tracks as possible on screen */ | ||
574 | if (viewer.first_display_index > 0) | ||
575 | { | ||
576 | viewer.first_display_index -= | ||
577 | (viewer.last_display_index - viewer.num_tracks + 1); | ||
578 | if (viewer.first_display_index < 0) | ||
579 | viewer.first_display_index = 0; | ||
580 | } | ||
581 | |||
582 | viewer.last_display_index = viewer.num_tracks - 1; | ||
583 | } | ||
584 | |||
585 | if (viewer.cursor_pos > | ||
586 | (viewer.last_display_index - viewer.first_display_index)) | ||
587 | viewer.cursor_pos = | ||
588 | viewer.last_display_index - viewer.first_display_index; | ||
589 | |||
590 | /* Load more data if needed */ | ||
591 | if (viewer.first_display_index < viewer.first_index) | ||
592 | load_playlist_entries_r(viewer.last_display_index); | ||
593 | else if (viewer.last_display_index > viewer.last_index) | ||
594 | load_playlist_entries(viewer.first_display_index); | ||
595 | |||
596 | display_playlist(); | ||
597 | } | ||
598 | |||
599 | put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, true); | ||
600 | } | ||
601 | |||
602 | /* Update lcd line. Scroll line if requested */ | ||
603 | static void update_display_line(int line, bool scroll) | ||
604 | { | ||
605 | char str[MAX_PATH + 16]; | ||
606 | |||
607 | format_line(&tracks[INDEX(line)], str, sizeof(str)); | ||
608 | |||
609 | if (scroll) | ||
610 | { | ||
611 | #ifdef HAVE_LCD_BITMAP | ||
612 | if (global_settings.invert_cursor) | ||
613 | lcd_puts_scroll_style(LINE_X, line, str, STYLE_INVERT); | ||
614 | else | ||
615 | #endif | ||
616 | lcd_puts_scroll(LINE_X, line, str); | ||
617 | } | ||
618 | else | ||
619 | lcd_puts(LINE_X, line, str); | ||
620 | } | ||
621 | |||
622 | /* Update first index, if necessary, to put as much as possible on the | ||
623 | screen */ | ||
624 | static void update_first_index(void) | ||
625 | { | ||
626 | /* viewer.num_tracks may be invalid at this point */ | ||
627 | int num_tracks = playlist_amount_ex(viewer.playlist); | ||
628 | |||
629 | if ((num_tracks - viewer.first_display_index) < viewer.num_display_lines) | ||
630 | { | ||
631 | /* Try to display as much as possible */ | ||
632 | int old_index = viewer.first_display_index; | ||
633 | |||
634 | viewer.first_display_index = num_tracks - viewer.num_display_lines; | ||
635 | if (viewer.first_display_index < 0) | ||
636 | viewer.first_display_index = 0; | ||
637 | |||
638 | /* Cursor should still point at current track */ | ||
639 | viewer.cursor_pos += old_index - viewer.first_display_index; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | /* Update playlist in case something has changed or forced */ | 390 | /* Update playlist in case something has changed or forced */ |
644 | static bool update_playlist(bool force) | 391 | static bool update_playlist(bool force) |
645 | { | 392 | { |
@@ -647,32 +394,18 @@ static bool update_playlist(bool force) | |||
647 | playlist_get_resume_info(&viewer.current_playing_track); | 394 | playlist_get_resume_info(&viewer.current_playing_track); |
648 | else | 395 | else |
649 | viewer.current_playing_track = -1; | 396 | viewer.current_playing_track = -1; |
650 | 397 | int nb_tracks=playlist_amount_ex(viewer.playlist); | |
651 | if (force || playlist_amount_ex(viewer.playlist) != viewer.num_tracks) | 398 | force=force || nb_tracks != viewer.num_tracks; |
399 | if (force) | ||
652 | { | 400 | { |
653 | int index; | ||
654 | |||
655 | /* Reload tracks */ | 401 | /* Reload tracks */ |
656 | viewer.num_tracks = playlist_amount_ex(viewer.playlist); | 402 | viewer.num_tracks = nb_tracks; |
657 | if (viewer.num_tracks < 0) | 403 | if (viewer.num_tracks < 0) |
658 | return false; | 404 | return false; |
659 | 405 | playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD); | |
660 | index = viewer.first_display_index; | 406 | if (viewer.buffer.num_loaded <= 0) |
661 | |||
662 | load_playlist_entries(index); | ||
663 | |||
664 | if (viewer.num_loaded <= 0) | ||
665 | return false; | 407 | return false; |
666 | |||
667 | viewer.first_display_index = viewer.first_index; | ||
668 | viewer.last_display_index = | ||
669 | viewer.first_index + viewer.num_display_lines - 1; | ||
670 | if (viewer.last_display_index >= viewer.num_tracks) | ||
671 | viewer.last_display_index = viewer.num_tracks - 1; | ||
672 | } | 408 | } |
673 | |||
674 | display_playlist(); | ||
675 | |||
676 | return true; | 409 | return true; |
677 | } | 410 | } |
678 | 411 | ||
@@ -683,7 +416,9 @@ static int onplay_menu(int index) | |||
683 | { | 416 | { |
684 | struct menu_item items[3]; /* increase this if you add entries! */ | 417 | struct menu_item items[3]; /* increase this if you add entries! */ |
685 | int m, i=0, result, ret = 0; | 418 | int m, i=0, result, ret = 0; |
686 | bool current = (tracks[index].index == viewer.current_playing_track); | 419 | struct playlist_entry * current_track= |
420 | playlist_buffer_get_track(&viewer.buffer, index); | ||
421 | bool current = (current_track->index == viewer.current_playing_track); | ||
687 | 422 | ||
688 | items[i].desc = ID2P(LANG_REMOVE); | 423 | items[i].desc = ID2P(LANG_REMOVE); |
689 | i++; | 424 | i++; |
@@ -707,13 +442,14 @@ static int onplay_menu(int index) | |||
707 | { | 442 | { |
708 | case 0: | 443 | case 0: |
709 | /* delete track */ | 444 | /* delete track */ |
710 | playlist_delete(viewer.playlist, tracks[index].index); | 445 | playlist_delete(viewer.playlist, current_track->index); |
711 | |||
712 | if (current) | 446 | if (current) |
713 | { | 447 | { |
714 | /* Start playing new track except if it's the last track | 448 | /* Start playing new track except if it's the last track |
715 | in the playlist and repeat mode is disabled */ | 449 | in the playlist and repeat mode is disabled */ |
716 | if (tracks[index].display_index != viewer.num_tracks || | 450 | current_track= |
451 | playlist_buffer_get_track(&viewer.buffer, index); | ||
452 | if (current_track->display_index != viewer.num_tracks || | ||
717 | global_settings.repeat_mode == REPEAT_ALL) | 453 | global_settings.repeat_mode == REPEAT_ALL) |
718 | { | 454 | { |
719 | talk_buffer_steal(); /* will use the mp3 buffer */ | 455 | talk_buffer_steal(); /* will use the mp3 buffer */ |
@@ -721,30 +457,26 @@ static int onplay_menu(int index) | |||
721 | viewer.current_playing_track = -1; | 457 | viewer.current_playing_track = -1; |
722 | } | 458 | } |
723 | } | 459 | } |
724 | |||
725 | ret = 1; | 460 | ret = 1; |
726 | break; | 461 | break; |
727 | case 1: | 462 | case 1: |
728 | /* move track */ | 463 | /* move track */ |
729 | viewer.move_track = tracks[index].index; | 464 | viewer.move_track = current_track->index; |
730 | ret = 0; | 465 | ret = 0; |
731 | break; | 466 | break; |
732 | case 2: | 467 | case 2: |
733 | { | 468 | { |
734 | onplay(tracks[index].name, TREE_ATTR_MPA, CONTEXT_TREE); | 469 | onplay(current_track->name, TREE_ATTR_MPA, CONTEXT_TREE); |
735 | 470 | ||
736 | if (!viewer.playlist) | 471 | if (!viewer.playlist) |
737 | ret = 1; | 472 | ret = 1; |
738 | else | 473 | else |
739 | ret = 0; | 474 | ret = 0; |
740 | |||
741 | break; | 475 | break; |
742 | } | 476 | } |
743 | } | 477 | } |
744 | } | 478 | } |
745 | |||
746 | menu_exit(m); | 479 | menu_exit(m); |
747 | |||
748 | return ret; | 480 | return ret; |
749 | } | 481 | } |
750 | 482 | ||
@@ -792,7 +524,7 @@ static bool track_display(void) | |||
792 | { STR(LANG_DISPLAY_TRACK_NAME_ONLY) }, | 524 | { STR(LANG_DISPLAY_TRACK_NAME_ONLY) }, |
793 | { STR(LANG_DISPLAY_FULL_PATH) } | 525 | { STR(LANG_DISPLAY_FULL_PATH) } |
794 | }; | 526 | }; |
795 | 527 | ||
796 | return set_option(str(LANG_TRACK_DISPLAY), | 528 | return set_option(str(LANG_TRACK_DISPLAY), |
797 | &global_settings.playlist_viewer_track_display, INT, names, 2, NULL); | 529 | &global_settings.playlist_viewer_track_display, INT, names, 2, NULL); |
798 | } | 530 | } |
@@ -807,7 +539,6 @@ static bool save_playlist(void) | |||
807 | if (!kbd_input(filename, sizeof(filename))) | 539 | if (!kbd_input(filename, sizeof(filename))) |
808 | { | 540 | { |
809 | playlist_save(viewer.playlist, filename); | 541 | playlist_save(viewer.playlist, filename); |
810 | |||
811 | /* reload in case playlist was saved to cwd */ | 542 | /* reload in case playlist was saved to cwd */ |
812 | reload_directory(); | 543 | reload_directory(); |
813 | } | 544 | } |
@@ -821,63 +552,89 @@ bool playlist_viewer(void) | |||
821 | return playlist_viewer_ex(NULL); | 552 | return playlist_viewer_ex(NULL); |
822 | } | 553 | } |
823 | 554 | ||
555 | |||
556 | |||
557 | |||
558 | char * playlist_callback_name(int selected_item, void * data, char *buffer) | ||
559 | { | ||
560 | struct playlist_viewer * local_viewer = (struct playlist_viewer *)data; | ||
561 | struct playlist_entry *track= | ||
562 | playlist_buffer_get_track(&(local_viewer->buffer), selected_item); | ||
563 | format_line(track, buffer, MAX_PATH); | ||
564 | return(buffer); | ||
565 | } | ||
566 | |||
567 | |||
568 | void playlist_callback_icons(int selected_item, void * data, ICON * icon) | ||
569 | { | ||
570 | struct playlist_viewer * local_viewer=(struct playlist_viewer *)data; | ||
571 | struct playlist_entry *track= | ||
572 | playlist_buffer_get_track(&(local_viewer->buffer), selected_item); | ||
573 | if (track->index == local_viewer->current_playing_track) | ||
574 | { | ||
575 | /* Current playing track */ | ||
576 | #ifdef HAVE_LCD_BITMAP | ||
577 | *icon=bitmap_icons_6x8[Icon_Audio]; | ||
578 | #else | ||
579 | *icon=Icon_Audio; | ||
580 | #endif | ||
581 | } | ||
582 | else if (track->index == local_viewer->move_track) | ||
583 | { | ||
584 | /* Track we are moving */ | ||
585 | #ifdef HAVE_LCD_BITMAP | ||
586 | *icon=bitmap_icons_6x8[Icon_Moving]; | ||
587 | #else | ||
588 | *icon=Icon_Moving; | ||
589 | #endif | ||
590 | } | ||
591 | else if (track->queued) | ||
592 | { | ||
593 | /* Queued track */ | ||
594 | #ifdef HAVE_LCD_BITMAP | ||
595 | *icon=bitmap_icons_6x8[Icon_Queued]; | ||
596 | #else | ||
597 | *icon=Icon_Queued; | ||
598 | #endif | ||
599 | } | ||
600 | else | ||
601 | *icon=0; | ||
602 | } | ||
603 | |||
604 | |||
605 | |||
824 | /* Main viewer function. Filename identifies playlist to be viewed. If NULL, | 606 | /* Main viewer function. Filename identifies playlist to be viewed. If NULL, |
825 | view current playlist. */ | 607 | view current playlist. */ |
826 | bool playlist_viewer_ex(char* filename) | 608 | bool playlist_viewer_ex(char* filename) |
827 | { | 609 | { |
828 | bool ret = false; /* return value */ | 610 | bool ret = false; /* return value */ |
829 | bool exit=false; /* exit viewer */ | 611 | bool exit=false; /* exit viewer */ |
830 | bool update=true; /* update display */ | ||
831 | bool cursor_on=true; /* used for flashing cursor */ | ||
832 | int old_cursor_pos; /* last cursor position */ | ||
833 | int button, lastbutton = BUTTON_NONE; | 612 | int button, lastbutton = BUTTON_NONE; |
834 | 613 | struct gui_synclist playlist_lists; | |
835 | if (!initialize(filename, false)) | 614 | if (!playlist_viewer_init(&viewer, filename, false)) |
836 | goto exit; | 615 | goto exit; |
837 | 616 | ||
838 | old_cursor_pos = viewer.cursor_pos; | 617 | gui_synclist_init(&playlist_lists, playlist_callback_icons, |
839 | 618 | playlist_callback_name, &viewer); | |
619 | gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks); | ||
620 | gui_synclist_select_item(&playlist_lists, viewer.selected_track); | ||
621 | gui_synclist_draw(&playlist_lists); | ||
840 | while (!exit) | 622 | while (!exit) |
841 | { | 623 | { |
842 | int track; | 624 | int track; |
843 | |||
844 | if (!viewer.playlist && !(audio_status() & AUDIO_STATUS_PLAY)) | 625 | if (!viewer.playlist && !(audio_status() & AUDIO_STATUS_PLAY)) |
845 | { | 626 | { |
846 | /* Play has stopped */ | 627 | /* Play has stopped */ |
847 | #ifdef HAVE_LCD_CHARCELLS | 628 | #ifdef HAVE_LCD_CHARCELLS |
848 | splash(HZ, true, str(LANG_END_PLAYLIST_PLAYER)); | 629 | gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_PLAYER)); |
849 | #else | 630 | #else |
850 | splash(HZ, true, str(LANG_END_PLAYLIST_RECORDER)); | 631 | gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_RECORDER)); |
851 | #endif | 632 | #endif |
852 | goto exit; | 633 | goto exit; |
853 | } | 634 | } |
854 | 635 | ||
855 | if (viewer.move_track != -1 || !cursor_on) | 636 | if (viewer.move_track != -1) |
856 | { | 637 | gui_synclist_flash(&playlist_lists); |
857 | /* Flash cursor to identify that we are moving a track */ | ||
858 | cursor_on = !cursor_on; | ||
859 | #ifdef HAVE_LCD_BITMAP | ||
860 | if (global_settings.invert_cursor) | ||
861 | { | ||
862 | lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
863 | lcd_fillrect( | ||
864 | MARGIN_X, MARGIN_Y+(viewer.cursor_pos*viewer.line_height), | ||
865 | LCD_WIDTH, viewer.line_height); | ||
866 | lcd_set_drawmode(DRMODE_SOLID); | ||
867 | lcd_invertscroll(LINE_X, viewer.cursor_pos); | ||
868 | } | ||
869 | else | ||
870 | put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, | ||
871 | cursor_on); | ||
872 | |||
873 | lcd_update_rect( | ||
874 | 0, MARGIN_Y + (viewer.cursor_pos * viewer.line_height), | ||
875 | LCD_WIDTH, viewer.line_height); | ||
876 | #else | ||
877 | put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, cursor_on); | ||
878 | lcd_update(); | ||
879 | #endif | ||
880 | } | ||
881 | 638 | ||
882 | if (!viewer.playlist) | 639 | if (!viewer.playlist) |
883 | playlist_get_resume_info(&track); | 640 | playlist_get_resume_info(&track); |
@@ -888,19 +645,27 @@ bool playlist_viewer_ex(char* filename) | |||
888 | playlist_amount_ex(viewer.playlist) != viewer.num_tracks) | 645 | playlist_amount_ex(viewer.playlist) != viewer.num_tracks) |
889 | { | 646 | { |
890 | /* Playlist has changed (new track started?) */ | 647 | /* Playlist has changed (new track started?) */ |
891 | update_first_index(); | ||
892 | if (!update_playlist(false)) | 648 | if (!update_playlist(false)) |
893 | goto exit; | 649 | goto exit; |
894 | else | 650 | gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks); |
895 | update = true; | ||
896 | |||
897 | /* Abort move on playlist change */ | 651 | /* Abort move on playlist change */ |
898 | viewer.move_track = -1; | 652 | viewer.move_track = -1; |
899 | } | 653 | } |
900 | 654 | ||
901 | /* Timeout so we can determine if play status has changed */ | 655 | /* Timeout so we can determine if play status has changed */ |
902 | button = button_get_w_tmo(HZ/2); | 656 | button = button_get_w_tmo(HZ/2); |
903 | 657 | int list_action; | |
658 | if( (list_action=gui_synclist_do_button(&playlist_lists, button))!=0 ) | ||
659 | { | ||
660 | viewer.selected_track=gui_synclist_get_sel_pos(&playlist_lists); | ||
661 | if(playlist_buffer_needs_reload(&viewer.buffer, viewer.selected_track)) | ||
662 | playlist_buffer_load_entries_screen(&viewer.buffer, | ||
663 | list_action==LIST_NEXT? | ||
664 | FORWARD | ||
665 | : | ||
666 | BACKWARD | ||
667 | ); | ||
668 | } | ||
904 | switch (button) | 669 | switch (button) |
905 | { | 670 | { |
906 | case TREE_EXIT: | 671 | case TREE_EXIT: |
@@ -910,48 +675,20 @@ bool playlist_viewer_ex(char* filename) | |||
910 | exit = true; | 675 | exit = true; |
911 | break; | 676 | break; |
912 | 677 | ||
913 | case TREE_PREV: | ||
914 | case TREE_PREV | BUTTON_REPEAT: | ||
915 | scroll_display(-1); | ||
916 | update = true; | ||
917 | break; | ||
918 | |||
919 | case TREE_NEXT: | ||
920 | case TREE_NEXT | BUTTON_REPEAT: | ||
921 | scroll_display(1); | ||
922 | update = true; | ||
923 | break; | ||
924 | |||
925 | #ifdef TREE_PGUP | ||
926 | case TREE_PGUP: | ||
927 | case TREE_PGUP | BUTTON_REPEAT: | ||
928 | /* Pageup */ | ||
929 | scroll_display(-viewer.num_display_lines); | ||
930 | update = true; | ||
931 | break; | ||
932 | |||
933 | case TREE_PGDN: | ||
934 | case TREE_PGDN | BUTTON_REPEAT: | ||
935 | /* Pagedown */ | ||
936 | scroll_display(viewer.num_display_lines); | ||
937 | update = true; | ||
938 | break; | ||
939 | #endif | ||
940 | |||
941 | case TREE_RUN: | 678 | case TREE_RUN: |
942 | #ifdef TREE_RUN_PRE | 679 | #ifdef TREE_RUN_PRE |
943 | if (lastbutton != TREE_RUN_PRE) | 680 | if (lastbutton != TREE_RUN_PRE) |
944 | break; | 681 | break; |
945 | #endif | 682 | #endif |
683 | struct playlist_entry * current_track=playlist_buffer_get_track(&viewer.buffer, viewer.selected_track); | ||
946 | if (viewer.move_track >= 0) | 684 | if (viewer.move_track >= 0) |
947 | { | 685 | { |
948 | /* Move track */ | 686 | /* Move track */ |
949 | int ret; | 687 | int ret; |
950 | 688 | ||
951 | ret = playlist_move(viewer.playlist, viewer.move_track, | 689 | ret = playlist_move(viewer.playlist, viewer.move_track, current_track->index); |
952 | tracks[INDEX(viewer.cursor_pos)].index); | ||
953 | if (ret < 0) | 690 | if (ret < 0) |
954 | splash(HZ, true, str(LANG_MOVE_FAILED)); | 691 | gui_syncsplash(HZ, true, str(LANG_MOVE_FAILED)); |
955 | 692 | ||
956 | update_playlist(true); | 693 | update_playlist(true); |
957 | viewer.move_track = -1; | 694 | viewer.move_track = -1; |
@@ -959,7 +696,7 @@ bool playlist_viewer_ex(char* filename) | |||
959 | else if (!viewer.playlist) | 696 | else if (!viewer.playlist) |
960 | { | 697 | { |
961 | /* play new track */ | 698 | /* play new track */ |
962 | playlist_start(tracks[INDEX(viewer.cursor_pos)].index, 0); | 699 | playlist_start(current_track->index, 0); |
963 | update_playlist(false); | 700 | update_playlist(false); |
964 | } | 701 | } |
965 | else | 702 | else |
@@ -968,15 +705,14 @@ bool playlist_viewer_ex(char* filename) | |||
968 | if (playlist_set_current(viewer.playlist) < 0) | 705 | if (playlist_set_current(viewer.playlist) < 0) |
969 | goto exit; | 706 | goto exit; |
970 | 707 | ||
971 | playlist_start(tracks[INDEX(viewer.cursor_pos)].index, 0); | 708 | playlist_start(current_track->index, 0); |
972 | 709 | ||
973 | /* Our playlist is now the current list */ | 710 | /* Our playlist is now the current list */ |
974 | if (!initialize(NULL, true)) | 711 | if (!playlist_viewer_init(&viewer, NULL, true)) |
975 | goto exit; | 712 | goto exit; |
976 | } | 713 | } |
714 | gui_synclist_draw(&playlist_lists); | ||
977 | 715 | ||
978 | display_playlist(); | ||
979 | update = true; | ||
980 | break; | 716 | break; |
981 | 717 | ||
982 | case TREE_CONTEXT: | 718 | case TREE_CONTEXT: |
@@ -987,7 +723,7 @@ bool playlist_viewer_ex(char* filename) | |||
987 | /* ON+PLAY menu */ | 723 | /* ON+PLAY menu */ |
988 | int ret; | 724 | int ret; |
989 | 725 | ||
990 | ret = onplay_menu(INDEX(viewer.cursor_pos)); | 726 | ret = onplay_menu(viewer.selected_track); |
991 | 727 | ||
992 | if (ret < 0) | 728 | if (ret < 0) |
993 | { | 729 | { |
@@ -997,15 +733,12 @@ bool playlist_viewer_ex(char* filename) | |||
997 | else if (ret > 0) | 733 | else if (ret > 0) |
998 | { | 734 | { |
999 | /* Playlist changed */ | 735 | /* Playlist changed */ |
1000 | update_first_index(); | 736 | gui_synclist_del_item(&playlist_lists); |
1001 | update_playlist(false); | 737 | update_playlist(true); |
1002 | if (viewer.num_tracks <= 0) | 738 | if (viewer.num_tracks <= 0) |
1003 | exit = true; | 739 | exit = true; |
1004 | } | 740 | } |
1005 | else | 741 | gui_synclist_draw(&playlist_lists); |
1006 | display_playlist(); | ||
1007 | |||
1008 | update = true; | ||
1009 | break; | 742 | break; |
1010 | } | 743 | } |
1011 | 744 | ||
@@ -1015,13 +748,11 @@ bool playlist_viewer_ex(char* filename) | |||
1015 | ret = true; | 748 | ret = true; |
1016 | goto exit; | 749 | goto exit; |
1017 | } | 750 | } |
1018 | 751 | gui_synclist_draw(&playlist_lists); | |
1019 | display_playlist(); | ||
1020 | update = true; | ||
1021 | break; | 752 | break; |
1022 | 753 | ||
1023 | case BUTTON_NONE: | 754 | case BUTTON_NONE: |
1024 | status_draw(false); | 755 | gui_syncstatusbar_draw(&statusbars, false); |
1025 | break; | 756 | break; |
1026 | 757 | ||
1027 | default: | 758 | default: |
@@ -1032,36 +763,6 @@ bool playlist_viewer_ex(char* filename) | |||
1032 | } | 763 | } |
1033 | break; | 764 | break; |
1034 | } | 765 | } |
1035 | |||
1036 | if (update && !exit) | ||
1037 | { | ||
1038 | lcd_stop_scroll(); | ||
1039 | |||
1040 | if (viewer.cursor_pos > | ||
1041 | (viewer.last_display_index - viewer.first_display_index)) | ||
1042 | { | ||
1043 | /* Cursor position is invalid */ | ||
1044 | put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, false); | ||
1045 | viewer.cursor_pos = | ||
1046 | viewer.last_display_index - viewer.first_display_index; | ||
1047 | put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, true); | ||
1048 | } | ||
1049 | |||
1050 | if (viewer.cursor_pos != old_cursor_pos && | ||
1051 | old_cursor_pos <= | ||
1052 | (viewer.last_display_index - viewer.first_display_index)) | ||
1053 | /* Stop scrolling previous line */ | ||
1054 | update_display_line(old_cursor_pos, false); | ||
1055 | |||
1056 | /* Scroll line at new cursor position */ | ||
1057 | update_display_line(viewer.cursor_pos, true); | ||
1058 | |||
1059 | lcd_update(); | ||
1060 | |||
1061 | old_cursor_pos = viewer.cursor_pos; | ||
1062 | cursor_on = true; | ||
1063 | update = false; | ||
1064 | } | ||
1065 | lastbutton = button; | 766 | lastbutton = button; |
1066 | } | 767 | } |
1067 | 768 | ||