seamus

commit cb747866b7b7c9fdf404f9e5cb83e2f96e2c04fd

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);