egui_cha/
drag_drop.rs

1//! Drag & Drop support for TEA pattern
2//!
3//! Provides type-safe drag and drop with message emission.
4
5use std::sync::Arc;
6
7use crate::ViewCtx;
8
9/// Response from a drag source
10pub struct DragSourceResponse<R> {
11    /// The return value from the content closure
12    pub inner: R,
13    /// The egui response
14    pub response: egui::Response,
15    /// Whether a drag was started this frame
16    pub drag_started: bool,
17}
18
19impl<R> DragSourceResponse<R> {
20    /// Emit a message when drag starts
21    pub fn on_drag_start<Msg>(self, ctx: &mut ViewCtx<'_, Msg>, msg: Msg) -> Self {
22        if self.drag_started {
23            ctx.emit(msg);
24        }
25        self
26    }
27
28    /// Map the inner value
29    pub fn map<U>(self, f: impl FnOnce(R) -> U) -> DragSourceResponse<U> {
30        DragSourceResponse {
31            inner: f(self.inner),
32            response: self.response,
33            drag_started: self.drag_started,
34        }
35    }
36}
37
38/// Response from a drop zone
39pub struct DropZoneResponse<P, R> {
40    /// The return value from the content closure
41    pub inner: R,
42    /// The egui response
43    pub response: egui::Response,
44    /// The payload if one was dropped
45    pub payload: Option<Arc<P>>,
46    /// Whether a compatible payload is being dragged over this zone
47    pub is_being_dragged_over: bool,
48}
49
50impl<P, R> DropZoneResponse<P, R> {
51    /// Emit a message when a payload is dropped
52    pub fn on_drop<Msg, F>(self, ctx: &mut ViewCtx<'_, Msg>, f: F) -> Self
53    where
54        F: FnOnce(Arc<P>) -> Msg,
55    {
56        if let Some(ref payload) = self.payload {
57            ctx.emit(f(Arc::clone(payload)));
58        }
59        self
60    }
61
62    /// Emit a message when hovering with a compatible payload
63    pub fn on_hover<Msg>(self, ctx: &mut ViewCtx<'_, Msg>, msg: Msg) -> Self {
64        if self.is_being_dragged_over {
65            ctx.emit(msg);
66        }
67        self
68    }
69
70    /// Map the inner value
71    pub fn map<U>(self, f: impl FnOnce(R) -> U) -> DropZoneResponse<P, U> {
72        DropZoneResponse {
73            inner: f(self.inner),
74            response: self.response,
75            payload: self.payload,
76            is_being_dragged_over: self.is_being_dragged_over,
77        }
78    }
79}