diff options
Diffstat (limited to 'apps/playlist_viewer.c')
-rw-r--r-- | apps/playlist_viewer.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index 68732adcbc..5479ba43ba 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c | |||
@@ -175,12 +175,21 @@ static void playlist_buffer_load_entries(struct playlist_buffer *pb, int index, | |||
175 | pb->num_loaded = i; | 175 | pb->num_loaded = i; |
176 | } | 176 | } |
177 | 177 | ||
178 | /* playlist_buffer_load_entries_screen() | ||
179 | * This function is called when the currently selected item gets too close | ||
180 | * to the start or the end of the loaded part of the playlis, or when | ||
181 | * the list callback requests a playlist item that has not been loaded yet | ||
182 | * | ||
183 | * reference_track is either the currently selected track, or the track that | ||
184 | * has been requested by the callback, and has not been loaded yet. | ||
185 | */ | ||
178 | static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb, | 186 | static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb, |
179 | enum direction direction) | 187 | enum direction direction, |
188 | int reference_track) | ||
180 | { | 189 | { |
181 | if (direction == FORWARD) | 190 | if (direction == FORWARD) |
182 | { | 191 | { |
183 | int min_start = viewer.selected_track-2*screens[0].getnblines(); | 192 | int min_start = reference_track-2*screens[0].getnblines(); |
184 | while (min_start < 0) | 193 | while (min_start < 0) |
185 | min_start += viewer.num_tracks; | 194 | min_start += viewer.num_tracks; |
186 | min_start %= viewer.num_tracks; | 195 | min_start %= viewer.num_tracks; |
@@ -188,7 +197,7 @@ static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb, | |||
188 | } | 197 | } |
189 | else | 198 | else |
190 | { | 199 | { |
191 | int max_start = viewer.selected_track+2*screens[0].getnblines(); | 200 | int max_start = reference_track+2*screens[0].getnblines(); |
192 | max_start %= viewer.num_tracks; | 201 | max_start %= viewer.num_tracks; |
193 | playlist_buffer_load_entries(pb, max_start, BACKWARD); | 202 | playlist_buffer_load_entries(pb, max_start, BACKWARD); |
194 | } | 203 | } |
@@ -266,6 +275,31 @@ static struct playlist_entry * playlist_buffer_get_track(struct playlist_buffer | |||
266 | int index) | 275 | int index) |
267 | { | 276 | { |
268 | int buffer_index = playlist_buffer_get_index(pb, index); | 277 | int buffer_index = playlist_buffer_get_index(pb, index); |
278 | /* Make sure that we are not returning an invalid pointer. | ||
279 | In some cases, when scrolling really fast, it could happen that a reqested track | ||
280 | has not been pre-loaded */ | ||
281 | if (buffer_index < 0) { | ||
282 | playlist_buffer_load_entries_screen(&viewer.buffer, | ||
283 | pb->direction == FORWARD ? BACKWARD : FORWARD, | ||
284 | index); | ||
285 | |||
286 | } else if (buffer_index >= pb->num_loaded) { | ||
287 | playlist_buffer_load_entries_screen(&viewer.buffer, | ||
288 | pb->direction, | ||
289 | index); | ||
290 | } | ||
291 | buffer_index = playlist_buffer_get_index(pb, index); | ||
292 | if (buffer_index < 0 || buffer_index >= pb->num_loaded) { | ||
293 | /* This really shouldn't happen. If this happens, then | ||
294 | the name_buffer is probably too small to store enough | ||
295 | titles to fill the screen, and preload data in the short | ||
296 | direction. | ||
297 | |||
298 | If this happens then scrolling performance will probably | ||
299 | be quite low, but it's better then having Data Abort errors */ | ||
300 | playlist_buffer_load_entries(pb, index, FORWARD); | ||
301 | buffer_index = playlist_buffer_get_index(pb, index); | ||
302 | } | ||
269 | return &(pb->tracks[buffer_index]); | 303 | return &(pb->tracks[buffer_index]); |
270 | } | 304 | } |
271 | 305 | ||
@@ -425,7 +459,8 @@ static bool update_playlist(bool force) | |||
425 | global_status.resume_offset = -1; | 459 | global_status.resume_offset = -1; |
426 | return false; | 460 | return false; |
427 | } | 461 | } |
428 | playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD); | 462 | playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD, |
463 | viewer.selected_track); | ||
429 | if (viewer.buffer.num_loaded <= 0) | 464 | if (viewer.buffer.num_loaded <= 0) |
430 | { | 465 | { |
431 | global_status.resume_index = -1; | 466 | global_status.resume_index = -1; |
@@ -679,7 +714,8 @@ enum playlist_viewer_result playlist_viewer_ex(const char* filename) | |||
679 | viewer.selected_track); | 714 | viewer.selected_track); |
680 | if (reload) | 715 | if (reload) |
681 | playlist_buffer_load_entries_screen(&viewer.buffer, | 716 | playlist_buffer_load_entries_screen(&viewer.buffer, |
682 | button == ACTION_STD_NEXT ? FORWARD : BACKWARD); | 717 | button == ACTION_STD_NEXT ? FORWARD : BACKWARD, |
718 | viewer.selected_track); | ||
683 | if (reload || viewer.moving_track >= 0) | 719 | if (reload || viewer.moving_track >= 0) |
684 | gui_synclist_draw(&playlist_lists); | 720 | gui_synclist_draw(&playlist_lists); |
685 | } | 721 | } |