diff --git a/src/playbin.vala b/src/playbin.vala index f6e0804..7650198 100644 --- a/src/playbin.vala +++ b/src/playbin.vala @@ -35,6 +35,7 @@ class Playbin : GLib.Object { // sent when a new song starts playing // continues: whether the track is a gapless continuation public signal void now_playing (bool continues, uint index, Song song); + public signal void stopped (); // the index of the track in the play queue that is currently playing // must equal play queue len iff state is STOPPED @@ -136,7 +137,8 @@ class Playbin : GLib.Object { if (this.update_position) { int64 new_position; if (this.playbin.query_position (Gst.Format.TIME, out new_position)) { - this.position = new_position; + if (new_position > this.duration) this.position = this.duration; + else this.position = new_position; } else { this.position = 0; } @@ -207,7 +209,7 @@ class Playbin : GLib.Object { }); bus.message["eos"].connect ((message) => { - assert (false); // TODO + this.stop (); }); } @@ -257,5 +259,9 @@ class Playbin : GLib.Object { this.playbin.set_state (Gst.State.READY); this.state = PlaybinState.STOPPED; this.current_position = this.play_queue.get_n_items (); + this.stopped (); + + this.position = 0; + this.duration = 1; } } diff --git a/src/ui/play_queue.vala b/src/ui/play_queue.vala index 6aa2a89..a9a64b3 100644 --- a/src/ui/play_queue.vala +++ b/src/ui/play_queue.vala @@ -85,7 +85,7 @@ public class PlayQueueSelection : GLib.Object, GLib.ListModel, Gtk.SelectionMode if (this.current_position >= position) { if (this.current_position < position+removed && added == 0) { - emit_signal = true; + if (position < this.get_n_items ()) emit_signal = true; this.current_position = position; } else { this.current_position += added; diff --git a/src/ui/window.blp b/src/ui/window.blp index 8d507ed..a2404d0 100644 --- a/src/ui/window.blp +++ b/src/ui/window.blp @@ -103,21 +103,21 @@ template $UiWindow: Adw.ApplicationWindow { styles [ "heading" ] xalign: 0; halign: start; - label: bind template.song as <$Song>.title; + label: bind $song_title (template.song) as ; ellipsize: end; } Label { styles [ "caption" ] xalign: 0; - label: bind template.song as <$Song>.artist; + label: bind $song_artist (template.song) as ; ellipsize: end; } Label { styles [ "caption" ] xalign: 0; - label: bind template.song as <$Song>.album; + label: bind $song_album (template.song) as ; ellipsize: end; } } diff --git a/src/ui/window.vala b/src/ui/window.vala index d8a1950..d624b82 100644 --- a/src/ui/window.vala +++ b/src/ui/window.vala @@ -65,6 +65,10 @@ class Ui.Window : Adw.ApplicationWindow { api.scrobble.begin (song.id); this.play_queue.selection.playbin_select (position); }); + this.playbin.stopped.connect (() => { + this.song = null; + this.play_queue.selection.playbin_select (this.play_queue_store.get_n_items ()); + }); this.play_queue.selection.user_selected.connect ((position) => { this.playbin.select_track (position); @@ -215,4 +219,16 @@ class Ui.Window : Adw.ApplicationWindow { if (new_position > this.playbin.duration) new_position = this.playbin.duration; this.seek_impl (new_position); } + + [GtkCallback] private string song_title (Song? song) { + return song == null ? "" : song.title; + } + + [GtkCallback] private string song_artist (Song? song) { + return song == null ? "" : song.artist; + } + + [GtkCallback] private string song_album (Song? song) { + return song == null ? "" : song.album; + } }