Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>
ui: center on the current playing song
include/seamus.h | 4 ++ src/seamus.c | 2 + src/status.c | 5 +++ src/ui.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-
diff --git a/include/seamus.h b/include/seamus.h index 50ed47d65dd89cae9f2d52f930842658b97df05f..5d0464eb8668c0a85651a9305aab04f451ec719c 100644 --- a/include/seamus.h +++ b/include/seamus.h @@ -56,6 +56,7 @@ KEY_PLAY_PAUSE, KEY_STOP, KEY_NEXT, KEY_REPEAT, + KEY_CENTER, }; struct seamus_frontend { @@ -69,6 +70,9 @@ int highlight_index; int scroll_offset; enum window_type current_window; + + int prev_song_id; + int needs_center; TickitWindow *main_window; TickitWindow *status_window; diff --git a/src/seamus.c b/src/seamus.c index 886294980ab8ec58c00fc57a5a2db9fa667f28db..45014a5dea80939b8b5901a3666a065d350c9146 100755 --- a/src/seamus.c +++ b/src/seamus.c @@ -55,6 +55,8 @@ { s->highlight_index = 0; s->scroll_offset = 0; s->current_window = WINDOW_QUEUE; + s->prev_song_id = -1; + s->needs_center = 0; int mpd_con = setup_connection(s); if (mpd_con != 0) { diff --git a/src/status.c b/src/status.c index a78057742f27e56ff6829f1d16e62c4d2343f117..294f49d402dcaeb1310d6301c49c00513137ca3f 100644 --- a/src/status.c +++ b/src/status.c @@ -59,6 +59,11 @@ } sprintf(s->status->description, "%s", "Stopped"); } + if (s->status->current_song_id != s->prev_song_id) { + s->prev_song_id = s->status->current_song_id; + s->needs_center = 1; + } + mpd_status_free(status); mpd_response_finish(s->conn); diff --git a/src/ui.c b/src/ui.c index 9b1d82f21a69a8de65e7849f5f5e3f91649d14ff..8c29c7ecd0ec86583c4a7824fe67baa7ae672272 100644 --- a/src/ui.c +++ b/src/ui.c @@ -14,6 +14,7 @@ static int update_scroll_position(struct seamus_frontend *seamus, int direction); static int scroll_page(struct seamus_frontend *seamus, int direction); static int scroll_to_extremes(struct seamus_frontend *seamus, int home); static int scroll_half_page(struct seamus_frontend *seamus, int direction); +static int scroll_to_center(struct seamus_frontend *seamus); static int switch_window(struct seamus_frontend *seamus); static int toggle_play_pause(struct seamus_frontend *seamus); static int stop_playback(struct seamus_frontend *seamus); @@ -99,9 +100,20 @@ tickit_window_bind_event(root, TICKIT_WINDOW_ON_EXPOSE, 0, &render_root, s); tickit_term_bind_event(tt, TICKIT_TERM_ON_KEY, 0, &on_key_event, s); - // Kick initial update event + // Initial fetch and center so first render is already aligned + // XXX: It doesn't work that well, need some more digging + fetch_current_status(s); + if (s->status && s->status->length > 0) { + s->version = s->status->version; + fetch_current_queue(s); + s->needs_center = 0; + scroll_to_center(s); + } else { + s->needs_center = 0; + } + + // Kick periodic update timer tickit_watch_timer_after_msec(s->t, 1000, 0, &update_status, s); - //tickit_watch_timer_after_msec(s->t, 1000, 0, &update_main_window, s); tickit_run(s->t); @@ -128,6 +140,7 @@ if (strcmp(str, "p") == 0) return KEY_PLAY_PAUSE; if (strcmp(str, "s") == 0) return KEY_STOP; if (strcmp(str, "n") == 0) return KEY_NEXT; if (strcmp(str, "r") == 0) return KEY_REPEAT; + if (strcmp(str, "c") == 0) return KEY_CENTER; return KEY_NONE; } @@ -217,6 +230,11 @@ log_info("Toggle repeat"); toggle_repeat(seamus); break; + case KEY_CENTER: + log_info("Center on playing song"); + scroll_to_center(seamus); + break; + case KEY_NONE: default: log_info("Pressed something else %s", info->str); @@ -244,6 +262,7 @@ return 1; } fetch_current_status(seamus); + scroll_to_center(seamus); tickit_window_expose(seamus->main_window, NULL); return 0; @@ -364,6 +383,43 @@ return 0; } static int +scroll_to_center(struct seamus_frontend *seamus) +{ + if (seamus->status->length <= 0 || seamus->queue_size <= 0) { + return 0; + } + + int playing_idx = -1; + for (int i = 0; i < seamus->queue_size; i++) { + if (seamus->queue[i].song_id == seamus->status->current_song_id) { + playing_idx = i; + break; + } + } + + if (playing_idx < 0) { + return 1; + } + + int visible_rows = tickit_window_lines(seamus->main_window) - QUEUE_START_LINE; + + if (visible_rows <= 0) { + visible_rows = 1; + } + + seamus->highlight_index = playing_idx; + seamus->scroll_offset = playing_idx - visible_rows / 2; + + if (seamus->scroll_offset < 0) { + seamus->scroll_offset = 0; + } + + tickit_window_expose(seamus->main_window, NULL); + + return 0; +} + +static int switch_window(struct seamus_frontend *seamus) { seamus->current_window++; @@ -413,6 +469,7 @@ return 1; } fetch_current_status(seamus); + scroll_to_center(seamus); tickit_window_expose(seamus->main_window, NULL); tickit_window_expose(seamus->status_window, NULL); @@ -441,6 +498,12 @@ (void)_info; struct seamus_frontend *seamus = (struct seamus_frontend*) data; tickit_window_expose(seamus->status_window, NULL); + + if (seamus->needs_center) { + seamus->needs_center = 0; + scroll_to_center(seamus); + } + tickit_watch_timer_after_msec(t, 1000, 0, &update_status, data); return 0; @@ -768,6 +831,7 @@ log_info("Rendering queue again"); switch (seamus->current_window) { case WINDOW_QUEUE: render_queue(seamus, render_buffer); + break; case WINDOW_LIBRARY: render_library(seamus, render_buffer);