📄 playlist_viewer.c
字号:
int result = 0; /* Playlist viewer orders songs based on display index. We need to convert to real playlist index to access track */ index = (index + playlist_get_first_index(viewer.playlist)) % viewer.num_tracks; if (playlist_get_track_info(viewer.playlist, index, &info) < 0) return -1; len = strlen(info.filename) + 1; if (len <= size) { strcpy(p, info.filename); tracks[pos].name = p; tracks[pos].index = info.index; tracks[pos].display_index = info.display_index; tracks[pos].queued = info.attr & PLAYLIST_ATTR_QUEUED; result = len; } else result = -1; return result;}/* Format trackname for display purposes */static void format_name(char* dest, char* src){ switch (global_settings.playlist_viewer_track_display) { case 0: default: { /* Only display the mp3 filename */ char* p = strrchr(src, '/'); int len; strcpy(dest, p+1); len = strlen(dest); /* Remove the extension */ if (!strcasecmp(&dest[len-4], ".mp3") || !strcasecmp(&dest[len-4], ".mp2") || !strcasecmp(&dest[len-4], ".mpa")) dest[len-4] = '\0'; break; } case 1: /* Full path */ strcpy(dest, src); break; }}/* Format display line */static void format_line(struct playlist_entry* track, char* str, int len){ char name[MAX_PATH]; format_name(name, track->name); if (global_settings.playlist_viewer_indices) /* Display playlist index */ snprintf(str, len, "%d. %s", track->display_index, name); else snprintf(str, len, "%s", name);}/* Display tracks on screen */static void display_playlist(void){ int i; int num_display_tracks = viewer.last_display_index - viewer.first_display_index; lcd_clear_display();#ifdef HAVE_LCD_BITMAP lcd_setmargins(MARGIN_X, MARGIN_Y); lcd_setfont(FONT_UI);#endif for (i=0; i<=num_display_tracks; i++) { if (global_settings.playlist_viewer_icons) { /* Icons */ if (tracks[INDEX(i)].index == viewer.current_playing_track) { /* Current playing track */#ifdef HAVE_LCD_BITMAP int offset=0; if ( viewer.line_height > 8 ) offset = (viewer.line_height - 8) / 2; lcd_bitmap(bitmap_icons_6x8[File], CURSOR_X * 6 + CURSOR_WIDTH, MARGIN_Y+(i*viewer.line_height) + offset, 6, 8, true);#else lcd_putc(LINE_X-1, i, File);#endif } else if (tracks[INDEX(i)].index == viewer.move_track) { /* Track we are moving */#ifdef HAVE_LCD_BITMAP lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, MARGIN_Y+(i*viewer.line_height), "M");#else lcd_putc(LINE_X-1, i, 'M');#endif } else if (tracks[INDEX(i)].queued) { /* Queued track */#ifdef HAVE_LCD_BITMAP lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, MARGIN_Y+(i*viewer.line_height), "Q");#else lcd_putc(LINE_X-1, i, 'Q');#endif } } update_display_line(i, false); }#ifdef HAVE_LCD_BITMAP if (global_settings.scrollbar && (viewer.num_tracks > viewer.num_display_lines)) scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1, LCD_HEIGHT - SCROLLBAR_Y, viewer.num_tracks-1, viewer.first_display_index, viewer.last_display_index, VERTICAL);#endif put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, true); status_draw(true);}/* Scroll cursor or display by num lines */static void scroll_display(int lines){ int new_index = viewer.first_display_index + viewer.cursor_pos + lines; bool pagescroll = false; bool wrap = false; put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, false); if (lines > 1 || lines < -1) pagescroll = true; if (new_index < 0) { /* Wrap around if not pageup */ if (pagescroll) new_index = 0; else { new_index += viewer.num_tracks; viewer.cursor_pos = viewer.num_display_lines-1; wrap = true; } } else if (new_index >= viewer.num_tracks) { /* Wrap around if not pagedown */ if (pagescroll) new_index = viewer.num_tracks - 1; else { new_index -= viewer.num_tracks; viewer.cursor_pos = 0; wrap = true; } } if (new_index >= viewer.first_display_index && new_index <= viewer.last_display_index) { /* Just update the cursor */ viewer.cursor_pos = new_index - viewer.first_display_index; } else { /* New track is outside of display */ if (wrap) viewer.first_display_index = new_index; else viewer.first_display_index = viewer.first_display_index + lines; if (viewer.first_display_index < 0) viewer.first_display_index = 0; viewer.last_display_index = viewer.first_display_index + (viewer.num_display_lines - 1); if (viewer.last_display_index >= viewer.num_tracks) { /* display as many tracks as possible on screen */ if (viewer.first_display_index > 0) { viewer.first_display_index -= (viewer.last_display_index - viewer.num_tracks + 1); if (viewer.first_display_index < 0) viewer.first_display_index = 0; } viewer.last_display_index = viewer.num_tracks - 1; } if (viewer.cursor_pos > (viewer.last_display_index - viewer.first_display_index)) viewer.cursor_pos = viewer.last_display_index - viewer.first_display_index; /* Load more data if needed */ if (viewer.first_display_index < viewer.first_index) load_playlist_entries_r(viewer.last_display_index); else if (viewer.last_display_index > viewer.last_index) load_playlist_entries(viewer.first_display_index); display_playlist(); } put_cursorxy(CURSOR_X, CURSOR_Y + viewer.cursor_pos, true);}/* Update lcd line. Scroll line if requested */static void update_display_line(int line, bool scroll){ char str[MAX_PATH + 16]; format_line(&tracks[INDEX(line)], str, sizeof(str)); if (scroll) {#ifdef HAVE_LCD_BITMAP if (global_settings.invert_cursor) lcd_puts_scroll_style(LINE_X, line, str, STYLE_INVERT); else#endif lcd_puts_scroll(LINE_X, line, str); } else lcd_puts(LINE_X, line, str);}/* Update first index, if necessary, to put as much as possible on the screen */static void update_first_index(void){ /* viewer.num_tracks may be invalid at this point */ int num_tracks = playlist_amount_ex(viewer.playlist); if ((num_tracks - viewer.first_display_index) < viewer.num_display_lines) { /* Try to display as much as possible */ int old_index = viewer.first_display_index; viewer.first_display_index = num_tracks - viewer.num_display_lines; if (viewer.first_display_index < 0) viewer.first_display_index = 0; /* Cursor should still point at current track */ viewer.cursor_pos += old_index - viewer.first_display_index; }}/* Update playlist in case something has changed or forced */static bool update_playlist(bool force){ if (!viewer.playlist) playlist_get_resume_info(&viewer.current_playing_track); else viewer.current_playing_track = -1; if (force || playlist_amount_ex(viewer.playlist) != viewer.num_tracks) { int index; /* Reload tracks */ viewer.num_tracks = playlist_amount_ex(viewer.playlist); if (viewer.num_tracks < 0) return false; index = viewer.first_display_index; load_playlist_entries(index); if (viewer.num_loaded <= 0) return false; viewer.first_display_index = viewer.first_index; viewer.last_display_index = viewer.first_index + viewer.num_display_lines - 1; if (viewer.last_display_index >= viewer.num_tracks) viewer.last_display_index = viewer.num_tracks - 1; } display_playlist(); return true;}#ifdef BUTTON_ON/* Menu of playlist commands. Invoked via ON+PLAY on main viewer screen. Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist changed. */static int onplay_menu(int index){ struct menu_items menu[3]; /* increase this if you add entries! */ int m, i=0, result, ret = 0; bool current = (tracks[index].index == viewer.current_playing_track); menu[i].desc = str(LANG_REMOVE); i++; menu[i].desc = str(LANG_MOVE); i++; menu[i].desc = str(LANG_FILE_OPTIONS); i++; m = menu_init(menu, i); result = menu_show(m); if (result == MENU_ATTACHED_USB) ret = -1; else if (result >= 0) { /* Abort current move */ viewer.move_track = -1; switch (result) { case 0: /* delete track */ if (current) mpeg_stop(); playlist_delete(viewer.playlist, tracks[index].index); if (current) { /* Start playing new track except if it's the last track in the playlist and repeat mode is disabled */ if (tracks[index].display_index != viewer.num_tracks || global_settings.repeat_mode == REPEAT_ALL) { mpeg_play(0); viewer.current_playing_track = -1; } } ret = 1; break; case 1: /* move track */ viewer.move_track = tracks[index].index; ret = 0; break; case 2: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -