X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_queue.c;h=c8fad68d2c7e52e2cf126a7aae6312ac094d7b51;hb=6c29c9b2dc0aab7c7273b093609edcc175510df7;hp=0381d52a0dbdeefb9fb0b2cbe0619feb2cc97360;hpb=13540f17f76eed4e0e3bbbde0c6cb538470e5c69;p=ncmpc.git diff --git a/src/screen_queue.c b/src/screen_queue.c index 0381d52..c8fad68 100644 --- a/src/screen_queue.c +++ b/src/screen_queue.c @@ -1,5 +1,5 @@ /* ncmpc (Ncurses MPD Client) - * (c) 2004-2009 The Music Player Daemon Project + * (c) 2004-2010 The Music Player Daemon Project * Project homepage: http://musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -30,7 +30,7 @@ #include "utils.h" #include "strfsong.h" #include "wreadln.h" -#include "colors.h" +#include "song_paint.h" #include "screen.h" #include "screen_utils.h" #include "screen_song.h" @@ -57,7 +57,6 @@ typedef struct } completion_callback_data_t; static struct hscroll hscroll; -static guint scroll_source_id; #endif static struct mpdclient_playlist *playlist; @@ -118,21 +117,8 @@ screen_queue_restore_selection(void) screen_queue_save_selection(); } -#ifndef NCMPC_MINI -static gboolean -scroll_timer_callback(G_GNUC_UNUSED gpointer data) -{ - scroll_source_id = 0; - - hscroll_step(&hscroll); - screen_queue_repaint(); - return false; -} -#endif - static const char * -screen_queue_lw_callback(unsigned idx, bool *highlight, char **second_column, - G_GNUC_UNUSED void *data) +screen_queue_lw_callback(unsigned idx, G_GNUC_UNUSED void *data) { static char songname[MAX_SONG_LENGTH]; struct mpd_song *song; @@ -141,83 +127,27 @@ screen_queue_lw_callback(unsigned idx, bool *highlight, char **second_column, assert(idx < playlist_length(playlist)); song = playlist_get(playlist, idx); - if ((int)mpd_song_get_id(song) == current_song_id) - *highlight = true; strfsong(songname, MAX_SONG_LENGTH, options.list_format, song); -#ifndef NCMPC_MINI - if (second_column != NULL && mpd_song_get_duration(song) > 0) { - char duration[32]; - format_duration_short(duration, sizeof(duration), - mpd_song_get_duration(song)); - *second_column = g_strdup(duration); - } - - if (idx == lw->selected) - { - int second_column_len = 0; - if (second_column != NULL && *second_column != NULL) - second_column_len = strlen(*second_column); - if (options.scroll && utf8_width(songname) > (unsigned)(COLS - second_column_len - 1) ) - { - static unsigned current_song; - char *tmp; - - if (current_song != lw->selected) { - hscroll_reset(&hscroll); - current_song = lw->selected; - } - - tmp = strscroll(&hscroll, songname, options.scroll_sep, - MAX_SONG_LENGTH); - g_strlcpy(songname, tmp, MAX_SONG_LENGTH); - g_free(tmp); - - if (scroll_source_id == 0) - scroll_source_id = - g_timeout_add(1000, - scroll_timer_callback, - NULL); - } else { - hscroll_reset(&hscroll); - - if (scroll_source_id != 0) { - g_source_remove(scroll_source_id); - scroll_source_id = 0; - } - } - } -#else - (void)second_column; -#endif - return songname; } static void -center_playing_item(struct mpdclient *c, bool center_cursor) +center_playing_item(const struct mpd_status *status, bool center_cursor) { - const struct mpd_song *song; - unsigned length = c->playlist.list->len; int idx; - song = mpdclient_get_current_song(c); - if (song == NULL) + if (status == NULL || + (mpd_status_get_state(status) != MPD_STATE_PLAY && + mpd_status_get_state(status) != MPD_STATE_PAUSE)) return; /* try to center the song that are playing */ - idx = playlist_get_index(&c->playlist, c->song); + idx = mpd_status_get_song_pos(status); if (idx < 0) return; - if (length < lw->rows) - { - if (center_cursor) - list_window_set_cursor(lw, idx); - return; - } - list_window_center(lw, idx); if (center_cursor) { @@ -229,6 +159,32 @@ center_playing_item(struct mpdclient *c, bool center_cursor) list_window_fetch_cursor(lw); } +G_GNUC_PURE +static int +get_current_song_id(const struct mpd_status *status) +{ + return status != NULL && + (mpd_status_get_state(status) == MPD_STATE_PLAY || + mpd_status_get_state(status) == MPD_STATE_PAUSE) + ? (int)mpd_status_get_song_id(status) + : -1; +} + +static bool +screen_queue_song_change(const struct mpd_status *status) +{ + if (get_current_song_id(status) == current_song_id) + return false; + + current_song_id = get_current_song_id(status); + + /* center the cursor */ + if (options.auto_center && !lw->range_selection) + center_playing_item(status, false); + + return true; +} + #ifndef NCMPC_MINI static void save_pre_completion_cb(GCompletion *gcmp, G_GNUC_UNUSED gchar *line, @@ -319,9 +275,11 @@ playlist_save(struct mpdclient *c, char *name, char *defaultname) /* send save command to mpd */ - filename_utf8 = locale_to_utf8(filename); - connection = mpdclient_get_connection(c); + if (connection == NULL) + return -1; + + filename_utf8 = locale_to_utf8(filename); if (!mpd_run_save(connection, filename_utf8)) { if (mpd_connection_get_error(connection) == MPD_ERROR_SERVER && mpd_connection_get_server_error(connection) == MPD_SERVER_ERROR_EXIST && @@ -418,8 +376,8 @@ static int handle_add_to_playlist(struct mpdclient *c) { gchar *path; -#ifndef NCMPC_MINI GCompletion *gcmp; +#ifndef NCMPC_MINI GList *list = NULL; GList *dir_list = NULL; completion_callback_data_t data; @@ -433,18 +391,15 @@ handle_add_to_playlist(struct mpdclient *c) wrln_completion_callback_data = &data; wrln_pre_completion_callback = add_pre_completion_cb; wrln_post_completion_callback = add_post_completion_cb; +#else + gcmp = NULL; #endif /* get path */ path = screen_readln(_("Add"), NULL, NULL, -#ifdef NCMPC_MINI - NULL -#else - gcmp -#endif - ); + gcmp); /* destroy completion data */ #ifndef NCMPC_MINI @@ -471,6 +426,11 @@ static void screen_queue_init(WINDOW *w, int cols, int rows) { lw = list_window_init(w, cols, rows); + +#ifndef NCMPC_MINI + if (options.scroll) + hscroll_init(&hscroll, w, options.scroll_sep); +#endif } static gboolean @@ -509,6 +469,7 @@ screen_queue_open(struct mpdclient *c) } screen_queue_restore_selection(); + screen_queue_song_change(c->status); } static void @@ -518,6 +479,11 @@ screen_queue_close(void) g_source_remove(timer_hide_cursor_id); timer_hide_cursor_id = 0; } + +#ifndef NCMPC_MINI + if (options.scroll) + hscroll_clear(&hscroll); +#endif } static void @@ -543,38 +509,58 @@ screen_queue_title(char *str, size_t size) return str; } +static void +screen_queue_paint_callback(WINDOW *w, unsigned i, + unsigned y, unsigned width, + bool selected, G_GNUC_UNUSED void *data) +{ + const struct mpd_song *song; + struct hscroll *row_hscroll; + + assert(playlist != NULL); + assert(i < playlist_length(playlist)); + + song = playlist_get(playlist, i); + +#ifdef NCMPC_MINI + row_hscroll = NULL; +#else + row_hscroll = selected && options.scroll && lw->selected == i + ? &hscroll : NULL; +#endif + + paint_song_row(w, y, width, selected, + (int)mpd_song_get_id(song) == current_song_id, + song, row_hscroll); +} + static void screen_queue_paint(void) { - list_window_paint(lw, screen_queue_lw_callback, NULL); +#ifndef NCMPC_MINI + if (options.scroll) + hscroll_clear(&hscroll); +#endif + + list_window_paint2(lw, screen_queue_paint_callback, NULL); } static void screen_queue_update(struct mpdclient *c) { - static int prev_song_id = -1; - - if (c->events & MPD_IDLE_PLAYLIST) + if (c->events & MPD_IDLE_QUEUE) screen_queue_restore_selection(); - - current_song_id = c->status != NULL && - (mpd_status_get_state(c->status) == MPD_STATE_PLAY || - mpd_status_get_state(c->status) == MPD_STATE_PAUSE) - ? (int)mpd_status_get_song_id(c->status) : -1; - - if (current_song_id != prev_song_id) { - prev_song_id = current_song_id; - - /* center the cursor */ - if (options.auto_center && current_song_id != -1 && ! lw->range_selection) - center_playing_item(c, false); - - screen_queue_repaint(); - } else if (c->events & MPD_IDLE_PLAYLIST) { - /* the playlist has changed, we must paint the new - version */ + else + /* the queue size may have changed, even if we havn't + revceived the QUEUE idle event yet */ + list_window_set_length(lw, playlist_length(playlist)); + + if (((c->events & MPD_IDLE_PLAYER) != 0 && + screen_queue_song_change(c->status)) || + c->events & MPD_IDLE_QUEUE) + /* the queue or the current song has changed, we must + paint the new version */ screen_queue_repaint(); - } } #ifdef HAVE_GETMOUSE @@ -582,8 +568,8 @@ static bool handle_mouse_event(struct mpdclient *c) { int row; - unsigned selected; unsigned long bstate; + unsigned old_selected; if (screen_get_mouse_event(c, &bstate, &row) || list_window_mouse(lw, bstate, row)) { @@ -597,19 +583,29 @@ handle_mouse_event(struct mpdclient *c) return true; } - selected = lw->start + row; + old_selected = lw->selected; + list_window_set_cursor(lw, lw->start + row); if (bstate & BUTTON1_CLICKED) { /* play */ - if (lw->start + row < playlist_length(playlist)) - mpdclient_cmd_play(c, lw->start + row); + const struct mpd_song *song = screen_queue_selected_song(); + if (song != NULL) { + struct mpd_connection *connection = + mpdclient_get_connection(c); + + if (connection != NULL && + !mpd_run_play_id(connection, + mpd_song_get_id(song))) + mpdclient_handle_error(c); + } } else if (bstate & BUTTON3_CLICKED) { /* delete */ - if (selected == lw->selected) + if (lw->selected == old_selected) mpdclient_cmd_delete(c, lw->selected); + + list_window_set_length(lw, playlist_length(playlist)); } - list_window_set_cursor(lw, selected); screen_queue_save_selection(); screen_queue_repaint(); @@ -624,6 +620,7 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd) static command_t cached_cmd = CMD_NONE; command_t prev_cmd = cached_cmd; struct list_window_range range; + const struct mpd_song *song; cached_cmd = cmd; @@ -644,7 +641,7 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd) switch(cmd) { case CMD_SCREEN_UPDATE: - center_playing_item(c, prev_cmd == CMD_SCREEN_UPDATE); + center_playing_item(c->status, prev_cmd == CMD_SCREEN_UPDATE); screen_queue_repaint(); return false; case CMD_SELECT_PLAYING: @@ -713,7 +710,15 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd) switch(cmd) { case CMD_PLAY: - mpdclient_cmd_play(c, lw->selected); + song = screen_queue_selected_song(); + if (song == NULL) + return false; + + connection = mpdclient_get_connection(c); + if (connection != NULL && + !mpd_run_play_id(connection, mpd_song_get_id(song))) + mpdclient_handle_error(c); + return true; case CMD_DELETE: @@ -738,6 +743,9 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd) break; connection = mpdclient_get_connection(c); + if (connection == NULL) + return true; + if (mpd_run_shuffle_range(connection, range.start, range.end)) screen_status_message(_("Shuffled playlist")); else @@ -749,8 +757,8 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd) if (range.start == 0 || range.end <= range.start) return false; - for (unsigned i = range.start; i < range.end; ++i) - mpdclient_cmd_move(c, i, i - 1); + if (!mpdclient_cmd_move(c, range.end - 1, range.start - 1)) + return true; lw->selected--; lw->range_base--; @@ -763,8 +771,8 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd) if (range.end >= playlist_length(&c->playlist)) return false; - for (int i = range.end - 1; i >= (int)range.start; --i) - mpdclient_cmd_move(c, i, i + 1); + if (!mpdclient_cmd_move(c, range.start, range.end)) + return true; lw->selected++; lw->range_base++;