From f3849aa2b3eb49ca6a903e6627f97540c1a383f1 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 18 Nov 2008 23:58:28 +0100 Subject: [PATCH] screen_song: new screen which views song information This new screen views all information available on a song: its location, file name, and tags. --- configure.ac | 14 ++++ src/Makefile.am | 4 + src/command.c | 3 + src/command.h | 1 + src/screen.h | 8 ++ src/screen_browser.c | 9 +++ src/screen_list.c | 3 + src/screen_play.c | 8 ++ src/screen_song.c | 189 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 239 insertions(+) create mode 100644 src/screen_song.c diff --git a/configure.ac b/configure.ac index f4a9a7d..5de3a32 100644 --- a/configure.ac +++ b/configure.ac @@ -312,6 +312,20 @@ if test "x$search_screen" = "xyes" ; then fi AM_CONDITIONAL(ENABLE_SEARCH_SCREEN, test x$search_screen = xyes) + +dnl Optional screen - song viewer +AC_MSG_CHECKING([whether to include the song viewer screen]) +AC_ARG_ENABLE([song-screen], + AC_HELP_STRING([--enable-song-screen], + [Enable song viewer screen @<:@default=yes@:>@]), + [song_screen="$enableval"], + [song_screen=$disable_mini]) +AC_MSG_RESULT([$song_screen]) +if test "x$song_screen" = "xyes" ; then + AC_DEFINE(ENABLE_SONG_SCREEN, 1, [Enable song viewer screen]) +fi + +AM_CONDITIONAL(ENABLE_SONG_SCREEN, test x$song_screen = xyes) dnl Optional screen - key editor AC_MSG_CHECKING([whether to include the key editor screen]) diff --git a/src/Makefile.am b/src/Makefile.am index 364c2d0..232417a 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 a1737a9..9dae30b 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 6bfcb02..c3b85c9 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 5d77379..f49ac82 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 be29a34..d0a591e 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 39ec8e9..bfbf90c 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 4b50f74..13b5e74 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 0000000..cf7fd60 --- /dev/null +++ b/src/screen_song.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2008 Max Kellermann + * + * 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 +#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); +} -- 2.30.2