diff --git a/src/playbin.vala b/src/playbin.vala index 81c956c..fe71d7f 100644 --- a/src/playbin.vala +++ b/src/playbin.vala @@ -276,4 +276,53 @@ public class Playbin : GLib.Object { if (this.state == STOPPED) this.play_queue_position += 1; this._play_queue.append (song); } + + public void move_track (uint from, uint to) + requires (from < this._play_queue.get_n_items ()) + requires (to < this._play_queue.get_n_items ()) + { + debug (@"moving track $from to $to"); + + if (from < to) { + // why offset to? because if the playlist is 01234, + // mpv takes "move 1 to 3" to mean 02134, not 02314 + // that is, the target is a "gap", not a playlist entry + // from -> 0 1 2 3 4 5 + // to -> 0 1 2 3 4 5 6 + assert(this.mpv.command({ + "playlist-move", + from.to_string (), + (to+1).to_string (), + }) >= 0); + + // F0123T -> 0123TF + var additions = new Object[to-from+1]; + for (uint i = from+1; i < to; i += 1) { + additions[i-from-1] = this._play_queue.get_item (i); + } + additions[to-from-1] = this._play_queue.get_item (to); + additions[to-from] = this._play_queue.get_item (from); + this._play_queue.splice(from, to-from+1, additions); + + if (this.play_queue_position == from) this.play_queue_position = to; + else if (this.play_queue_position > from && this.play_queue_position <= to) this.play_queue_position -= 1; + } else if (from > to) { + assert(this.mpv.command({ + "playlist-move", + from.to_string (), + to.to_string (), + }) >= 0); + + // T0123F -> FT0123 + var additions = new Object[from-to+1]; + additions[0] = this._play_queue.get_item (from); + for (uint i = to; i < from; i += 1) { + additions[i-to+1] = this._play_queue.get_item (i); + } + this._play_queue.splice (to, from-to+1, additions); + + if (this.play_queue_position == from) this.play_queue_position = to; + else if (this.play_queue_position >= to && this.play_queue_position < from) this.play_queue_position += 1; + } + } } diff --git a/src/ui/play_queue.vala b/src/ui/play_queue.vala index 5697333..d5d2d3f 100644 --- a/src/ui/play_queue.vala +++ b/src/ui/play_queue.vala @@ -65,6 +65,7 @@ class Ui.PlayQueueSong : Gtk.ListBoxRow { [GtkCallback] private bool on_drop (Value value, double x, double y) { 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; } } @@ -100,7 +101,7 @@ public class Ui.PlayQueue : Adw.NavigationPage { var item = object as Gtk.ListItem; var child = new PlayQueueSong (this.playbin); - child.draggable = false; // TODO + child.draggable = true; child.show_artist = true; child.show_album = true;