Skip to content

Commit 9689d71

Browse files
committed
Done
1 parent c3fdd35 commit 9689d71

File tree

3 files changed

+38
-61
lines changed

3 files changed

+38
-61
lines changed

examples/hierachical_list_drag_and_drop/src/app.rs

Lines changed: 36 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::collections::{HashMap, HashSet};
1+
//! This demo is a stripped-down version of the drag-and-drop implementation in the
2+
//! [rerun viewer](https://github.com/rerun-io/rerun).
3+
4+
use std::collections::HashMap;
25

36
use eframe::{egui, egui::NumExt as _};
47

@@ -30,20 +33,14 @@ enum Item {
3033

3134
#[derive(Debug)]
3235
enum Command {
33-
/// Set the selection to the given item.
34-
SetSelection(ItemId),
35-
36-
/// Toggle the selected state of the given item.
37-
ToggleSelected(ItemId),
38-
3936
/// Move the currently dragged item to the given container and position.
4037
MoveItem {
4138
moved_item_id: ItemId,
4239
target_container_id: ItemId,
4340
target_position_index: usize,
4441
},
4542

46-
/// Specify the currently identifed target container to be highlighted.
43+
/// Specify the currently identified target container to be highlighted.
4744
HighlightTargetContainer(ItemId),
4845
}
4946

@@ -54,9 +51,6 @@ pub struct HierarchicalDragAndDrop {
5451
/// Id of the root item (not displayed in the UI)
5552
root_id: ItemId,
5653

57-
/// Set of all selected items
58-
selected_items: HashSet<ItemId>,
59-
6054
/// If a drag is ongoing, this is the id of the destination container (if any was identified)
6155
///
6256
/// This is used to highlight the target container.
@@ -79,7 +73,6 @@ impl Default for HierarchicalDragAndDrop {
7973
let mut res = Self {
8074
items: std::iter::once((root_id, root_item)).collect(),
8175
root_id,
82-
selected_items: HashSet::new(),
8376
target_container: None,
8477
command_receiver,
8578
command_sender,
@@ -227,10 +220,6 @@ impl HierarchicalDragAndDrop {
227220
}
228221
}
229222

230-
fn selected(&self, id: ItemId) -> bool {
231-
self.selected_items.contains(&id)
232-
}
233-
234223
fn send_command(&self, command: Command) {
235224
// The only way this can fail is if the receiver has been dropped.
236225
self.command_sender.send(command).ok();
@@ -252,17 +241,6 @@ impl HierarchicalDragAndDrop {
252241
while let Ok(command) = self.command_receiver.try_recv() {
253242
//println!("Received command: {command:?}");
254243
match command {
255-
Command::SetSelection(item_id) => {
256-
self.selected_items.clear();
257-
self.selected_items.insert(item_id);
258-
}
259-
Command::ToggleSelected(item_id) => {
260-
if self.selected_items.contains(&item_id) {
261-
self.selected_items.remove(&item_id);
262-
} else {
263-
self.selected_items.insert(item_id);
264-
}
265-
}
266244
Command::MoveItem {
267245
moved_item_id,
268246
target_container_id,
@@ -276,7 +254,7 @@ impl HierarchicalDragAndDrop {
276254
}
277255

278256
fn container_ui(&self, ui: &mut egui::Ui, item_id: ItemId, children: &Vec<ItemId>) {
279-
let (_, header_resp, body_resp) =
257+
let (response, head_response, body_resp) =
280258
egui::collapsing_header::CollapsingState::load_with_default_open(
281259
ui.ctx(),
282260
item_id.into(),
@@ -293,11 +271,11 @@ impl HierarchicalDragAndDrop {
293271
self.container_children_ui(ui, children);
294272
});
295273

296-
self.handle_interaction(
274+
self.handle_drag_and_drop_interaction(
297275
ui,
298276
item_id,
299277
true,
300-
&header_resp.inner,
278+
&head_response.inner.union(response),
301279
body_resp.as_ref().map(|r| &r.response),
302280
);
303281
}
@@ -322,16 +300,11 @@ impl HierarchicalDragAndDrop {
322300
.selectable(false)
323301
.sense(egui::Sense::drag()),
324302
);
325-
// let response = re_ui
326-
// .list_item(label)
327-
// .selected(self.selected(item_id))
328-
// .draggable(true)
329-
// .show(ui);
330303

331-
self.handle_interaction(ui, item_id, false, &response, None);
304+
self.handle_drag_and_drop_interaction(ui, item_id, false, &response, None);
332305
}
333306

334-
fn handle_interaction(
307+
fn handle_drag_and_drop_interaction(
335308
&self,
336309
ui: &egui::Ui,
337310
item_id: ItemId,
@@ -340,31 +313,15 @@ impl HierarchicalDragAndDrop {
340313
body_response: Option<&egui::Response>,
341314
) {
342315
//
343-
// basic selection management
344-
//
345-
346-
if response.clicked() {
347-
if ui.input(|i| i.modifiers.command) {
348-
self.send_command(Command::ToggleSelected(item_id));
349-
} else {
350-
self.send_command(Command::SetSelection(item_id));
351-
}
352-
}
353-
354-
//
355-
// handle drag
316+
// handle start of drag
356317
//
357318

358319
if response.drag_started() {
359-
// Here, we support dragging a single item at a time, so we set the selection to the dragged item
360-
// if/when we're dragging it proper.
361-
self.send_command(Command::SetSelection(item_id));
362-
363320
egui::DragAndDrop::set_payload(ui.ctx(), item_id);
364321
}
365322

366323
//
367-
// handle drop
324+
// handle candidate drop
368325
//
369326

370327
// find the item being dragged
@@ -397,11 +354,28 @@ impl HierarchicalDragAndDrop {
397354
previous_container_id,
398355
};
399356

357+
//
358+
// compute the drag target areas based on the item and body responses
359+
//
360+
361+
// adjust the drop target to account for the spacing between items
362+
let item_rect = response
363+
.rect
364+
.expand2(egui::Vec2::new(0.0, ui.spacing().item_spacing.y / 2.0));
365+
let body_rect = body_response.map(|r| {
366+
r.rect
367+
.expand2(egui::Vec2::new(0.0, ui.spacing().item_spacing.y))
368+
});
369+
370+
//
371+
// find the candidate drop target
372+
//
373+
400374
let drop_target = crate::drag_and_drop::find_drop_target(
401375
ui,
402376
&item_desc,
403-
response.rect,
404-
body_response.map(|r| r.rect),
377+
item_rect,
378+
body_rect,
405379
response.rect.height(),
406380
);
407381

@@ -413,10 +387,13 @@ impl HierarchicalDragAndDrop {
413387
return;
414388
}
415389

390+
// extend the cursor to the right of the enclosing container
391+
let mut span_x = drop_target.indicator_span_x;
392+
span_x.max = ui.cursor().right();
393+
416394
ui.painter().hline(
417-
drop_target.indicator_span_x,
395+
span_x,
418396
drop_target.indicator_position_y,
419-
//TODO: use style
420397
(2.0, egui::Color32::BLACK),
421398
);
422399

examples/hierachical_list_drag_and_drop/src/drag_and_drop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ pub fn find_drop_target<ItemId: Copy>(
211211
);
212212
ui.ctx().debug_painter().debug_rect(
213213
body_insert_after_me_area,
214-
egui::Color32::YELLOW,
214+
egui::Color32::BLUE.gamma_multiply(0.5),
215215
"bdy",
216216
);
217217
}

examples/hierachical_list_drag_and_drop/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ fn main() -> Result<(), eframe::Error> {
1515
eframe::run_native(
1616
"My egui App",
1717
options,
18-
Box::new(|cc| Box::<HierarchicalDragAndDrop>::default()),
18+
Box::new(|_cc| Box::<HierarchicalDragAndDrop>::default()),
1919
)
2020
}

0 commit comments

Comments
 (0)