diff --git a/examples/simple.rs b/examples/simple.rs index a7d1287..21723a8 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -10,9 +10,13 @@ pub fn main() -> eframe::Result<()> { Default::default(), move |ctx, _frame| { CentralPanel::default().show(ctx, |ui| { - dnd(ui, "dnd_example").show_vec(&mut items, |ui, item, handle, _state| { + dnd(ui, "dnd_example").show_vec(&mut items, |ui, item, handle, state| { handle.ui(ui, |ui| { - ui.label("drag"); + if state.dragged { + ui.label("dragging"); + } else { + ui.label("drag"); + } }); ui.label(*item); }); diff --git a/src/lib.rs b/src/lib.rs index 28de902..140b959 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -146,8 +146,8 @@ impl<'a> Dnd<'a> { mut drag_drop_ui, } = self; - let response = drag_drop_ui.ui(ui, items, |item, ui, handle, dragged| { - item_ui(ui, item, handle, ItemState { dragged }); + let response = drag_drop_ui.ui(ui, items, |item, ui, handle, item_state| { + item_ui(ui, item, handle, item_state); }); ui.ctx().data_mut(|data| data.insert_temp(id, drag_drop_ui)); @@ -175,4 +175,9 @@ impl<'a> Dnd<'a> { pub struct ItemState { /// True if the item is currently being dragged. pub dragged: bool, + /// Index of the item in the list. + /// Note that when you sort the source list while the drag is still ongoing (default behaviour + /// of [Dnd::show_vec]), this index will updated while the item is being dragged. + /// If you sort once after the item is dropped, the index will be stable during the drag. + pub index: usize, } diff --git a/src/state.rs b/src/state.rs index e4bf5a2..f8fbde9 100644 --- a/src/state.rs +++ b/src/state.rs @@ -4,6 +4,7 @@ use std::time::{Duration, SystemTime}; use egui::{CursorIcon, Id, InnerResponse, LayerId, Order, Pos2, Rect, Sense, Ui, Vec2}; +use crate::ItemState; #[cfg(target_arch = "wasm32")] use web_time::{Duration, SystemTime}; @@ -490,7 +491,7 @@ impl DragDropUi { &mut self, ui: &mut Ui, values: impl Iterator, - mut item_ui: impl FnMut(T, &mut Ui, Handle, bool), + mut item_ui: impl FnMut(T, &mut Ui, Handle, ItemState), ) -> DragDropResponse { // During the first frame, we check if the pointer is actually over any of the item handles and cancel the drag if it isn't let mut first_frame = false; @@ -626,7 +627,15 @@ impl DragDropUi { item_id, &mut hovering_over_any_handle, |ui, handle| { - item_ui(item, ui, handle, is_dragged_item); + item_ui( + item, + ui, + handle, + ItemState { + dragged: is_dragged_item, + index: idx, + }, + ); }, ) })