audrey/src/ui/play_queue.vala

167 lines
4.9 KiB
Vala
Raw Normal View History

2024-10-13 14:24:25 +00:00
class Ui.PlayQueueStore : Object, ListModel, Gtk.SelectionModel {
public ListStore inner = new ListStore (typeof (Song));
public uint playing_index { get; private set; default = 0; }
2024-10-12 12:57:37 +00:00
2024-10-13 14:24:25 +00:00
private bool starting_stream = false;
2024-10-12 13:36:47 +00:00
2024-10-13 14:24:25 +00:00
public signal void stop_stream ();
public signal void start_stream (Song song);
// public void on_song_start ();
2024-10-12 12:28:05 +00:00
public signal void now_playing (Song song);
2024-10-13 14:24:25 +00:00
public signal void prepare_next_song (Song? song);
// public void on_stream_end ();
2024-10-10 20:04:55 +00:00
2024-10-13 14:24:25 +00:00
construct {
this.inner.items_changed.connect ((position, removed, added) => {
if (this.playing_index >= position) {
if (this.playing_index < position+removed) {
this.playing_index = position;
if (this.playing_index < this.inner.get_n_items ()) {
this.starting_stream = true;
this.now_playing ((Song) this.inner.get_item (this.playing_index));
this.start_stream((Song) this.inner.get_item (this.playing_index));
} else {
this.stop_stream ();
}
} else {
this.playing_index += added;
this.playing_index -= removed;
}
} else {
this.prepare_next_song ((Song?) this.inner.get_item (this.playing_index+1));
}
2024-10-12 16:35:42 +00:00
2024-10-13 14:24:25 +00:00
this.items_changed (position, removed, added);
if (this.playing_index < this.inner.get_n_items ()) {
this.selection_changed (this.playing_index, 1);
}
});
}
2024-10-12 16:35:42 +00:00
2024-10-13 14:24:25 +00:00
public void on_stream_start () {
if (!starting_stream) {
this.playing_index += 1;
this.selection_changed (this.playing_index-1, 2);
this.now_playing ((Song) this.inner.get_item (this.playing_index));
}
2024-10-12 16:35:42 +00:00
2024-10-13 14:24:25 +00:00
this.prepare_next_song ((Song?) this.inner.get_item (this.playing_index+1));
starting_stream = false;
2024-10-10 09:53:52 +00:00
}
2024-10-13 14:24:25 +00:00
Gtk.Bitset get_selection_in_range (uint position, uint n_items) {
var bitset = new Gtk.Bitset.empty ();
if (this.playing_index < this.inner.get_n_items ()) {
bitset.add (playing_index);
}
return bitset;
2024-10-10 09:53:52 +00:00
}
2024-10-13 14:24:25 +00:00
bool is_selected (uint position) {
return position == this.playing_index;
2024-10-10 09:53:52 +00:00
}
2024-10-11 06:57:01 +00:00
2024-10-13 14:24:25 +00:00
bool select_all () {
return false;
2024-10-12 16:35:42 +00:00
}
2024-10-13 14:24:25 +00:00
bool select_item (uint position, bool unselect_rest) {
if (!unselect_rest) {
return false;
}
var previous = this.playing_index;
this.playing_index = position;
2024-10-12 16:35:42 +00:00
2024-10-13 14:24:25 +00:00
if (previous < this.inner.get_n_items ()) {
this.selection_changed (previous, 1);
2024-10-12 16:35:42 +00:00
}
2024-10-13 14:24:25 +00:00
this.selection_changed (position, 1);
this.starting_stream = true;
this.now_playing ((Song) this.inner.get_item (this.playing_index));
this.start_stream ((Song) this.inner.get_item (this.playing_index));
return true;
2024-10-11 08:22:05 +00:00
}
2024-10-12 12:28:05 +00:00
2024-10-13 14:24:25 +00:00
bool select_range (uint position, uint n_items, bool unselect_rest) {
return false;
}
2024-10-12 12:28:05 +00:00
2024-10-13 14:24:25 +00:00
bool set_selection (Gtk.Bitset selected, Gtk.Bitset mask) {
return false;
}
2024-10-12 16:35:42 +00:00
2024-10-13 14:24:25 +00:00
bool unselect_all () {
return false;
}
bool unselect_item (uint position) {
return false;
}
bool unselect_range (uint position, uint n_items) {
return false;
}
Object? get_item (uint position) {
return this.inner.get_item (position);
}
Type get_item_type () {
return this.inner.get_item_type ();
}
uint get_n_items () {
return this.inner.get_n_items ();
}
}
[GtkTemplate (ui = "/eu/callcc/audrey/ui/play_queue.ui")]
public class Ui.PlayQueue : Adw.NavigationPage {
[GtkChild] private unowned Gtk.ColumnView view;
PlayQueueStore store = new PlayQueueStore ();
public signal void play_now (Song song);
public signal void play_next (Song? song);
public signal void now_playing (Song song);
public bool can_clear_all { get; private set; default = false; }
construct {
this.view.model = this.store;
}
[GtkCallback] public void clear () {
this.store.inner.remove_all ();
this.can_clear_all = false;
this.store.start_stream.connect ((song) => this.play_now(song));
this.store.now_playing.connect ((song) => this.now_playing(song));
this.store.prepare_next_song.connect ((song) => this.play_next(song));
}
public void queue (Song song) {
this.store.inner.append (song);
}
internal void on_stream_start () {
this.store.on_stream_start ();
2024-10-12 12:28:05 +00:00
}
2024-10-12 12:57:37 +00:00
internal void restart () {
2024-10-13 14:24:25 +00:00
this.store.select_item (0, true);
2024-10-12 12:57:37 +00:00
}
2024-10-12 13:36:47 +00:00
public void skip_forward () {
2024-10-13 14:24:25 +00:00
this.store.select_item (this.store.playing_index+1, true);
2024-10-12 13:36:47 +00:00
}
public void skip_backward () {
2024-10-13 14:24:25 +00:00
if (this.store.playing_index >= 1) {
this.store.select_item (this.store.playing_index-1, true);
2024-10-12 13:36:47 +00:00
}
2024-10-12 16:35:42 +00:00
}
2024-10-10 09:53:52 +00:00
}