1use gpui::prelude::*;
4use gpui::{div, AnyElement, App, ElementId, IntoElement, SharedString, Window};
5
6use super::chip::DragChip;
7use crate::devtools::Probed;
8
9#[derive(IntoElement)]
18pub struct Draggable<T: Clone + 'static> {
19 id: ElementId,
20 payload: T,
21 label: SharedString,
22 child: Option<AnyElement>,
23}
24
25impl<T: Clone + 'static> Draggable<T> {
26 pub fn new(id: impl Into<ElementId>, payload: T) -> Self {
27 Draggable {
28 id: id.into(),
29 payload,
30 label: SharedString::new_static("…"),
31 child: None,
32 }
33 }
34
35 pub fn label(mut self, label: impl Into<SharedString>) -> Self {
37 self.label = label.into();
38 self
39 }
40
41 pub fn child(mut self, child: impl IntoElement) -> Self {
42 self.child = Some(child.into_any_element());
43 self
44 }
45}
46
47impl<T: Clone + 'static> RenderOnce for Draggable<T> {
48 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
49 let chip = DragChip {
50 value: self.payload,
51 label: self.label,
52 };
53 let mut root = div()
54 .id(self.id)
55 .cursor_grab()
56 .on_drag(chip, |dragged: &DragChip<T>, _offset, _window, cx| {
57 cx.new(|_| dragged.clone())
58 });
59 if let Some(child) = self.child {
60 root = root.child(child);
61 }
62 root.probe("Draggable")
63 }
64}