dioxus_html/events/
drag.rs1use crate::input_data::{MouseButton, MouseButtonSet};
2use crate::*;
3use crate::{
4 data_transfer::DataTransfer,
5 geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint},
6};
7
8use dioxus_core::Event;
9use keyboard_types::Modifiers;
10
11use crate::HasMouseData;
12
13pub type DragEvent = Event<DragData>;
14
15pub struct DragData {
20 inner: Box<dyn HasDragData>,
21}
22
23impl<E: HasDragData + 'static> From<E> for DragData {
24 fn from(e: E) -> Self {
25 Self { inner: Box::new(e) }
26 }
27}
28
29impl std::fmt::Debug for DragData {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.debug_struct("DragData")
32 .field("coordinates", &self.coordinates())
33 .field("modifiers", &self.modifiers())
34 .field("held_buttons", &self.held_buttons())
35 .field("trigger_button", &self.trigger_button())
36 .finish()
37 }
38}
39
40impl PartialEq for DragData {
41 fn eq(&self, other: &Self) -> bool {
42 self.coordinates() == other.coordinates()
43 && self.modifiers() == other.modifiers()
44 && self.held_buttons() == other.held_buttons()
45 && self.trigger_button() == other.trigger_button()
46 }
47}
48
49impl DragData {
50 pub fn new(inner: impl HasDragData + 'static) -> Self {
52 Self {
53 inner: Box::new(inner),
54 }
55 }
56
57 pub fn data_transfer(&self) -> DataTransfer {
59 self.inner.data_transfer()
60 }
61
62 #[inline(always)]
64 pub fn downcast<T: 'static>(&self) -> Option<&T> {
65 HasDragData::as_any(&*self.inner).downcast_ref::<T>()
66 }
67}
68
69impl crate::HasFileData for DragData {
70 fn files(&self) -> Vec<FileData> {
71 self.inner.files()
72 }
73}
74
75impl InteractionLocation for DragData {
76 fn client_coordinates(&self) -> ClientPoint {
77 self.inner.client_coordinates()
78 }
79
80 fn page_coordinates(&self) -> PagePoint {
81 self.inner.page_coordinates()
82 }
83
84 fn screen_coordinates(&self) -> ScreenPoint {
85 self.inner.screen_coordinates()
86 }
87}
88
89impl InteractionElementOffset for DragData {
90 fn element_coordinates(&self) -> ElementPoint {
91 self.inner.element_coordinates()
92 }
93
94 fn coordinates(&self) -> Coordinates {
95 self.inner.coordinates()
96 }
97}
98
99impl ModifiersInteraction for DragData {
100 fn modifiers(&self) -> Modifiers {
101 self.inner.modifiers()
102 }
103}
104
105impl PointerInteraction for DragData {
106 fn held_buttons(&self) -> MouseButtonSet {
107 self.inner.held_buttons()
108 }
109
110 fn trigger_button(&self) -> Option<MouseButton> {
112 self.inner.trigger_button()
113 }
114}
115
116#[cfg(feature = "serialize")]
117pub use ser::*;
118
119#[cfg(feature = "serialize")]
120mod ser {
121 use super::*;
122
123 #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
125 pub struct SerializedDragData {
126 pub mouse: crate::point_interaction::SerializedPointInteraction,
127
128 pub data_transfer: crate::data_transfer::SerializedDataTransfer,
129 }
130
131 impl SerializedDragData {
132 fn new(drag: &DragData) -> Self {
133 Self {
134 mouse: crate::point_interaction::SerializedPointInteraction::from(drag),
135 data_transfer: crate::data_transfer::SerializedDataTransfer::from(drag),
136 }
137 }
138 }
139
140 impl HasDataTransferData for SerializedDragData {
141 fn data_transfer(&self) -> crate::data_transfer::DataTransfer {
142 crate::data_transfer::DataTransfer::new(self.data_transfer.clone())
143 }
144 }
145
146 impl HasDragData for SerializedDragData {
147 fn as_any(&self) -> &dyn std::any::Any {
148 self
149 }
150 }
151
152 impl crate::file_data::HasFileData for SerializedDragData {
153 fn files(&self) -> Vec<FileData> {
154 self.data_transfer
155 .files
156 .iter()
157 .map(|f| FileData::new(f.clone()))
158 .collect()
159 }
160 }
161
162 impl HasMouseData for SerializedDragData {
163 fn as_any(&self) -> &dyn std::any::Any {
164 self
165 }
166 }
167
168 impl InteractionLocation for SerializedDragData {
169 fn client_coordinates(&self) -> ClientPoint {
170 self.mouse.client_coordinates()
171 }
172
173 fn page_coordinates(&self) -> PagePoint {
174 self.mouse.page_coordinates()
175 }
176
177 fn screen_coordinates(&self) -> ScreenPoint {
178 self.mouse.screen_coordinates()
179 }
180 }
181
182 impl InteractionElementOffset for SerializedDragData {
183 fn element_coordinates(&self) -> ElementPoint {
184 self.mouse.element_coordinates()
185 }
186
187 fn coordinates(&self) -> Coordinates {
188 self.mouse.coordinates()
189 }
190 }
191
192 impl ModifiersInteraction for SerializedDragData {
193 fn modifiers(&self) -> Modifiers {
194 self.mouse.modifiers()
195 }
196 }
197
198 impl PointerInteraction for SerializedDragData {
199 fn held_buttons(&self) -> MouseButtonSet {
200 self.mouse.held_buttons()
201 }
202
203 fn trigger_button(&self) -> Option<MouseButton> {
204 self.mouse.trigger_button()
205 }
206 }
207
208 impl serde::Serialize for DragData {
209 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
210 SerializedDragData::new(self).serialize(serializer)
211 }
212 }
213
214 impl<'de> serde::Deserialize<'de> for DragData {
215 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
216 let data = SerializedDragData::deserialize(deserializer)?;
217 Ok(Self {
218 inner: Box::new(data),
219 })
220 }
221 }
222}
223
224pub trait HasDragData: HasMouseData + crate::HasFileData + crate::HasDataTransferData {
226 fn as_any(&self) -> &dyn std::any::Any;
228}
229
230impl_event! {
231 DragData;
232
233 ondrag
235
236 ondragend
238
239 ondragenter
241
242 ondragexit
244
245 ondragleave
247
248 ondragover
250
251 ondragstart
253
254 ondrop
256}