1 /***************************************************************************
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
11 * Copyright (C) 2003 Hardeep Sidhu
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
36 #ifdef HAVE_LCD_BITMAP
42 #include "playlist_viewer.h"
44 /* Defines for LCD display purposes. Taken from tree.c */
45 #ifdef HAVE_LCD_BITMAP
46 #define CURSOR_X (global_settings.scrollbar && \
47 viewer.num_tracks>viewer.num_display_lines?1:0)
49 #define CURSOR_WIDTH (global_settings.invert_cursor ? 0 : 4)
51 #define ICON_WIDTH ((viewer.char_width > 6) ? viewer.char_width : 6)
53 #define MARGIN_X ((global_settings.scrollbar && \
54 viewer.num_tracks > viewer.num_display_lines ? \
55 SCROLLBAR_WIDTH : 0) + CURSOR_WIDTH + \
56 (global_settings.playlist_viewer_icons ? \
58 #define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0)
61 #define LINE_Y (global_settings.statusbar ? 1 : 0)
64 #define SCROLLBAR_Y lcd_getymargin()
65 #define SCROLLBAR_WIDTH 6
75 /* Maximum number of tracks we can have loaded at one time */
76 #define MAX_PLAYLIST_ENTRIES 200
78 /* Default playlist name for saving */
79 #define DEFAULT_PLAYLIST_NAME "/viewer.m3u"
81 /* Index of track on display line _pos */
82 #define INDEX(_pos) (viewer.first_display_index - viewer.first_index + (_pos))
84 /* Global playlist viewer settings */
85 struct playlist_viewer_info
{
86 struct playlist_info
* playlist
; /* playlist being viewed */
87 char *name_buffer
; /* Buffer used to store track names */
88 int buffer_size
; /* Size of name buffer */
90 int num_display_lines
; /* Number of lines on lcd */
91 int line_height
; /* Height (in pixels) of display line */
92 int char_width
; /* Width (in pixels) of a character */
94 int num_tracks
; /* Number of tracks in playlist */
95 int current_playing_track
; /* Index of current playing track */
97 int num_loaded
; /* Number of track entries loaded in viewer */
98 int first_index
; /* Index of first loaded track */
99 int last_index
; /* Index of last loaded track */
100 int first_display_index
; /* Index of first track on display */
101 int last_display_index
; /* Index of last track on display */
102 int cursor_pos
; /* Line number of cursor */
104 int move_track
; /* Playlist index of track to move or -1 */
107 /* Information about a specific track */
108 struct playlist_entry
{
109 char *name
; /* Formatted track name */
110 int index
; /* Playlist index */
111 int display_index
; /* Display index */
112 bool queued
; /* Is track queued? */
115 static struct playlist_viewer_info viewer
;
116 static struct playlist_entry tracks
[MAX_PLAYLIST_ENTRIES
];
118 /* Used when viewing playlists on disk */
119 static struct playlist_info temp_playlist
;
121 #ifdef HAVE_LCD_BITMAP
122 extern unsigned char bitmap_icons_6x8
[LastIcon
][6];
125 static bool initialize(char* filename
, bool reload
);
126 static void load_playlist_entries(int start_index
);
127 static void load_playlist_entries_r(int end_index
);
128 static int load_entry(int index
, int pos
, char* p
, int size
);
129 static void format_name(char* dest
, char* src
);
130 static void format_line(struct playlist_entry
* track
, char* str
, int len
);
131 static void display_playlist(void);
132 static void update_display_line(int line
, bool scroll
);
133 static void scroll_display(int lines
);
134 static void update_first_index(void);
135 static bool update_playlist(bool force
);
137 static int onplay_menu(int index
);
139 static bool viewer_menu(void);
140 static bool show_icons(void);
141 static bool show_indices(void);
142 static bool track_display(void);
143 static bool save_playlist(void);
145 /* Initialize the playlist viewer. */
146 static bool initialize(char* filename
, bool reload
)
150 bool is_playing
= mpeg_status() & MPEG_STATUS_PLAY
;
152 if (!filename
&& !is_playing
)
153 /* Nothing is playing, exit */
156 buffer
= plugin_get_buffer(&buffer_size
);
161 viewer
.playlist
= NULL
;
164 /* Viewing playlist on disk */
165 char *dir
, *file
, *temp_ptr
;
166 char *index_buffer
= NULL
;
167 int index_buffer_size
= 0;
169 viewer
.playlist
= &temp_playlist
;
171 /* Separate directory from filename */
172 temp_ptr
= strrchr(filename
+1,'/');
187 /* Something is playing, use half the plugin buffer for playlist
189 index_buffer_size
= buffer_size
/ 2;
190 index_buffer
= buffer
;
193 playlist_create_ex(viewer
.playlist
, dir
, file
, index_buffer
,
194 index_buffer_size
, buffer
+index_buffer_size
,
195 buffer_size
-index_buffer_size
);
200 buffer
+= index_buffer_size
;
201 buffer_size
-= index_buffer_size
;
204 viewer
.name_buffer
= buffer
;
205 viewer
.buffer_size
= buffer_size
;
207 #ifdef HAVE_LCD_BITMAP
209 char icon_chars
[] = "MQ"; /* characters used as icons */
212 viewer
.char_width
= 0;
213 viewer
.line_height
= 0;
215 /* Use icon characters to calculate largest possible width/height so
216 that we set proper margins */
217 for (i
=0; i
<sizeof(icon_chars
); i
++)
222 snprintf(str
, sizeof(str
), "%c", icon_chars
[i
]);
223 lcd_getstringsize(str
, &w
, &h
);
225 if (w
> viewer
.char_width
)
226 viewer
.char_width
= w
;
228 if (h
> viewer
.line_height
)
230 viewer
.line_height
= h
;
231 viewer
.num_display_lines
= (LCD_HEIGHT
- MARGIN_Y
)/h
;
236 viewer
.num_display_lines
= 2;
237 viewer
.char_width
= 1;
238 viewer
.line_height
= 1;
241 viewer
.move_track
= -1;
245 viewer
.cursor_pos
= 0;
247 if (!viewer
.playlist
)
248 /* Start displaying at current playing track */
249 viewer
.first_display_index
= playlist_get_display_index() - 1;
251 viewer
.first_display_index
= 0;
253 update_first_index();
256 if (!update_playlist(true))
262 /* Load tracks starting at start_index */
263 static void load_playlist_entries(int start_index
)
265 int num_entries
= viewer
.num_tracks
- start_index
;
266 char* p
= viewer
.name_buffer
;
267 int remaining
= viewer
.buffer_size
;
270 viewer
.first_index
= start_index
;
272 if (num_entries
> MAX_PLAYLIST_ENTRIES
)
273 num_entries
= MAX_PLAYLIST_ENTRIES
;
275 for(i
=0; i
<num_entries
; i
++, start_index
++)
277 int len
= load_entry(start_index
, i
, p
, remaining
);
280 /* Out of name buffer space */
289 viewer
.num_loaded
= num_entries
;
290 viewer
.last_index
= viewer
.first_index
+ (viewer
.num_loaded
- 1);
293 /* Load tracks in reverse, ending at end_index */
294 static void load_playlist_entries_r(int end_index
)
296 int num_entries
= end_index
;
297 char* p
= viewer
.name_buffer
;
298 int remaining
= viewer
.buffer_size
;
301 viewer
.last_index
= end_index
;
303 if (num_entries
>= MAX_PLAYLIST_ENTRIES
)
304 num_entries
= MAX_PLAYLIST_ENTRIES
-1;
306 for(i
=num_entries
; i
>=0; i
--, end_index
--)
308 int len
= load_entry(end_index
, i
, p
, remaining
);
313 /* Out of name buffer space */
316 /* Shift loaded tracks up such that first track is index 0 */
317 for (j
=0; j
<num_entries
; j
++, i
++)
319 tracks
[j
].name
= tracks
[i
].name
;
320 tracks
[j
].index
= tracks
[i
].index
;
321 tracks
[j
].display_index
= tracks
[i
].display_index
;
322 tracks
[j
].queued
= tracks
[i
].queued
;
332 viewer
.first_index
= viewer
.last_index
- num_entries
;
335 if (!viewer
.first_index
&&
336 num_entries
< viewer
.num_tracks
&&
337 num_entries
< MAX_PLAYLIST_ENTRIES
)
339 /* Lets see if we can load more data at the end of the list */
340 int max
= viewer
.num_tracks
;
341 if (max
> MAX_PLAYLIST_ENTRIES
)
342 max
= MAX_PLAYLIST_ENTRIES
;
344 for (i
= num_entries
; i
<max
; i
++)
346 int len
= load_entry(num_entries
, num_entries
, p
, remaining
);
348 /* Out of name buffer space */
359 viewer
.num_loaded
= num_entries
;
362 /* Load track at playlist index. pos is the position in the tracks array and
363 p is a pointer to the name buffer (max size), Returns -1 if buffer is
365 static int load_entry(int index
, int pos
, char* p
, int size
)
367 struct playlist_track_info info
;
371 /* Playlist viewer orders songs based on display index. We need to
372 convert to real playlist index to access track */
373 index
= (index
+ playlist_get_first_index(viewer
.playlist
)) %
375 if (playlist_get_track_info(viewer
.playlist
, index
, &info
) < 0)
378 len
= strlen(info
.filename
) + 1;
382 strcpy(p
, info
.filename
);
384 tracks
[pos
].name
= p
;
385 tracks
[pos
].index
= info
.index
;
386 tracks
[pos
].display_index
= info
.display_index
;
387 tracks
[pos
].queued
= info
.attr
& PLAYLIST_ATTR_QUEUED
;
397 /* Format trackname for display purposes */
398 static void format_name(char* dest
, char* src
)
400 switch (global_settings
.playlist_viewer_track_display
)
405 /* Only display the mp3 filename */
406 char* p
= strrchr(src
, '/');
412 /* Remove the extension */
413 if (!strcasecmp(&dest
[len
-4], ".mp3") ||
414 !strcasecmp(&dest
[len
-4], ".mp2") ||
415 !strcasecmp(&dest
[len
-4], ".mpa"))
427 /* Format display line */
428 static void format_line(struct playlist_entry
* track
, char* str
, int len
)
432 format_name(name
, track
->name
);
434 if (global_settings
.playlist_viewer_indices
)
435 /* Display playlist index */
436 snprintf(str
, len
, "%d. %s", track
->display_index
, name
);
438 snprintf(str
, len
, "%s", name
);
442 /* Display tracks on screen */
443 static void display_playlist(void)
446 int num_display_tracks
=
447 viewer
.last_display_index
- viewer
.first_display_index
;
451 #ifdef HAVE_LCD_BITMAP
452 lcd_setmargins(MARGIN_X
, MARGIN_Y
);
453 lcd_setfont(FONT_UI
);
456 for (i
=0; i
<=num_display_tracks
; i
++)
458 if (global_settings
.playlist_viewer_icons
)
461 if (tracks
[INDEX(i
)].index
== viewer
.current_playing_track
)
463 /* Current playing track */
464 #ifdef HAVE_LCD_BITMAP
466 if ( viewer
.line_height
> 8 )
467 offset
= (viewer
.line_height
- 8) / 2;
468 lcd_bitmap(bitmap_icons_6x8
[File
],
469 CURSOR_X
* 6 + CURSOR_WIDTH
,
470 MARGIN_Y
+(i
*viewer
.line_height
) + offset
,
473 lcd_putc(LINE_X
-1, i
, File
);
476 else if (tracks
[INDEX(i
)].index
== viewer
.move_track
)
478 /* Track we are moving */
479 #ifdef HAVE_LCD_BITMAP
480 lcd_putsxy(CURSOR_X
* 6 + CURSOR_WIDTH
,
481 MARGIN_Y
+(i
*viewer
.line_height
), "M");
483 lcd_putc(LINE_X
-1, i
, 'M');
486 else if (tracks
[INDEX(i
)].queued
)
489 #ifdef HAVE_LCD_BITMAP
490 lcd_putsxy(CURSOR_X
* 6 + CURSOR_WIDTH
,
491 MARGIN_Y
+(i
*viewer
.line_height
), "Q");
493 lcd_putc(LINE_X
-1, i
, 'Q');
498 update_display_line(i
, false);
501 #ifdef HAVE_LCD_BITMAP
502 if (global_settings
.scrollbar
&&
503 (viewer
.num_tracks
> viewer
.num_display_lines
))
504 scrollbar(SCROLLBAR_X
, SCROLLBAR_Y
, SCROLLBAR_WIDTH
- 1,
505 LCD_HEIGHT
- SCROLLBAR_Y
, viewer
.num_tracks
-1,
506 viewer
.first_display_index
, viewer
.last_display_index
,
510 put_cursorxy(CURSOR_X
, CURSOR_Y
+ viewer
.cursor_pos
, true);
514 /* Scroll cursor or display by num lines */
515 static void scroll_display(int lines
)
517 int new_index
= viewer
.first_display_index
+ viewer
.cursor_pos
+ lines
;
518 bool pagescroll
= false;
521 put_cursorxy(CURSOR_X
, CURSOR_Y
+ viewer
.cursor_pos
, false);
523 if (lines
> 1 || lines
< -1)
528 /* Wrap around if not pageup */
533 new_index
+= viewer
.num_tracks
;
534 viewer
.cursor_pos
= viewer
.num_display_lines
-1;
538 else if (new_index
>= viewer
.num_tracks
)
540 /* Wrap around if not pagedown */
542 new_index
= viewer
.num_tracks
- 1;
545 new_index
-= viewer
.num_tracks
;
546 viewer
.cursor_pos
= 0;
551 if (new_index
>= viewer
.first_display_index
&&
552 new_index
<= viewer
.last_display_index
)
554 /* Just update the cursor */
555 viewer
.cursor_pos
= new_index
- viewer
.first_display_index
;
559 /* New track is outside of display */
561 viewer
.first_display_index
= new_index
;
563 viewer
.first_display_index
= viewer
.first_display_index
+ lines
;
565 if (viewer
.first_display_index
< 0)
566 viewer
.first_display_index
= 0;
568 viewer
.last_display_index
=
569 viewer
.first_display_index
+ (viewer
.num_display_lines
- 1);
570 if (viewer
.last_display_index
>= viewer
.num_tracks
)
572 /* display as many tracks as possible on screen */
573 if (viewer
.first_display_index
> 0)
575 viewer
.first_display_index
-=
576 (viewer
.last_display_index
- viewer
.num_tracks
+ 1);
577 if (viewer
.first_display_index
< 0)
578 viewer
.first_display_index
= 0;
581 viewer
.last_display_index
= viewer
.num_tracks
- 1;
584 if (viewer
.cursor_pos
>
585 (viewer
.last_display_index
- viewer
.first_display_index
))
587 viewer
.last_display_index
- viewer
.first_display_index
;
589 /* Load more data if needed */
590 if (viewer
.first_display_index
< viewer
.first_index
)
591 load_playlist_entries_r(viewer
.last_display_index
);
592 else if (viewer
.last_display_index
> viewer
.last_index
)
593 load_playlist_entries(viewer
.first_display_index
);
598 put_cursorxy(CURSOR_X
, CURSOR_Y
+ viewer
.cursor_pos
, true);
601 /* Update lcd line. Scroll line if requested */
602 static void update_display_line(int line
, bool scroll
)
604 char str
[MAX_PATH
+ 16];
606 format_line(&tracks
[INDEX(line
)], str
, sizeof(str
));
610 #ifdef HAVE_LCD_BITMAP
611 if (global_settings
.invert_cursor
)
612 lcd_puts_scroll_style(LINE_X
, line
, str
, STYLE_INVERT
);
615 lcd_puts_scroll(LINE_X
, line
, str
);
618 lcd_puts(LINE_X
, line
, str
);
621 /* Update first index, if necessary, to put as much as possible on the
623 static void update_first_index(void)
625 /* viewer.num_tracks may be invalid at this point */
626 int num_tracks
= playlist_amount_ex(viewer
.playlist
);
628 if ((num_tracks
- viewer
.first_display_index
) < viewer
.num_display_lines
)
630 /* Try to display as much as possible */
631 int old_index
= viewer
.first_display_index
;
633 viewer
.first_display_index
= num_tracks
- viewer
.num_display_lines
;
634 if (viewer
.first_display_index
< 0)
635 viewer
.first_display_index
= 0;
637 /* Cursor should still point at current track */
638 viewer
.cursor_pos
+= old_index
- viewer
.first_display_index
;
642 /* Update playlist in case something has changed or forced */
643 static bool update_playlist(bool force
)
645 if (!viewer
.playlist
)
646 playlist_get_resume_info(&viewer
.current_playing_track
);
648 viewer
.current_playing_track
= -1;
650 if (force
|| playlist_amount_ex(viewer
.playlist
) != viewer
.num_tracks
)
655 viewer
.num_tracks
= playlist_amount_ex(viewer
.playlist
);
656 if (viewer
.num_tracks
< 0)
659 index
= viewer
.first_display_index
;
661 load_playlist_entries(index
);
663 if (viewer
.num_loaded
<= 0)
666 viewer
.first_display_index
= viewer
.first_index
;
667 viewer
.last_display_index
=
668 viewer
.first_index
+ viewer
.num_display_lines
- 1;
669 if (viewer
.last_display_index
>= viewer
.num_tracks
)
670 viewer
.last_display_index
= viewer
.num_tracks
- 1;
679 /* Menu of playlist commands. Invoked via ON+PLAY on main viewer screen.
680 Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist
682 static int onplay_menu(int index
)
684 struct menu_item items
[3]; /* increase this if you add entries! */
685 int m
, i
=0, result
, ret
= 0;
686 bool current
= (tracks
[index
].index
== viewer
.current_playing_track
);
688 items
[i
].desc
= str(LANG_REMOVE
);
689 items
[i
].voice_id
= LANG_REMOVE
;
692 items
[i
].desc
= str(LANG_MOVE
);
693 items
[i
].voice_id
= LANG_MOVE
;
696 items
[i
].desc
= str(LANG_FILE_OPTIONS
);
697 items
[i
].voice_id
= LANG_FILE_OPTIONS
;
700 m
= menu_init(items
, i
, NULL
, NULL
, NULL
, NULL
);
701 result
= menu_show(m
);
702 if (result
== MENU_ATTACHED_USB
)
704 else if (result
>= 0)
706 /* Abort current move */
707 viewer
.move_track
= -1;
716 playlist_delete(viewer
.playlist
, tracks
[index
].index
);
720 /* Start playing new track except if it's the last track
721 in the playlist and repeat mode is disabled */
722 if (tracks
[index
].display_index
!= viewer
.num_tracks
||
723 global_settings
.repeat_mode
== REPEAT_ALL
)
725 talk_buffer_steal(); /* will use the mp3 buffer */
727 viewer
.current_playing_track
= -1;
735 viewer
.move_track
= tracks
[index
].index
;
740 onplay(tracks
[index
].name
, TREE_ATTR_MPA
);
742 if (!viewer
.playlist
)
758 /* Menu of viewer options. Invoked via F1(r) or Menu(p). */
759 static bool viewer_menu(void)
764 struct menu_item items
[] = {
765 { STR(LANG_SHOW_ICONS
), show_icons
},
766 { STR(LANG_SHOW_INDICES
), show_indices
},
767 { STR(LANG_TRACK_DISPLAY
), track_display
},
768 { STR(LANG_SAVE_DYNAMIC_PLAYLIST
), save_playlist
},
771 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
773 result
= menu_run(m
);
781 /* Show icons in viewer? */
782 static bool show_icons(void)
784 return set_bool(str(LANG_SHOW_ICONS
),
785 &global_settings
.playlist_viewer_icons
);
788 /* Show indices of tracks? */
789 static bool show_indices(void)
791 return set_bool(str(LANG_SHOW_INDICES
),
792 &global_settings
.playlist_viewer_indices
);
795 /* How to display a track */
796 static bool track_display(void)
798 struct opt_items names
[] = {
799 { STR(LANG_DISPLAY_TRACK_NAME_ONLY
) },
800 { STR(LANG_DISPLAY_FULL_PATH
) }
803 return set_option(str(LANG_TRACK_DISPLAY
),
804 &global_settings
.playlist_viewer_track_display
, INT
, names
, 2, NULL
);
807 /* Save playlist to disk */
808 static bool save_playlist(void)
810 char filename
[MAX_PATH
+1];
812 strncpy(filename
, DEFAULT_PLAYLIST_NAME
, sizeof(filename
));
814 if (!kbd_input(filename
, sizeof(filename
)))
816 playlist_save(viewer
.playlist
, filename
);
818 /* reload in case playlist was saved to cwd */
825 /* View current playlist */
826 bool playlist_viewer(void)
828 return playlist_viewer_ex(NULL
);
831 /* Main viewer function. Filename identifies playlist to be viewed. If NULL,
832 view current playlist. */
833 bool playlist_viewer_ex(char* filename
)
835 bool ret
= false; /* return value */
836 bool exit
=false; /* exit viewer */
837 bool update
=true; /* update display */
838 bool cursor_on
=true; /* used for flashing cursor */
839 int old_cursor_pos
; /* last cursor position */
842 if (!initialize(filename
, false))
845 old_cursor_pos
= viewer
.cursor_pos
;
851 if (!viewer
.playlist
&& !(mpeg_status() & MPEG_STATUS_PLAY
))
853 /* Play has stopped */
854 #ifdef HAVE_LCD_CHARCELLS
855 splash(HZ
, true, str(LANG_END_PLAYLIST_PLAYER
));
857 splash(HZ
, true, str(LANG_END_PLAYLIST_RECORDER
));
859 status_set_playmode(STATUS_STOP
);
863 if (viewer
.move_track
!= -1 || !cursor_on
)
865 /* Flash cursor to identify that we are moving a track */
866 cursor_on
= !cursor_on
;
867 #ifdef HAVE_LCD_BITMAP
868 if (global_settings
.invert_cursor
)
871 MARGIN_X
, MARGIN_Y
+(viewer
.cursor_pos
*viewer
.line_height
),
872 LCD_WIDTH
, viewer
.line_height
);
873 lcd_invertscroll(LINE_X
, viewer
.cursor_pos
);
876 put_cursorxy(CURSOR_X
, CURSOR_Y
+ viewer
.cursor_pos
,
880 0, MARGIN_Y
+ (viewer
.cursor_pos
* viewer
.line_height
),
881 LCD_WIDTH
, viewer
.line_height
);
883 put_cursorxy(CURSOR_X
, CURSOR_Y
+ viewer
.cursor_pos
, cursor_on
);
888 if (!viewer
.playlist
)
889 playlist_get_resume_info(&track
);
893 if (track
!= viewer
.current_playing_track
||
894 playlist_amount_ex(viewer
.playlist
) != viewer
.num_tracks
)
896 /* Playlist has changed (new track started?) */
897 update_first_index();
898 if (!update_playlist(false))
903 /* Abort move on playlist change */
904 viewer
.move_track
= -1;
907 /* Timeout so we can determine if play status has changed */
908 button
= button_get_w_tmo(HZ
/2);
912 #ifdef HAVE_RECORDER_KEYPAD
921 #ifdef HAVE_RECORDER_KEYPAD
923 case BUTTON_UP
| BUTTON_REPEAT
:
926 case BUTTON_LEFT
| BUTTON_REPEAT
:
932 #ifdef HAVE_RECORDER_KEYPAD
934 case BUTTON_DOWN
| BUTTON_REPEAT
:
937 case BUTTON_RIGHT
| BUTTON_REPEAT
:
944 #ifdef HAVE_RECORDER_KEYPAD
945 case BUTTON_ON
| BUTTON_UP
:
946 case BUTTON_ON
| BUTTON_UP
| BUTTON_REPEAT
:
948 case BUTTON_ON
| BUTTON_LEFT
:
949 case BUTTON_ON
| BUTTON_LEFT
| BUTTON_REPEAT
:
952 scroll_display(-viewer
.num_display_lines
);
956 #ifdef HAVE_RECORDER_KEYPAD
957 case BUTTON_ON
| BUTTON_DOWN
:
958 case BUTTON_ON
| BUTTON_DOWN
| BUTTON_REPEAT
:
960 case BUTTON_ON
| BUTTON_RIGHT
:
961 case BUTTON_ON
| BUTTON_RIGHT
| BUTTON_REPEAT
:
964 scroll_display(viewer
.num_display_lines
);
967 #endif /* BUTTON_ON */
969 #ifdef HAVE_RECORDER_KEYPAD
973 if (viewer
.move_track
>= 0)
978 ret
= playlist_move(viewer
.playlist
, viewer
.move_track
,
979 tracks
[INDEX(viewer
.cursor_pos
)].index
);
981 splash(HZ
, true, str(LANG_MOVE_FAILED
));
983 update_playlist(true);
984 viewer
.move_track
= -1;
986 else if (!viewer
.playlist
)
988 /* Stop current track and play new track */
990 playlist_start(tracks
[INDEX(viewer
.cursor_pos
)].index
, 0);
991 status_set_playmode(STATUS_PLAY
);
992 update_playlist(false);
996 /* Play track from playlist on disk */
1000 if (playlist_set_current(viewer
.playlist
) < 0)
1003 playlist_start(tracks
[INDEX(viewer
.cursor_pos
)].index
, 0);
1004 status_set_playmode(STATUS_PLAY
);
1006 /* Our playlist is now the current list */
1007 if (!initialize(NULL
, true))
1016 case BUTTON_ON
| BUTTON_PLAY
:
1021 ret
= onplay_menu(INDEX(viewer
.cursor_pos
));
1030 /* Playlist changed */
1031 update_first_index();
1032 update_playlist(false);
1033 if (viewer
.num_tracks
<= 0)
1042 #endif /* BUTTON_ON */
1043 #ifdef HAVE_RECORDER_KEYPAD
1058 case SYS_USB_CONNECTED
:
1069 if (update
&& !exit
)
1073 if (viewer
.cursor_pos
>
1074 (viewer
.last_display_index
- viewer
.first_display_index
))
1076 /* Cursor position is invalid */
1077 put_cursorxy(CURSOR_X
, CURSOR_Y
+ viewer
.cursor_pos
, false);
1079 viewer
.last_display_index
- viewer
.first_display_index
;
1080 put_cursorxy(CURSOR_X
, CURSOR_Y
+ viewer
.cursor_pos
, true);
1083 if (viewer
.cursor_pos
!= old_cursor_pos
&&
1085 (viewer
.last_display_index
- viewer
.first_display_index
))
1086 /* Stop scrolling previous line */
1087 update_display_line(old_cursor_pos
, false);
1089 /* Scroll line at new cursor position */
1090 update_display_line(viewer
.cursor_pos
, true);
1094 old_cursor_pos
= viewer
.cursor_pos
;
1101 if (viewer
.playlist
)
1102 playlist_close(viewer
.playlist
);