X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_queue.c;h=31c4dcc8a93ad0801cf84e01c8dc9afd7022702e;hb=057875e822828d9dd7e656613b19c784853c7e18;hp=7d915ebf9b242496175727962c2794f1503631f2;hpb=f4aa3b9b5c98d5698e80546f07fa67d54ef86f81;p=ncmpc.git diff --git a/src/screen_queue.c b/src/screen_queue.c index 7d915eb..31c4dcc 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 @@ -56,10 +56,7 @@ typedef struct struct mpdclient *c; } completion_callback_data_t; -/* static struct hscroll hscroll; -static guint scroll_source_id; -*/ #endif static struct mpdclient_playlist *playlist; @@ -120,20 +117,6 @@ 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, G_GNUC_UNUSED void *data) { @@ -147,67 +130,24 @@ screen_queue_lw_callback(unsigned idx, G_GNUC_UNUSED void *data) strfsong(songname, MAX_SONG_LENGTH, options.list_format, song); - /* -#ifndef NCMPC_MINI - if (idx == lw->selected) - { - if (options.scroll && utf8_width(songname) > (unsigned)COLS) { - 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; - } - } - } -#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) { @@ -219,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, @@ -310,8 +276,10 @@ playlist_save(struct mpdclient *c, char *name, char *defaultname) /* send save command to mpd */ connection = mpdclient_get_connection(c); - if (connection == NULL) + if (connection == NULL) { + g_free(filename); return -1; + } filename_utf8 = locale_to_utf8(filename); if (!mpd_run_save(connection, filename_utf8)) { @@ -410,8 +378,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; @@ -425,18 +393,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 @@ -463,6 +428,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 @@ -501,6 +471,7 @@ screen_queue_open(struct mpdclient *c) } screen_queue_restore_selection(); + screen_queue_song_change(c->status); } static void @@ -510,6 +481,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 @@ -541,54 +517,52 @@ screen_queue_paint_callback(WINDOW *w, unsigned i, 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); + song, row_hscroll); } static void screen_queue_paint(void) { - list_window_paint2(lw, screen_queue_paint_callback, NULL); -} +#ifndef NCMPC_MINI + if (options.scroll) + hscroll_clear(&hscroll); +#endif -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; + list_window_paint2(lw, screen_queue_paint_callback, NULL); } static void screen_queue_update(struct mpdclient *c) { - if (c->events & MPD_IDLE_PLAYLIST) + if (c->events & MPD_IDLE_QUEUE) screen_queue_restore_selection(); + else + /* the queue size may have changed, even if we havn't + received the QUEUE idle event yet */ + list_window_set_length(lw, playlist_length(playlist)); - if ((c->events & MPD_IDLE_PLAYER) != 0 && - get_current_song_id(c->status) != current_song_id) { - current_song_id = get_current_song_id(c->status); - - /* 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 */ + 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 @@ -669,7 +643,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: @@ -766,7 +740,7 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd) case CMD_SHUFFLE: list_window_get_range(lw, &range); - if (range.end < range.start + 1) + if (range.end <= range.start + 1) /* No range selection, shuffle all list. */ break; @@ -785,12 +759,16 @@ 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_swap(c, i, i - 1); + if (!mpdclient_cmd_move(c, range.end - 1, range.start - 1)) + return true; lw->selected--; lw->range_base--; + if (lw->range_selection) + list_window_scroll_to(lw, lw->range_base); + list_window_scroll_to(lw, lw->selected); + screen_queue_save_selection(); return true; @@ -799,12 +777,16 @@ 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_swap(c, i, i + 1); + if (!mpdclient_cmd_move(c, range.start, range.end)) + return true; lw->selected++; lw->range_base++; + if (lw->range_selection) + list_window_scroll_to(lw, lw->range_base); + list_window_scroll_to(lw, lw->selected); + screen_queue_save_selection(); return true;