diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/command.c | 3 | ||||
-rw-r--r-- | src/command.h | 1 | ||||
-rw-r--r-- | src/screen.h | 8 | ||||
-rw-r--r-- | src/screen_browser.c | 9 | ||||
-rw-r--r-- | src/screen_list.c | 3 | ||||
-rw-r--r-- | src/screen_play.c | 8 | ||||
-rw-r--r-- | src/screen_song.c | 189 |
8 files changed, 225 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 364c2d0b0..232417a91 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,6 +90,10 @@ if ENABLE_SEARCH_SCREEN ncmpc_SOURCES += screen_search.c endif +if ENABLE_SONG_SCREEN +ncmpc_SOURCES += screen_song.c +endif + if ENABLE_KEYDEF_SCREEN ncmpc_SOURCES += screen_keydef.c endif diff --git a/src/command.c b/src/command.c index a1737a942..9dae30be6 100644 --- a/src/command.c +++ b/src/command.c @@ -142,6 +142,9 @@ static command_definition_t cmds[] = { { { '"', 0, 0 }, 0, CMD_GO_PARENT_DIRECTORY, "go-parent-directory", N_("Go to parent directory") }, + { { 'i', 0, 0 }, 0, CMD_VIEW, "view", + N_("View the song") }, + { { 'G', 0, 0 }, 0, CMD_LOCATE, "locate", N_("Locate song in browser") }, diff --git a/src/command.h b/src/command.h index 6bfcb027e..c3b85c97d 100644 --- a/src/command.h +++ b/src/command.h @@ -62,6 +62,7 @@ typedef enum { CMD_INTERRUPT, CMD_GO_ROOT_DIRECTORY, CMD_GO_PARENT_DIRECTORY, + CMD_VIEW, CMD_LOCATE, CMD_QUIT } command_t; diff --git a/src/screen.h b/src/screen.h index 5d7737973..f49ac82d1 100644 --- a/src/screen.h +++ b/src/screen.h @@ -56,6 +56,9 @@ extern const struct screen_functions screen_help; #ifdef ENABLE_SEARCH_SCREEN extern const struct screen_functions screen_search; #endif +#ifdef ENABLE_SONG_SCREEN +extern const struct screen_functions screen_song; +#endif #ifdef ENABLE_KEYDEF_SCREEN extern const struct screen_functions screen_keydef; #endif @@ -98,6 +101,11 @@ int screen_get_mouse_event(mpdclient_t *c, unsigned long *bstate, int *row); bool screen_file_goto_song(struct mpdclient *c, const struct mpd_song *song); +#ifdef ENABLE_SONG_SCREEN +void +screen_song_switch(struct mpdclient *c, const struct mpd_song *song); +#endif + #ifdef ENABLE_LYRICS_SCREEN void screen_lyrics_switch(struct mpdclient *c, const struct mpd_song *song); diff --git a/src/screen_browser.c b/src/screen_browser.c index be29a341a..d0a591ec4 100644 --- a/src/screen_browser.c +++ b/src/screen_browser.c @@ -529,6 +529,15 @@ browser_cmd(struct screen_browser *browser, return true; #endif + case CMD_VIEW: + entry = browser_get_selected(browser); + if (entry == NULL || entry->entity == NULL || + entry->entity->type != MPD_INFO_ENTITY_TYPE_SONG) + return false; + + screen_song_switch(c, entry->entity->info.song); + return true; + case CMD_LOCATE: entry = browser_get_selected(browser); if (entry == NULL || entry->entity == NULL || diff --git a/src/screen_list.c b/src/screen_list.c index 39ec8e9f3..bfbf90c63 100644 --- a/src/screen_list.c +++ b/src/screen_list.c @@ -38,6 +38,9 @@ static const struct #ifdef ENABLE_SEARCH_SCREEN { "search", &screen_search }, #endif +#ifdef ENABLE_SONG_SCREEN + { "song", &screen_song }, +#endif #ifdef ENABLE_KEYDEF_SCREEN { "keydef", &screen_keydef }, #endif diff --git a/src/screen_play.c b/src/screen_play.c index 4b50f7459..13b5e742b 100644 --- a/src/screen_play.c +++ b/src/screen_play.c @@ -554,6 +554,14 @@ play_cmd(mpdclient_t *c, command_t cmd) return handle_mouse_event(c); #endif + case CMD_VIEW: + if (lw->selected < playlist_length(&c->playlist)) { + screen_song_switch(c, playlist_get(&c->playlist, lw->selected)); + return true; + } + + break; + case CMD_LOCATE: if (lw->selected < playlist_length(&c->playlist)) { screen_file_goto_song(c, playlist_get(&c->playlist, lw->selected)); diff --git a/src/screen_song.c b/src/screen_song.c new file mode 100644 index 000000000..cf7fd606b --- /dev/null +++ b/src/screen_song.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2008 Max Kellermann <max@duempel.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <sys/stat.h> +#include "i18n.h" +#include "options.h" +#include "mpdclient.h" +#include "command.h" +#include "screen.h" +#include "screen_utils.h" +#include "strfsong.h" +#include "charset.h" + +static list_window_t *lw; + +struct { + struct mpd_song *song; + GPtrArray *lines; +} current; + +static void +screen_song_clear(void) +{ + for (guint i = 0; i < current.lines->len; ++i) + g_free(g_ptr_array_index(current.lines, i)); + + g_ptr_array_set_size(current.lines, 0); +} + +static void +screen_song_paint(void); + +/** + * Repaint and update the screen. + */ +static void +screen_song_repaint(void) +{ + screen_song_paint(); + wrefresh(lw->w); +} + +static const char * +screen_song_list_callback(unsigned idx, G_GNUC_UNUSED int *highlight, + G_GNUC_UNUSED void *data) +{ + static char buffer[256]; + char *value; + + if (idx >= current.lines->len) + return NULL; + + value = utf8_to_locale(g_ptr_array_index(current.lines, idx)); + g_strlcpy(buffer, value, sizeof(buffer)); + g_free(value); + + return buffer; +} + + +static void +screen_song_init(WINDOW *w, int cols, int rows) +{ + current.lines = g_ptr_array_new(); + lw = list_window_init(w, cols, rows); + lw->flags = LW_HIDE_CURSOR; +} + +static void +screen_song_exit(void) +{ + list_window_free(lw); + + screen_song_clear(); + + g_ptr_array_free(current.lines, TRUE); + current.lines = NULL; +} + +static void +screen_song_resize(int cols, int rows) +{ + lw->cols = cols; + lw->rows = rows; +} + +static const char * +screen_song_title(G_GNUC_UNUSED char *str, G_GNUC_UNUSED size_t size) +{ + return _("Song viewer"); +} + +static void +screen_song_paint(void) +{ + list_window_paint(lw, screen_song_list_callback, NULL); +} + +static bool +screen_song_cmd(mpdclient_t *c, command_t cmd) +{ + if (list_window_scroll_cmd(lw, current.lines->len, cmd)) { + screen_song_repaint(); + return true; + } + + switch(cmd) { + case CMD_LOCATE: + if (current.song != NULL) { + screen_file_goto_song(c, current.song); + return true; + } + + return false; + + default: + break; + } + + if (screen_find(lw, current.lines->len, + cmd, screen_song_list_callback, NULL)) { + /* center the row */ + list_window_center(lw, current.lines->len, lw->selected); + screen_song_repaint(); + return true; + } + + return false; +} + +const struct screen_functions screen_song = { + .init = screen_song_init, + .exit = screen_song_exit, + .resize = screen_song_resize, + .paint = screen_song_paint, + .cmd = screen_song_cmd, + .get_title = screen_song_title, +}; + +static void +screen_song_append(const char *label, const char *value) +{ + assert(label != NULL); + + if (value != NULL) + g_ptr_array_add(current.lines, + g_strdup_printf("%s: %s", label, value)); +} + +void +screen_song_switch(struct mpdclient *c, const struct mpd_song *song) +{ + assert(song != NULL); + assert(song->file != NULL); + + screen_song_clear(); + + current.song = mpd_songDup(song); + + g_ptr_array_add(current.lines, g_strdup(song->file)); + + screen_song_append(_("Artist"), song->artist); + screen_song_append(_("Title"), song->title); + screen_song_append(_("Album"), song->album); + screen_song_append(_("Composer"), song->composer); + screen_song_append(_("Name"), song->name); + screen_song_append(_("Disc"), song->disc); + screen_song_append(_("Track"), song->track); + screen_song_append(_("Date"), song->date); + screen_song_append(_("Genre"), song->genre); + screen_song_append(_("Comment"), song->comment); + + screen_switch(&screen_song, c); +} |