Code

Added support for (auto) center/focus playlists.
[ncmpc.git] / screen_play.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <glib.h>
4 #include <ncurses.h>
6 #include "config.h"
7 #include "options.h"
8 #include "support.h"
9 #include "libmpdclient.h"
10 #include "mpc.h"
11 #include "command.h"
12 #include "screen.h"
13 #include "screen_utils.h"
14 #include "screen_file.h"
15 #include "screen_play.h"
18 #define BUFSIZE 256
20 static char *
21 list_callback(int index, int *highlight, void *data)
22 {
23   mpd_client_t *c = (mpd_client_t *) data;
24   mpd_Song *song;
26   *highlight = 0;
27   if( (song=mpc_playlist_get_song(c, index)) == NULL )
28     {
29       return NULL;
30     }
32   if( IS_PLAYING(c->status->state) && index==c->song_id )
33     {
34       *highlight = 1;
35     }
37   return mpc_get_song_name(song);
38 }
40 static int
41 center_playing_item(screen_t *screen, mpd_client_t *c)
42 {
43   list_window_t *lw = screen->playlist;
44   int length = c->playlist_length;
45   int offset = lw->selected-lw->start;
46   
47   if( !lw || length<lw->rows || !IS_PLAYING(c->status->state) )
48     return 0;
50   /* try to center the song that are playing */
51   lw->start = c->song_id-(lw->rows/2);
52   if( lw->start+lw->rows > length )
53     lw->start = length-lw->rows;
54   if( lw->start<0 )
55     lw->start=0;
57   /* make sure the cursor is in the window */
58   lw->selected = lw->start+offset;
59   list_window_check_selected(lw, length);
61   lw->clear = 1;
62   lw->repaint = 1;
64   return 0;
65 }
67 static int
68 handle_save_playlist(screen_t *screen, mpd_client_t *c)
69 {
70   char *filename, *filename_utf8;
72   filename=screen_getstr(screen->status_window.w, "Save playlist as: ");
73   filename=trim(filename);
74   if( filename==NULL || filename[0]=='\0' )
75     return -1;
76   /* convert filename to utf-8 */
77   filename_utf8 = locale_to_utf8(filename);
78   /* send save command to mpd */
79   mpd_sendSaveCommand(c->connection, filename_utf8);
80   mpd_finishCommand(c->connection);
81   g_free(filename_utf8);
82   /* handle errors */
83   if( mpc_error(c))
84     {
85       if(  mpc_error_str(c) )
86         {
87           char *str = utf8_to_locale(mpc_error_str(c));
88           screen_status_message(str);
89           g_free(str);
90         }
91       else
92         screen_status_printf("Error: Unable to save playlist as %s", filename);
93       mpd_clearError(c->connection);
94       beep();
95       return -1;
96     }
97   /* success */
98   screen_status_printf("Saved %s", filename);
99   g_free(filename);
100   /* update the file list if it has been initalized */
101   if( c->filelist )
102     {
103       mpc_update_filelist(c);
104       list_window_check_selected(screen->filelist, c->filelist_length);
105     }
106   return 0;
109 void 
110 play_open(screen_t *screen, mpd_client_t *c)
115 void 
116 play_close(screen_t *screen, mpd_client_t *c)
120 void
121 play_paint(screen_t *screen, mpd_client_t *c)
123   list_window_t *w = screen->playlist;
124  
125   w->clear = 1;
126   
127   list_window_paint(screen->playlist, list_callback, (void *) c);
128   wnoutrefresh(screen->playlist->w);
131 void
132 play_update(screen_t *screen, mpd_client_t *c)
134   if( options.auto_center )
135     {
136       static int prev_song_id = 0;
137       
138       if( prev_song_id != c->song_id )  
139         {
140           center_playing_item(screen, c);
141           prev_song_id = c->song_id;
142         }
143     }
145   if( c->playlist_updated )
146     {
147       if( screen->playlist->selected >= c->playlist_length )
148         screen->playlist->selected = c->playlist_length-1;
149       if( screen->playlist->start    >= c->playlist_length )
150         list_window_reset(screen->playlist);
152       play_paint(screen, c);
153       c->playlist_updated = 0;
154     }
155   else if( screen->playlist->repaint || 1)
156     {
157       list_window_paint(screen->playlist, list_callback, (void *) c);
158       wnoutrefresh(screen->playlist->w);
159       screen->playlist->repaint = 0;
160     }
163 int
164 play_cmd(screen_t *screen, mpd_client_t *c, command_t cmd)
166   mpd_Song *song;
168   switch(cmd)
169     {
170     case CMD_DELETE:
171       song = mpc_playlist_get_song(c, screen->playlist->selected);
172       if( song )
173         {
174           file_clear_highlight(c, song);
175           mpd_sendDeleteCommand(c->connection, screen->playlist->selected);
176           mpd_finishCommand(c->connection);
177           screen_status_printf("Removed \'%s\' from playlist!",
178                                mpc_get_song_name(song));
179         }
180       return 1;
181     case CMD_SAVE_PLAYLIST:
182       handle_save_playlist(screen, c);
183       return 1;
184     case CMD_SCREEN_UPDATE:
185       center_playing_item(screen, c);
186       return 1;
187     case CMD_LIST_FIND:
188     case CMD_LIST_RFIND:
189     case CMD_LIST_FIND_NEXT:
190     case CMD_LIST_RFIND_NEXT:
191       return screen_find(screen, c, 
192                          screen->playlist, c->playlist_length,
193                          cmd, list_callback);
194     default:
195       break;
196     }
197   return list_window_cmd(screen->playlist, c->playlist_length, cmd) ;