dock: Add drag drop event for tiles (#640)

This commit is contained in:
ihavecoke 2025-02-19 22:20:48 +08:00 committed by GitHub
parent 75212c3aba
commit 6c39078e8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 45 additions and 2 deletions

View file

@ -61,6 +61,9 @@ impl StoryTiles {
window, window,
|this, dock_area, ev: &DockEvent, window, cx| match ev { |this, dock_area, ev: &DockEvent, window, cx| match ev {
DockEvent::LayoutChanged => this.save_layout(dock_area, window, cx), DockEvent::LayoutChanged => this.save_layout(dock_area, window, cx),
DockEvent::DragDrop(item) => {
println!("drag drop: {:?}", item);
}
}, },
) )
.detach(); .detach();

View file

@ -79,6 +79,7 @@ impl StoryWorkspace {
window, window,
|this, dock_area, ev: &DockEvent, window, cx| match ev { |this, dock_area, ev: &DockEvent, window, cx| match ev {
DockEvent::LayoutChanged => this.save_layout(dock_area, window, cx), DockEvent::LayoutChanged => this.save_layout(dock_area, window, cx),
_ => {}
}, },
) )
.detach(); .detach();

View file

@ -33,6 +33,9 @@ pub enum DockEvent {
/// This event is emitted when every time the layout of the dock has changed, /// 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. /// So it emits may be too frequently, you may want to debounce the event.
LayoutChanged, LayoutChanged,
/// The drag item drop event.
DragDrop(AnyDrag),
} }
/// The main area of the dock. /// The main area of the dock.
@ -217,6 +220,7 @@ impl DockItem {
move |window, cx| { move |window, cx| {
_ = dock_area.update(cx, |this, cx| { _ = dock_area.update(cx, |this, cx| {
this.subscribe_panel(&tile_panel, window, cx); this.subscribe_panel(&tile_panel, window, cx);
this.subscribe_tiles_item_drop(&tile_panel, window, cx);
}); });
} }
}); });
@ -418,6 +422,20 @@ impl DockArea {
this this
} }
/// Subscribe to the tiles item drag item drop event
fn subscribe_tiles_item_drop(
&mut self,
tile_panel: &Entity<Tiles>,
_: &mut Window,
cx: &mut Context<Self>,
) {
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. /// Set the panel style of the dock area.
pub fn panel_style(mut self, style: PanelStyle) -> Self { pub fn panel_style(mut self, style: PanelStyle) -> Self {
self.panel_style = style; self.panel_style = style;

View file

@ -1,4 +1,5 @@
use std::{ use std::{
any::Any,
cell::Cell, cell::Cell,
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},
rc::Rc, rc::Rc,
@ -109,6 +110,19 @@ impl TileItem {
} }
} }
#[derive(Clone, Debug)]
pub struct AnyDrag {
pub value: Arc<dyn Any>,
}
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. /// Tiles is a canvas that can contain multiple panels, each of which can be dragged and resized.
pub struct Tiles { pub struct Tiles {
focus_handle: FocusHandle, focus_handle: FocusHandle,
@ -157,6 +171,11 @@ impl Panel for Tiles {
} }
} }
#[derive(Clone, Debug)]
pub struct DragDrop(pub AnyDrag);
impl EventEmitter<DragDrop> for Tiles {}
impl Tiles { impl Tiles {
pub fn new(_: &mut Window, cx: &mut Context<Self>) -> Self { pub fn new(_: &mut Window, cx: &mut Context<Self>) -> Self {
Self { Self {
@ -339,7 +358,6 @@ impl Tiles {
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
self.panels.push(item.clone()); self.panels.push(item.clone());
window.defer(cx, { window.defer(cx, {
let panel = item.panel.clone(); let panel = item.panel.clone();
let dock_area = dock_area.clone(); let dock_area = dock_area.clone();
@ -892,7 +910,10 @@ impl Render for Tiles {
) )
.absolute() .absolute()
.size_full() .size_full()
}), })
.on_drop(cx.listener(move |_, item: &AnyDrag, _, cx| {
cx.emit(DragDrop(item.clone()));
})),
) )
.on_mouse_up( .on_mouse_up(
MouseButton::Left, MouseButton::Left,