dioxus_web/events/
drag.rs1use crate::{WebDataTransfer, WebFileData, WebFileEngine};
2
3use super::{Synthetic, WebEventExt};
4use dioxus_html::{
5 FileData, HasDataTransferData, HasDragData, HasFileData, HasMouseData,
6 InteractionElementOffset, InteractionLocation, Modifiers, ModifiersInteraction,
7 PointerInteraction,
8 geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint},
9 input_data::{MouseButton, decode_mouse_button_set},
10};
11use web_sys::{DragEvent, FileReader};
12
13impl InteractionLocation for Synthetic<DragEvent> {
14 fn client_coordinates(&self) -> ClientPoint {
15 ClientPoint::new(self.event.client_x().into(), self.event.client_y().into())
16 }
17
18 fn page_coordinates(&self) -> PagePoint {
19 PagePoint::new(self.event.page_x().into(), self.event.page_y().into())
20 }
21
22 fn screen_coordinates(&self) -> ScreenPoint {
23 ScreenPoint::new(self.event.screen_x().into(), self.event.screen_y().into())
24 }
25}
26
27impl InteractionElementOffset for Synthetic<DragEvent> {
28 fn element_coordinates(&self) -> ElementPoint {
29 ElementPoint::new(self.event.offset_x().into(), self.event.offset_y().into())
30 }
31}
32
33impl ModifiersInteraction for Synthetic<DragEvent> {
34 fn modifiers(&self) -> Modifiers {
35 let mut modifiers = Modifiers::empty();
36
37 if self.event.alt_key() {
38 modifiers.insert(Modifiers::ALT);
39 }
40 if self.event.ctrl_key() {
41 modifiers.insert(Modifiers::CONTROL);
42 }
43 if self.event.meta_key() {
44 modifiers.insert(Modifiers::META);
45 }
46 if self.event.shift_key() {
47 modifiers.insert(Modifiers::SHIFT);
48 }
49
50 modifiers
51 }
52}
53
54impl PointerInteraction for Synthetic<DragEvent> {
55 fn held_buttons(&self) -> dioxus_html::input_data::MouseButtonSet {
56 decode_mouse_button_set(self.event.buttons())
57 }
58
59 fn trigger_button(&self) -> Option<MouseButton> {
60 Some(MouseButton::from_web_code(self.event.button()))
61 }
62}
63
64impl HasMouseData for Synthetic<DragEvent> {
65 fn as_any(&self) -> &dyn std::any::Any {
66 &self.event
67 }
68}
69
70impl HasDragData for Synthetic<DragEvent> {
71 fn as_any(&self) -> &dyn std::any::Any {
72 &self.event
73 }
74}
75
76impl HasDataTransferData for Synthetic<DragEvent> {
77 fn data_transfer(&self) -> dioxus_html::DataTransfer {
78 use wasm_bindgen::JsCast;
79
80 if let Some(target) = self.event.dyn_ref::<web_sys::DragEvent>()
81 && let Some(data) = target.data_transfer()
82 {
83 let web_data_transfer = WebDataTransfer::new(data);
84 return dioxus_html::DataTransfer::new(web_data_transfer);
85 }
86
87 let web_data_transfer = WebDataTransfer::new(web_sys::DataTransfer::new().unwrap());
89 dioxus_html::DataTransfer::new(web_data_transfer)
90 }
91}
92
93impl HasFileData for Synthetic<DragEvent> {
94 fn files(&self) -> Vec<FileData> {
95 use wasm_bindgen::JsCast;
96
97 if let Some(target) = self.event.dyn_ref::<web_sys::DragEvent>() {
98 if let Some(data_transfer) = target.data_transfer() {
99 if let Some(file_list) = data_transfer.files() {
100 return WebFileEngine::new(file_list).to_files();
101 } else {
102 let items = data_transfer.items();
103 let mut files = vec![];
104 for i in 0..items.length() {
105 if let Some(item) = items.get(i)
106 && item.kind() == "file"
107 && let Ok(Some(file)) = item.get_as_file()
108 {
109 let web_data = WebFileData::new(file, FileReader::new().unwrap());
110 files.push(FileData::new(web_data));
111 }
112 }
113 return files;
114 }
115 }
116 } else {
117 tracing::warn!("DragEvent target was not a DragEvent");
118 }
119
120 vec![]
121 }
122}
123
124impl WebEventExt for dioxus_html::DragData {
125 type WebEvent = web_sys::DragEvent;
126
127 #[inline(always)]
128 fn try_as_web_event(&self) -> Option<web_sys::DragEvent> {
129 self.downcast::<DragEvent>().cloned()
130 }
131}