fix drag and drop
This commit is contained in:
parent
930430d5ec
commit
b5fadce142
4 changed files with 71 additions and 23 deletions
|
@ -3,10 +3,10 @@ using Gtk 4.0;
|
|||
template $AudreyUiPlayQueueSong: Box {
|
||||
height-request: 48;
|
||||
spacing: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
|
||||
Box {
|
||||
margin-start: 6;
|
||||
|
||||
width-request: 36;
|
||||
focusable: false;
|
||||
homogeneous: true;
|
||||
|
@ -116,6 +116,7 @@ template $AudreyUiPlayQueueSong: Box {
|
|||
valign: center;
|
||||
}
|
||||
|
||||
Box {
|
||||
MenuButton {
|
||||
// visible: false;
|
||||
focusable: true;
|
||||
|
@ -132,6 +133,9 @@ template $AudreyUiPlayQueueSong: Box {
|
|||
};
|
||||
}
|
||||
|
||||
margin-end: 6;
|
||||
}
|
||||
|
||||
DragSource {
|
||||
actions: move;
|
||||
propagation-phase: capture;
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
min-height: 15px;
|
||||
}
|
||||
|
||||
/* make drag and drop indicator take up entire perimeter */
|
||||
#play-queue listview row {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#play-queue .playing label.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
@ -112,8 +112,7 @@ mod imp {
|
|||
fn on_drag_prepare(&self, x: f64, y: f64) -> Option<gdk::ContentProvider> {
|
||||
if self.draggable.get() {
|
||||
self.drag_pos.replace((x as i32, y as i32));
|
||||
let value = self.obj().to_value();
|
||||
Some(gdk::ContentProvider::for_value(&value))
|
||||
Some(gdk::ContentProvider::for_value(&self.obj().to_value()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -122,6 +121,7 @@ mod imp {
|
|||
#[template_callback]
|
||||
fn on_drag_begin(&self, drag: &gdk::Drag) {
|
||||
let drag_widget = gtk::ListBox::new();
|
||||
drag_widget.add_css_class("boxed-list");
|
||||
|
||||
let drag_row: super::Song = glib::Object::new();
|
||||
drag_row.set_draggable(false);
|
||||
|
@ -148,19 +148,23 @@ mod imp {
|
|||
}
|
||||
|
||||
#[template_callback]
|
||||
fn on_drop(&self, _value: glib::Value, _x: f64, _y: f64) -> bool {
|
||||
/* FIXME: WrongValueType(ValueTypeMismatchError { actual: GValue, requested: AudreyUiPlayQueueSong })
|
||||
// why BoxedValue? see https://discourse.gnome.org/t/gtk-rs-passing-widget-as-gvalue-through-drag-and-drop-with-composite-template/16449/2
|
||||
fn on_drop(&self, value: glib::BoxedValue, _x: f64, _y: f64) -> bool {
|
||||
let source: super::Song = value.get().unwrap();
|
||||
|
||||
source.imp().drag_widget.set(None);
|
||||
|
||||
self.obj().playbin().move_track(
|
||||
source.displayed_position() - 1,
|
||||
self.obj().displayed_position() - 1,
|
||||
);
|
||||
let from = source.position();
|
||||
let to = self.obj().position();
|
||||
|
||||
true */
|
||||
false
|
||||
// see playlist_move for justification
|
||||
if from < to {
|
||||
self.obj().window().playlist_move(from, to + 1);
|
||||
} else {
|
||||
self.obj().window().playlist_move(from, to);
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn set_playlist_pos(&self, playlist_pos: i32) {
|
||||
|
|
|
@ -627,4 +627,39 @@ impl Window {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn playlist_move(&self, from: u32, to: u32) {
|
||||
// NOTE: for mpv, to refers to the "gap" right before i
|
||||
// so playlist-move i 0 makes a track the first
|
||||
// playlist-move i 1 makes a track the second
|
||||
// and playlist-move i playlist-count makes a track the last
|
||||
// (so if to is the position of another track, from is left behind to)
|
||||
self.imp()
|
||||
.mpv
|
||||
.command(["playlist-move", &from.to_string(), &to.to_string()])
|
||||
.unwrap();
|
||||
|
||||
if from < to {
|
||||
// F1234T -> 1234FT
|
||||
let mut spliced = Vec::with_capacity((to - from) as usize);
|
||||
for i in from + 1..to {
|
||||
spliced.push(self.playlist_model().item(i).unwrap());
|
||||
}
|
||||
spliced.push(self.playlist_model().item(from).unwrap());
|
||||
|
||||
self.playlist_model()
|
||||
.splice(from, spliced.len() as u32, &spliced);
|
||||
} else if to < from {
|
||||
// T1234F -> FT1234
|
||||
let mut spliced = Vec::with_capacity((from - to + 1) as usize);
|
||||
spliced.push(self.playlist_model().item(from).unwrap());
|
||||
spliced.push(self.playlist_model().item(to).unwrap());
|
||||
for i in to + 1..from {
|
||||
spliced.push(self.playlist_model().item(i).unwrap());
|
||||
}
|
||||
|
||||
self.playlist_model()
|
||||
.splice(to, spliced.len() as u32, &spliced);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue