From 6c39078e8a7b73364a4f9f1e6c018ccac4347c97 Mon Sep 17 00:00:00 2001 From: ihavecoke Date: Wed, 19 Feb 2025 22:20:48 +0800 Subject: [PATCH] dock: Add drag drop event for tiles (#640) --- crates/story/examples/tiles.rs | 3 +++ crates/story/src/main.rs | 1 + crates/ui/src/dock/mod.rs | 18 ++++++++++++++++++ crates/ui/src/dock/tiles.rs | 25 +++++++++++++++++++++++-- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/crates/story/examples/tiles.rs b/crates/story/examples/tiles.rs index f1613639..ece92804 100644 --- a/crates/story/examples/tiles.rs +++ b/crates/story/examples/tiles.rs @@ -61,6 +61,9 @@ impl StoryTiles { window, |this, dock_area, ev: &DockEvent, window, cx| match ev { DockEvent::LayoutChanged => this.save_layout(dock_area, window, cx), + DockEvent::DragDrop(item) => { + println!("drag drop: {:?}", item); + } }, ) .detach(); diff --git a/crates/story/src/main.rs b/crates/story/src/main.rs index 20a781cb..3756a317 100644 --- a/crates/story/src/main.rs +++ b/crates/story/src/main.rs @@ -79,6 +79,7 @@ impl StoryWorkspace { window, |this, dock_area, ev: &DockEvent, window, cx| match ev { DockEvent::LayoutChanged => this.save_layout(dock_area, window, cx), + _ => {} }, ) .detach(); diff --git a/crates/ui/src/dock/mod.rs b/crates/ui/src/dock/mod.rs index 27a5798d..1821309d 100644 --- a/crates/ui/src/dock/mod.rs +++ b/crates/ui/src/dock/mod.rs @@ -33,6 +33,9 @@ pub enum DockEvent { /// This event is emitted when every time the layout of the dock has changed, /// So it emits may be too frequently, you may want to debounce the event. LayoutChanged, + + /// The drag item drop event. + DragDrop(AnyDrag), } /// The main area of the dock. @@ -217,6 +220,7 @@ impl DockItem { move |window, cx| { _ = dock_area.update(cx, |this, cx| { this.subscribe_panel(&tile_panel, window, cx); + this.subscribe_tiles_item_drop(&tile_panel, window, cx); }); } }); @@ -418,6 +422,20 @@ impl DockArea { this } + /// Subscribe to the tiles item drag item drop event + fn subscribe_tiles_item_drop( + &mut self, + tile_panel: &Entity, + _: &mut Window, + cx: &mut Context, + ) { + self._subscriptions + .push(cx.subscribe(tile_panel, move |_, _, evt: &DragDrop, cx| { + let item = evt.0.clone(); + cx.emit(DockEvent::DragDrop(item)); + })); + } + /// Set the panel style of the dock area. pub fn panel_style(mut self, style: PanelStyle) -> Self { self.panel_style = style; diff --git a/crates/ui/src/dock/tiles.rs b/crates/ui/src/dock/tiles.rs index 782b36b8..89172091 100644 --- a/crates/ui/src/dock/tiles.rs +++ b/crates/ui/src/dock/tiles.rs @@ -1,4 +1,5 @@ use std::{ + any::Any, cell::Cell, fmt::{Debug, Formatter}, rc::Rc, @@ -109,6 +110,19 @@ impl TileItem { } } +#[derive(Clone, Debug)] +pub struct AnyDrag { + pub value: Arc, +} + +impl AnyDrag { + pub fn new(value: impl Any) -> Self { + Self { + value: Arc::new(value), + } + } +} + /// Tiles is a canvas that can contain multiple panels, each of which can be dragged and resized. pub struct Tiles { focus_handle: FocusHandle, @@ -157,6 +171,11 @@ impl Panel for Tiles { } } +#[derive(Clone, Debug)] +pub struct DragDrop(pub AnyDrag); + +impl EventEmitter for Tiles {} + impl Tiles { pub fn new(_: &mut Window, cx: &mut Context) -> Self { Self { @@ -339,7 +358,6 @@ impl Tiles { cx: &mut Context, ) { self.panels.push(item.clone()); - window.defer(cx, { let panel = item.panel.clone(); let dock_area = dock_area.clone(); @@ -892,7 +910,10 @@ impl Render for Tiles { ) .absolute() .size_full() - }), + }) + .on_drop(cx.listener(move |_, item: &AnyDrag, _, cx| { + cx.emit(DragDrop(item.clone())); + })), ) .on_mouse_up( MouseButton::Left,