commit a001039548e2df4ba88b5ad0396eac4980959ab0
parent 019761cb13674f85468188b193e2fa7ff959f47f
Author: Louis Burda <quent.burda@gmail.com>
Date: Sat, 8 Jan 2022 17:20:46 +0100
Allow switch between playlist and tracks in hovered tag
Diffstat:
3 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/src/listnav.c b/src/listnav.c
@@ -12,26 +12,30 @@ listnav_init(struct listnav *nav)
void
listnav_update_bounds(struct listnav *nav, int min, int max)
{
+ ASSERT(max >= min);
nav->min = min;
nav->max = max;
- nav->wmin = MAX(nav->wmin, nav->min);
- nav->wmax = MIN(nav->wmin + nav->wlen, nav->max);
- nav->sel = MIN(MAX(nav->sel, nav->wmin), nav->wmax - 1);
+ listnav_update_wlen(nav, MIN(nav->wlen, nav->max - nav->min));
}
void
listnav_update_wlen(struct listnav *nav, int wlen)
{
- nav->wlen = wlen;
- nav->wmax = MIN(nav->wmin + nav->wlen, nav->max);
- nav->sel = MIN(MAX(nav->sel, nav->wmin), nav->wmax - 1);
+ ASSERT(wlen >= 0);
+
+ nav->wlen = MIN(wlen, nav->max - nav->min);
+ if (nav->wmin < nav->min)
+ nav->wmin = nav->min;
+ if (nav->wmin + nav->wlen > nav->max)
+ nav->wmin = nav->max - nav->wlen;
+ nav->wmax = nav->wmin + nav->wlen;
+ nav->sel = MAX(MIN(nav->sel, nav->wmax - 1), nav->wmin);
}
void
listnav_update_sel(struct listnav *nav, int sel)
{
nav->sel = MAX(MIN(sel, nav->max - 1), nav->min);
-
if (nav->sel >= nav->wmax) {
nav->wmax = nav->sel + 1;
nav->wmin = MAX(nav->min, nav->wmax - nav->wlen);
diff --git a/src/main.c b/src/main.c
@@ -87,6 +87,8 @@ static struct pane *const panes[] = {
static struct link tracks;
static struct link tags;
static struct link tags_sel;
+static struct link *tracks_vis;
+static int track_show_playlist;
/* bottom 'cmd' pane for search / exec */
static struct pane *cmd_pane;
@@ -140,6 +142,7 @@ static int cmd_pane_input(wint_t c);
static void cmd_pane_vis(struct pane *pane, int sel);
static void queue_hover(void);
+static void update_track_playlist(void);
static void main_input(wint_t c);
static void main_vis(void);
@@ -173,6 +176,9 @@ init(void)
listnav_init(&tag_nav);
listnav_init(&track_nav);
+ track_show_playlist = 0;
+ update_track_playlist();
+
on_exit(cleanup, NULL);
signal(SIGINT, exit);
}
@@ -252,11 +258,11 @@ tui_resize(void)
getmaxyx(stdscr, scrh, scrw);
/* guarantee a minimum terminal size */
- if (scrw < 10 || scrh < 4) {
+ while (scrw < 10 || scrh < 4) {
clear();
- printw("...");
refresh();
usleep(10000);
+ getmaxyx(stdscr, scrh, scrw);
}
/* adjust tag pane width to name lengths */
@@ -309,6 +315,8 @@ data_load(void)
tracks_load(tag);
}
closedir(dir);
+
+ ASSERT(!list_empty(&tags));
}
void
@@ -595,8 +603,8 @@ track_pane_input(wint_t c)
listnav_update_sel(&track_nav, track_nav.sel + 1);
return 1;
case KEY_ENTER:
- if (list_empty(&player->playlist)) return 1;
- link = link_iter(player->playlist.next, track_nav.sel);
+ if (list_empty(tracks_vis)) return 1;
+ link = link_iter(tracks_vis->next, track_nav.sel);
ASSERT(link != NULL);
track = UPCAST(link, struct ref)->data;
player_play_track(track);
@@ -619,16 +627,17 @@ track_pane_vis(struct pane *pane, int sel)
{
struct track *track;
struct link *iter;
+ struct tag *tag;
int index;
werase(pane->win);
pane_title(pane, "Tracks", sel);
- listnav_update_bounds(&track_nav, 0, list_len(&player->playlist));
+ listnav_update_bounds(&track_nav, 0, list_len(tracks_vis));
listnav_update_wlen(&track_nav, pane->h - 1);
index = 0;
- for (iter = player->playlist.next; iter; iter = iter->next, index++) {
+ for (iter = tracks_vis->next; iter; iter = iter->next, index++) {
track = UPCAST(iter, struct ref)->data;
if (index < track_nav.wmin) continue;
@@ -851,7 +860,8 @@ cmd_pane_vis(struct pane *pane, int sel)
/* status bits on right of status line */
if (player->loaded) ATTR_ON(pane->win, A_REVERSE);
- mvwaddstr(pane->win, 1, pane->w - 4, "[ ]");
+ mvwaddstr(pane->win, 1, pane->w - 5, "[ ]");
+ if (track_show_playlist) mvwaddstr(pane->win, 1, pane->w - 4, "P");
if (player->autoplay) mvwaddstr(pane->win, 1, pane->w - 3, "A");
if (player->shuffle) mvwaddstr(pane->win, 1, pane->w - 2, "S");
if (player->loaded) ATTR_OFF(pane->win, A_REVERSE);
@@ -901,6 +911,22 @@ queue_hover(void)
}
void
+update_track_playlist(void)
+{
+ struct link *iter;
+ struct tag *tag;
+
+ if (track_show_playlist) {
+ tracks_vis = &player->playlist;
+ } else {
+ iter = link_iter(tags.next, tag_nav.sel);
+ ASSERT(iter != NULL);
+ tag = UPCAST(iter, struct tag);
+ tracks_vis = &tag->tracks;
+ }
+}
+
+void
main_input(wint_t c)
{
switch (c) {
@@ -929,6 +955,9 @@ main_input(wint_t c)
case L'c':
player_toggle_pause();
break;
+ case L'P':
+ track_show_playlist ^= 1;
+ break;
case L'n':
case L'>':
player_next();
@@ -1026,6 +1055,8 @@ main(int argc, const char **argv)
if (!handled) main_input(c);
}
+ update_track_playlist();
+
refresh();
for (i = 0; i < ARRLEN(panes); i++) {
/* only update ui for panes that are visible */
diff --git a/src/player.c b/src/player.c
@@ -41,13 +41,13 @@ handle_mpd_status(int status)
case MPD_ERROR_SERVER:
case MPD_ERROR_ARGUMENT:
if (!mpd_connection_clear_error(player->conn))
- PANIC("Player failed to recover from error");
+ PANIC("PLAYER: Failed to recover from argument error");
case MPD_ERROR_SYSTEM:
PLAYER_STATUS(PLAYER_MSG_ERR, "%s",
mpd_connection_get_error_message(player->conn));
return 1;
case MPD_ERROR_CLOSED:
- PANIC("Player encountered non-recoverable error");
+ PANIC("PLAYER: Connection abruptly closed");
}
return 0;
}
@@ -67,6 +67,7 @@ player_init(void)
player->playlist = LIST_HEAD;
player->track = NULL;
+ player->loaded = 0;
player->state = PLAYER_STATE_PAUSED;
player->autoplay = 0;
@@ -154,8 +155,9 @@ player_update(void)
|| !list_empty(&player->queue)) {
player->action = PLAYER_ACTION_PLAY_NEXT;
}
+ } else {
+ mpd_song_free(song);
}
- mpd_song_free(song);
mpd_status_free(status);
@@ -205,13 +207,13 @@ player_update(void)
player->loaded = true;
player->time_pos = mpd_status_get_elapsed_time(status);
player->time_end = mpd_song_get_duration(song);
+ mpd_song_free(song);
} else {
player->loaded = false;
player->track = NULL;
player->time_pos = 0;
player->time_end = 0;
}
- mpd_song_free(song);
switch (mpd_status_get_state(status)) {
case MPD_STATE_PAUSE: