176 lines
5.6 KiB
Vala
176 lines
5.6 KiB
Vala
|
// song widget+drag behavior taken from gnome music
|
||
|
|
||
|
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue_song.ui")]
|
||
|
class Ui.PlayQueueSong : Gtk.Box {
|
||
|
public bool draggable { get; set; default = false; }
|
||
|
public bool show_position { get; set; default = false; }
|
||
|
public bool show_artist { get; set; default = false; }
|
||
|
public bool show_cover { get; set; default = false; }
|
||
|
|
||
|
private bool _current = false;
|
||
|
public bool current {
|
||
|
get { return _current; }
|
||
|
set {
|
||
|
this._current = value;
|
||
|
if (value) {
|
||
|
this.add_css_class ("playing");
|
||
|
} else {
|
||
|
this.remove_css_class ("playing");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
public uint displayed_position { get; set; }
|
||
|
public PlaybinSong song { get; set; }
|
||
|
|
||
|
private weak Playbin playbin;
|
||
|
public PlayQueueSong (Playbin playbin) {
|
||
|
this.playbin = playbin;
|
||
|
|
||
|
var action_group = new SimpleActionGroup ();
|
||
|
|
||
|
var remove = new SimpleAction ("remove", null);
|
||
|
remove.activate.connect (() => {
|
||
|
this.playbin.remove_track (this.displayed_position-1);
|
||
|
});
|
||
|
action_group.add_action (remove);
|
||
|
|
||
|
this.insert_action_group ("song", action_group);
|
||
|
}
|
||
|
|
||
|
private ulong connection;
|
||
|
public void bind (uint position, PlaybinSong song) {
|
||
|
this.displayed_position = position+1;
|
||
|
this.song = song;
|
||
|
this.current = this.playbin.play_queue_position == position;
|
||
|
this.connection = this.playbin.notify["play-queue-position"].connect (() => {
|
||
|
this.current = this.playbin.play_queue_position == position;
|
||
|
});
|
||
|
|
||
|
song.need_cover_art ();
|
||
|
}
|
||
|
|
||
|
public void unbind () {
|
||
|
this.playbin.disconnect (this.connection);
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private string format_duration (int duration) {
|
||
|
return "%02d:%02d".printf(duration/60, duration%60);
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private string star_button_icon_name (DateTime? starred) {
|
||
|
return starred == null ? "non-starred" : "starred";
|
||
|
}
|
||
|
|
||
|
private double drag_x;
|
||
|
private double drag_y;
|
||
|
|
||
|
[GtkCallback] private Gdk.ContentProvider? on_drag_prepare (double x, double y) {
|
||
|
if (this.draggable) {
|
||
|
this.drag_x = x;
|
||
|
this.drag_y = y;
|
||
|
return new Gdk.ContentProvider.for_value (this);
|
||
|
}
|
||
|
else return null;
|
||
|
}
|
||
|
|
||
|
private Gtk.ListBox? drag_widget;
|
||
|
|
||
|
[GtkCallback] private void on_drag_begin (Gtk.DragSource source, Gdk.Drag drag) {
|
||
|
this.drag_widget = new Gtk.ListBox ();
|
||
|
|
||
|
var drag_row = new PlayQueueSong (this.playbin);
|
||
|
drag_row.draggable = false;
|
||
|
drag_row.show_position = this.show_position;
|
||
|
drag_row.show_artist = this.show_artist;
|
||
|
drag_row.show_cover = this.show_cover;
|
||
|
drag_row.current = false;
|
||
|
drag_row.displayed_position = this.displayed_position;
|
||
|
drag_row.song = this.song;
|
||
|
drag_row.set_size_request (this.get_width (), this.get_height ());
|
||
|
|
||
|
var drag_row_real = new Gtk.ListBoxRow ();
|
||
|
drag_row_real.child = drag_row;
|
||
|
|
||
|
this.drag_widget.append (drag_row_real);
|
||
|
this.drag_widget.drag_highlight_row (drag_row_real);
|
||
|
|
||
|
var drag_icon = Gtk.DragIcon.get_for_drag (drag);
|
||
|
drag_icon.set("child", this.drag_widget);
|
||
|
drag.set_hotspot ((int) this.drag_x, (int) this.drag_y);
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private bool on_drop (Value value, double x, double y) {
|
||
|
this.drag_widget = null;
|
||
|
this.drag_x = 0.0;
|
||
|
this.drag_y = 0.0;
|
||
|
|
||
|
var source = value as PlayQueueSong;
|
||
|
debug ("dropped %u on %u", source.displayed_position, this.displayed_position);
|
||
|
this.playbin.move_track (source.displayed_position-1, this.displayed_position-1);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue.ui")]
|
||
|
public class Ui.PlayQueue : Adw.Bin {
|
||
|
private weak Playbin _playbin;
|
||
|
public Playbin playbin {
|
||
|
get { return _playbin; }
|
||
|
set {
|
||
|
assert (_playbin == null); // only set once
|
||
|
_playbin = value;
|
||
|
|
||
|
_playbin.play_queue.items_changed.connect (this.on_store_items_changed);
|
||
|
this.can_clear_all = _playbin.play_queue.get_n_items () > 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool can_clear_all { get; private set; }
|
||
|
|
||
|
/*[GtkCallback] private void on_clear () {
|
||
|
this.playbin.clear ();
|
||
|
}*/
|
||
|
|
||
|
private void on_store_items_changed (GLib.ListModel store, uint position, uint removed, uint added) {
|
||
|
this.can_clear_all = store.get_n_items () > 0;
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private void on_song_list_setup (Gtk.SignalListItemFactory factory, Object object) {
|
||
|
var item = object as Gtk.ListItem;
|
||
|
var child = new PlayQueueSong (this.playbin);
|
||
|
|
||
|
child.draggable = true;
|
||
|
child.show_position = true;
|
||
|
child.show_artist = true;
|
||
|
child.show_cover = true;
|
||
|
|
||
|
item.child = child;
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private void on_song_list_bind (Gtk.SignalListItemFactory factory, Object object) {
|
||
|
var item = object as Gtk.ListItem;
|
||
|
var child = item.child as PlayQueueSong;
|
||
|
|
||
|
child.bind (item.position, item.item as PlaybinSong);
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private void on_song_list_unbind (Gtk.SignalListItemFactory factory, Object object) {
|
||
|
var item = object as Gtk.ListItem;
|
||
|
var child = item.child as PlayQueueSong;
|
||
|
|
||
|
child.unbind ();
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private void on_row_activated (uint position) {
|
||
|
playbin.select_track (position);
|
||
|
}
|
||
|
|
||
|
[GtkCallback] private string visible_child_name (uint n_items) {
|
||
|
return n_items > 0 ? "not-empty" : "empty";
|
||
|
}
|
||
|
|
||
|
~PlayQueue () {
|
||
|
debug ("destroying play queue widget");
|
||
|
}
|
||
|
}
|