use crate::{WebDataTransfer, WebFileData, WebFileEngine}; use super::{Synthetic, WebEventExt}; use dioxus_html::{ geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint}, input_data::{decode_mouse_button_set, MouseButton}, FileData, HasDataTransferData, HasDragData, HasFileData, HasMouseData, InteractionElementOffset, InteractionLocation, Modifiers, ModifiersInteraction, PointerInteraction, }; use web_sys::{DragEvent, FileReader}; impl InteractionLocation for Synthetic { fn client_coordinates(&self) -> ClientPoint { ClientPoint::new(self.event.client_x().into(), self.event.client_y().into()) } fn page_coordinates(&self) -> PagePoint { PagePoint::new(self.event.page_x().into(), self.event.page_y().into()) } fn screen_coordinates(&self) -> ScreenPoint { ScreenPoint::new(self.event.screen_x().into(), self.event.screen_y().into()) } } impl InteractionElementOffset for Synthetic { fn element_coordinates(&self) -> ElementPoint { ElementPoint::new(self.event.offset_x().into(), self.event.offset_y().into()) } } impl ModifiersInteraction for Synthetic { fn modifiers(&self) -> Modifiers { let mut modifiers = Modifiers::empty(); if self.event.alt_key() { modifiers.insert(Modifiers::ALT); } if self.event.ctrl_key() { modifiers.insert(Modifiers::CONTROL); } if self.event.meta_key() { modifiers.insert(Modifiers::META); } if self.event.shift_key() { modifiers.insert(Modifiers::SHIFT); } modifiers } } impl PointerInteraction for Synthetic { fn held_buttons(&self) -> dioxus_html::input_data::MouseButtonSet { decode_mouse_button_set(self.event.buttons()) } fn trigger_button(&self) -> Option { Some(MouseButton::from_web_code(self.event.button())) } } impl HasMouseData for Synthetic { fn as_any(&self) -> &dyn std::any::Any { &self.event } } impl HasDragData for Synthetic { fn as_any(&self) -> &dyn std::any::Any { &self.event } } impl HasDataTransferData for Synthetic { fn data_transfer(&self) -> dioxus_html::DataTransfer { use wasm_bindgen::JsCast; if let Some(target) = self.event.dyn_ref::() { if let Some(data) = target.data_transfer() { let web_data_transfer = WebDataTransfer::new(data); return dioxus_html::DataTransfer::new(web_data_transfer); } } // Return an empty DataTransfer if we couldn't get one from the event let web_data_transfer = WebDataTransfer::new(web_sys::DataTransfer::new().unwrap()); dioxus_html::DataTransfer::new(web_data_transfer) } } impl HasFileData for Synthetic { fn files(&self) -> Vec { use wasm_bindgen::JsCast; if let Some(target) = self.event.dyn_ref::() { if let Some(data_transfer) = target.data_transfer() { if let Some(file_list) = data_transfer.files() { return WebFileEngine::new(file_list).to_files(); } else { let items = data_transfer.items(); let mut files = vec![]; for i in 0..items.length() { if let Some(item) = items.get(i) { if item.kind() == "file" { if let Ok(Some(file)) = item.get_as_file() { let web_data = WebFileData::new(file, FileReader::new().unwrap()); files.push(FileData::new(web_data)); } } } } return files; } } } else { tracing::warn!("DragEvent target was not a DragEvent"); } vec![] } } impl WebEventExt for dioxus_html::DragData { type WebEvent = web_sys::DragEvent; #[inline(always)] fn try_as_web_event(&self) -> Option { self.downcast::().cloned() } }