📄 playlist_viewer.c
字号:
/*************************************************************************** * * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: playlist_viewer.c,v 1.7 2004/02/01 04:35:28 hardeeps Exp $ * * Copyright (C) 2003 Hardeep Sidhu * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/#include <string.h>#include <sprintf.h>#include "playlist.h"#include "mpeg.h"#include "screens.h"#include "status.h"#include "settings.h"#include "icons.h"#include "menu.h"#include "plugin.h"#include "keyboard.h"#include "tree.h"#include "onplay.h"#ifdef HAVE_LCD_BITMAP#include "widgets.h"#endif#include "lang.h"#include "playlist_viewer.h"/* Defines for LCD display purposes. Taken from tree.c */#ifdef HAVE_LCD_BITMAP #define CURSOR_X (global_settings.scrollbar && \ viewer.num_tracks>viewer.num_display_lines?1:0) #define CURSOR_Y 0 #define CURSOR_WIDTH (global_settings.invert_cursor ? 0 : 4) #define ICON_WIDTH ((viewer.char_width > 6) ? viewer.char_width : 6) #define MARGIN_X ((global_settings.scrollbar && \ viewer.num_tracks > viewer.num_display_lines ? \ SCROLLBAR_WIDTH : 0) + CURSOR_WIDTH + \ (global_settings.playlist_viewer_icons ? \ ICON_WIDTH : 0)) #define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0) #define LINE_X 0 #define LINE_Y (global_settings.statusbar ? 1 : 0) #define SCROLLBAR_X 0 #define SCROLLBAR_Y lcd_getymargin() #define SCROLLBAR_WIDTH 6#else #define MARGIN_X 0 #define MARGIN_Y 0 #define LINE_X 2 #define LINE_Y 0 #define CURSOR_X 0 #define CURSOR_Y 0#endif/* Maximum number of tracks we can have loaded at one time */#define MAX_PLAYLIST_ENTRIES 200/* Default playlist name for saving */#define DEFAULT_PLAYLIST_NAME "/viewer.m3u"/* Index of track on display line _pos */#define INDEX(_pos) (viewer.first_display_index - viewer.first_index + (_pos))/* Global playlist viewer settings */struct playlist_viewer_info { struct playlist_info* playlist; /* playlist being viewed */ char *name_buffer; /* Buffer used to store track names */ int buffer_size; /* Size of name buffer */ int num_display_lines; /* Number of lines on lcd */ int line_height; /* Height (in pixels) of display line */ int char_width; /* Width (in pixels) of a character */ int num_tracks; /* Number of tracks in playlist */ int current_playing_track; /* Index of current playing track */ int num_loaded; /* Number of track entries loaded in viewer */ int first_index; /* Index of first loaded track */ int last_index; /* Index of last loaded track */ int first_display_index; /* Index of first track on display */ int last_display_index; /* Index of last track on display */ int cursor_pos; /* Line number of cursor */ int move_track; /* Playlist index of track to move or -1 */};/* Information about a specific track */struct playlist_entry { char *name; /* Formatted track name */ int index; /* Playlist index */ int display_index; /* Display index */ bool queued; /* Is track queued? */};static struct playlist_viewer_info viewer;static struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES];/* Used when viewing playlists on disk */static struct playlist_info temp_playlist;#ifdef HAVE_LCD_BITMAPextern unsigned char bitmap_icons_6x8[LastIcon][6];#endifstatic bool initialize(char* filename, bool reload);static void load_playlist_entries(int start_index);static void load_playlist_entries_r(int end_index);static int load_entry(int index, int pos, char* p, int size);static void format_name(char* dest, char* src);static void format_line(struct playlist_entry* track, char* str, int len);static void display_playlist(void);static void update_display_line(int line, bool scroll);static void scroll_display(int lines);static void update_first_index(void);static bool update_playlist(bool force);#ifdef BUTTON_ONstatic int onplay_menu(int index);#endifstatic bool viewer_menu(void);static bool show_icons(void);static bool show_indices(void);static bool track_display(void);static bool save_playlist(void);/* Initialize the playlist viewer. */static bool initialize(char* filename, bool reload){ char* buffer; int buffer_size; bool is_playing = mpeg_status() & MPEG_STATUS_PLAY; if (!filename && !is_playing) /* Nothing is playing, exit */ return false; buffer = plugin_get_buffer(&buffer_size); if (!buffer) return false; if (!filename) viewer.playlist = NULL; else { /* Viewing playlist on disk */ char *dir, *file, *temp_ptr; char *index_buffer = NULL; int index_buffer_size = 0; viewer.playlist = &temp_playlist; /* Separate directory from filename */ temp_ptr = strrchr(filename+1,'/'); if (temp_ptr) { *temp_ptr = 0; dir = filename; file = temp_ptr + 1; } else { dir = "/"; file = filename+1; } if (is_playing) { /* Something is playing, use half the plugin buffer for playlist indices */ index_buffer_size = buffer_size / 2; index_buffer = buffer; } playlist_create_ex(viewer.playlist, dir, file, index_buffer, index_buffer_size, buffer+index_buffer_size, buffer_size-index_buffer_size); if (temp_ptr) *temp_ptr = '/'; buffer += index_buffer_size; buffer_size -= index_buffer_size; } viewer.name_buffer = buffer; viewer.buffer_size = buffer_size;#ifdef HAVE_LCD_BITMAP { char icon_chars[] = "MQ"; /* characters used as icons */ unsigned int i; viewer.char_width = 0; viewer.line_height = 0; /* Use icon characters to calculate largest possible width/height so that we set proper margins */ for (i=0; i<sizeof(icon_chars); i++) { char str[2]; int w, h; snprintf(str, sizeof(str), "%c", icon_chars[i]); lcd_getstringsize(str, &w, &h); if (w > viewer.char_width) viewer.char_width = w; if (h > viewer.line_height) { viewer.line_height = h; viewer.num_display_lines = (LCD_HEIGHT - MARGIN_Y)/h; } } }#else viewer.num_display_lines = 2; viewer.char_width = 1; viewer.line_height = 1;#endif viewer.move_track = -1; if (!reload) { viewer.cursor_pos = 0; if (!viewer.playlist) /* Start displaying at current playing track */ viewer.first_display_index = playlist_get_display_index() - 1; else viewer.first_display_index = 0; update_first_index(); } if (!update_playlist(true)) return false; return true;}/* Load tracks starting at start_index */static void load_playlist_entries(int start_index){ int num_entries = viewer.num_tracks - start_index; char* p = viewer.name_buffer; int remaining = viewer.buffer_size; int i; viewer.first_index = start_index; if (num_entries > MAX_PLAYLIST_ENTRIES) num_entries = MAX_PLAYLIST_ENTRIES; for(i=0; i<num_entries; i++, start_index++) { int len = load_entry(start_index, i, p, remaining); if (len < 0) { /* Out of name buffer space */ num_entries = i; break; } p += len; remaining -= len; } viewer.num_loaded = num_entries; viewer.last_index = viewer.first_index + (viewer.num_loaded - 1);}/* Load tracks in reverse, ending at end_index */static void load_playlist_entries_r(int end_index){ int num_entries = end_index; char* p = viewer.name_buffer; int remaining = viewer.buffer_size; int i; viewer.last_index = end_index; if (num_entries >= MAX_PLAYLIST_ENTRIES) num_entries = MAX_PLAYLIST_ENTRIES-1; for(i=num_entries; i>=0; i--, end_index--) { int len = load_entry(end_index, i, p, remaining); if (len < 0) { int j; /* Out of name buffer space */ num_entries -= i; /* Shift loaded tracks up such that first track is index 0 */ for (j=0; j<num_entries; j++, i++) { tracks[j].name = tracks[i].name; tracks[j].index = tracks[i].index; tracks[j].display_index = tracks[i].display_index; tracks[j].queued = tracks[i].queued; } break; } p += len; remaining -= len; } viewer.first_index = viewer.last_index - num_entries; num_entries++; if (!viewer.first_index && num_entries < viewer.num_tracks && num_entries < MAX_PLAYLIST_ENTRIES) { /* Lets see if we can load more data at the end of the list */ int max = viewer.num_tracks; if (max > MAX_PLAYLIST_ENTRIES) max = MAX_PLAYLIST_ENTRIES; for (i = num_entries; i<max; i++) { int len = load_entry(num_entries, num_entries, p, remaining); if (len < 0) /* Out of name buffer space */ break; p += len; remaining -= len; num_entries++; viewer.last_index++; } } viewer.num_loaded = num_entries;}/* Load track at playlist index. pos is the position in the tracks array and p is a pointer to the name buffer (max size), Returns -1 if buffer is full. */static int load_entry(int index, int pos, char* p, int size){ struct playlist_track_info info; int len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -