events.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. use crate::events::HasKeyboardData;
  2. use crate::events::{
  3. AnimationData, CompositionData, KeyboardData, MouseData, PointerData, TouchData,
  4. TransitionData, WheelData,
  5. };
  6. use crate::file_data::HasFileData;
  7. use crate::geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint};
  8. use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton};
  9. use crate::prelude::*;
  10. use keyboard_types::{Code, Key, Modifiers};
  11. use std::str::FromStr;
  12. use wasm_bindgen::JsCast;
  13. use web_sys::{
  14. AnimationEvent, CompositionEvent, Event, KeyboardEvent, MouseEvent, PointerEvent, Touch,
  15. TouchEvent, TransitionEvent, WheelEvent,
  16. };
  17. macro_rules! uncheck_convert {
  18. ($t:ty, $d:ty) => {
  19. impl From<Event> for $d {
  20. #[inline]
  21. fn from(e: Event) -> Self {
  22. let e: $t = e.unchecked_into();
  23. Self::from(e)
  24. }
  25. }
  26. impl From<&Event> for $d {
  27. #[inline]
  28. fn from(e: &Event) -> Self {
  29. let e: &$t = e.unchecked_ref();
  30. Self::from(e.clone())
  31. }
  32. }
  33. };
  34. ($($t:ty => $d:ty),+ $(,)?) => {
  35. $(uncheck_convert!($t, $d);)+
  36. };
  37. }
  38. uncheck_convert![
  39. web_sys::CompositionEvent => CompositionData,
  40. web_sys::KeyboardEvent => KeyboardData,
  41. web_sys::MouseEvent => MouseData,
  42. web_sys::TouchEvent => TouchData,
  43. web_sys::PointerEvent => PointerData,
  44. web_sys::WheelEvent => WheelData,
  45. web_sys::AnimationEvent => AnimationData,
  46. web_sys::TransitionEvent => TransitionData,
  47. web_sys::MouseEvent => DragData,
  48. web_sys::FocusEvent => FocusData,
  49. ];
  50. impl HasCompositionData for CompositionEvent {
  51. fn data(&self) -> std::string::String {
  52. self.data().unwrap_or_default()
  53. }
  54. fn as_any(&self) -> &dyn std::any::Any {
  55. self
  56. }
  57. }
  58. impl HasKeyboardData for KeyboardEvent {
  59. fn key(&self) -> Key {
  60. Key::from_str(self.key().as_str()).unwrap_or(Key::Unidentified)
  61. }
  62. fn code(&self) -> Code {
  63. Code::from_str(self.code().as_str()).unwrap_or(Code::Unidentified)
  64. }
  65. fn location(&self) -> keyboard_types::Location {
  66. decode_key_location(self.location() as usize)
  67. }
  68. fn is_auto_repeating(&self) -> bool {
  69. self.repeat()
  70. }
  71. fn is_composing(&self) -> bool {
  72. self.is_composing()
  73. }
  74. fn as_any(&self) -> &dyn std::any::Any {
  75. self
  76. }
  77. }
  78. impl ModifiersInteraction for KeyboardEvent {
  79. fn modifiers(&self) -> Modifiers {
  80. let mut modifiers = Modifiers::empty();
  81. if self.alt_key() {
  82. modifiers.insert(Modifiers::ALT);
  83. }
  84. if self.ctrl_key() {
  85. modifiers.insert(Modifiers::CONTROL);
  86. }
  87. if self.meta_key() {
  88. modifiers.insert(Modifiers::META);
  89. }
  90. if self.shift_key() {
  91. modifiers.insert(Modifiers::SHIFT);
  92. }
  93. modifiers
  94. }
  95. }
  96. impl InteractionLocation for MouseEvent {
  97. fn client_coordinates(&self) -> ClientPoint {
  98. ClientPoint::new(self.client_x().into(), self.client_y().into())
  99. }
  100. fn page_coordinates(&self) -> PagePoint {
  101. PagePoint::new(self.page_x().into(), self.page_y().into())
  102. }
  103. fn screen_coordinates(&self) -> ScreenPoint {
  104. ScreenPoint::new(self.screen_x().into(), self.screen_y().into())
  105. }
  106. }
  107. impl InteractionElementOffset for MouseEvent {
  108. fn element_coordinates(&self) -> ElementPoint {
  109. ElementPoint::new(self.offset_x().into(), self.offset_y().into())
  110. }
  111. }
  112. impl ModifiersInteraction for MouseEvent {
  113. fn modifiers(&self) -> Modifiers {
  114. let mut modifiers = Modifiers::empty();
  115. if self.alt_key() {
  116. modifiers.insert(Modifiers::ALT);
  117. }
  118. if self.ctrl_key() {
  119. modifiers.insert(Modifiers::CONTROL);
  120. }
  121. if self.meta_key() {
  122. modifiers.insert(Modifiers::META);
  123. }
  124. if self.shift_key() {
  125. modifiers.insert(Modifiers::SHIFT);
  126. }
  127. modifiers
  128. }
  129. }
  130. impl PointerInteraction for MouseEvent {
  131. fn held_buttons(&self) -> crate::input_data::MouseButtonSet {
  132. decode_mouse_button_set(self.buttons())
  133. }
  134. fn trigger_button(&self) -> Option<MouseButton> {
  135. Some(MouseButton::from_web_code(self.button()))
  136. }
  137. }
  138. impl HasMouseData for MouseEvent {
  139. fn as_any(&self) -> &dyn std::any::Any {
  140. self
  141. }
  142. }
  143. impl HasFileData for MouseEvent {}
  144. impl HasDragData for MouseEvent {
  145. fn as_any(&self) -> &dyn std::any::Any {
  146. self
  147. }
  148. }
  149. impl ModifiersInteraction for TouchEvent {
  150. fn modifiers(&self) -> Modifiers {
  151. let mut modifiers = Modifiers::empty();
  152. if self.alt_key() {
  153. modifiers.insert(Modifiers::ALT);
  154. }
  155. if self.ctrl_key() {
  156. modifiers.insert(Modifiers::CONTROL);
  157. }
  158. if self.meta_key() {
  159. modifiers.insert(Modifiers::META);
  160. }
  161. if self.shift_key() {
  162. modifiers.insert(Modifiers::SHIFT);
  163. }
  164. modifiers
  165. }
  166. }
  167. impl crate::events::HasTouchData for TouchEvent {
  168. fn touches(&self) -> Vec<TouchPoint> {
  169. let touches = TouchEvent::touches(self);
  170. let mut result = Vec::with_capacity(touches.length() as usize);
  171. for i in 0..touches.length() {
  172. let touch = touches.get(i).unwrap();
  173. result.push(TouchPoint::new(touch));
  174. }
  175. result
  176. }
  177. fn touches_changed(&self) -> Vec<TouchPoint> {
  178. let touches = self.changed_touches();
  179. let mut result = Vec::with_capacity(touches.length() as usize);
  180. for i in 0..touches.length() {
  181. let touch = touches.get(i).unwrap();
  182. result.push(TouchPoint::new(touch));
  183. }
  184. result
  185. }
  186. fn target_touches(&self) -> Vec<TouchPoint> {
  187. let touches = self.target_touches();
  188. let mut result = Vec::with_capacity(touches.length() as usize);
  189. for i in 0..touches.length() {
  190. let touch = touches.get(i).unwrap();
  191. result.push(TouchPoint::new(touch));
  192. }
  193. result
  194. }
  195. fn as_any(&self) -> &dyn std::any::Any {
  196. self
  197. }
  198. }
  199. impl HasTouchPointData for Touch {
  200. fn identifier(&self) -> i32 {
  201. self.identifier()
  202. }
  203. fn radius(&self) -> ScreenPoint {
  204. ScreenPoint::new(self.radius_x().into(), self.radius_y().into())
  205. }
  206. fn rotation(&self) -> f64 {
  207. self.rotation_angle() as f64
  208. }
  209. fn force(&self) -> f64 {
  210. self.force() as f64
  211. }
  212. fn as_any(&self) -> &dyn std::any::Any {
  213. self
  214. }
  215. }
  216. impl InteractionLocation for Touch {
  217. fn client_coordinates(&self) -> ClientPoint {
  218. ClientPoint::new(self.client_x().into(), self.client_y().into())
  219. }
  220. fn screen_coordinates(&self) -> ScreenPoint {
  221. ScreenPoint::new(self.screen_x().into(), self.screen_y().into())
  222. }
  223. fn page_coordinates(&self) -> PagePoint {
  224. PagePoint::new(self.page_x().into(), self.page_y().into())
  225. }
  226. }
  227. impl HasPointerData for PointerEvent {
  228. fn pointer_id(&self) -> i32 {
  229. self.pointer_id()
  230. }
  231. fn width(&self) -> i32 {
  232. self.width()
  233. }
  234. fn height(&self) -> i32 {
  235. self.height()
  236. }
  237. fn pressure(&self) -> f32 {
  238. self.pressure()
  239. }
  240. fn tangential_pressure(&self) -> f32 {
  241. self.tangential_pressure()
  242. }
  243. fn tilt_x(&self) -> i32 {
  244. self.tilt_x()
  245. }
  246. fn tilt_y(&self) -> i32 {
  247. self.tilt_y()
  248. }
  249. fn twist(&self) -> i32 {
  250. self.twist()
  251. }
  252. fn pointer_type(&self) -> String {
  253. self.pointer_type()
  254. }
  255. fn is_primary(&self) -> bool {
  256. self.is_primary()
  257. }
  258. fn as_any(&self) -> &dyn std::any::Any {
  259. self
  260. }
  261. }
  262. impl InteractionLocation for PointerEvent {
  263. fn client_coordinates(&self) -> ClientPoint {
  264. ClientPoint::new(self.client_x().into(), self.client_y().into())
  265. }
  266. fn screen_coordinates(&self) -> ScreenPoint {
  267. ScreenPoint::new(self.screen_x().into(), self.screen_y().into())
  268. }
  269. fn page_coordinates(&self) -> PagePoint {
  270. PagePoint::new(self.page_x().into(), self.page_y().into())
  271. }
  272. }
  273. impl InteractionElementOffset for PointerEvent {
  274. fn element_coordinates(&self) -> ElementPoint {
  275. ElementPoint::new(self.offset_x().into(), self.offset_y().into())
  276. }
  277. }
  278. impl ModifiersInteraction for PointerEvent {
  279. fn modifiers(&self) -> Modifiers {
  280. let mut modifiers = Modifiers::empty();
  281. if self.alt_key() {
  282. modifiers.insert(Modifiers::ALT);
  283. }
  284. if self.ctrl_key() {
  285. modifiers.insert(Modifiers::CONTROL);
  286. }
  287. if self.meta_key() {
  288. modifiers.insert(Modifiers::META);
  289. }
  290. if self.shift_key() {
  291. modifiers.insert(Modifiers::SHIFT);
  292. }
  293. modifiers
  294. }
  295. }
  296. impl PointerInteraction for PointerEvent {
  297. fn held_buttons(&self) -> crate::input_data::MouseButtonSet {
  298. decode_mouse_button_set(self.buttons())
  299. }
  300. fn trigger_button(&self) -> Option<MouseButton> {
  301. Some(MouseButton::from_web_code(self.button()))
  302. }
  303. }
  304. impl HasWheelData for WheelEvent {
  305. fn delta(&self) -> crate::geometry::WheelDelta {
  306. crate::geometry::WheelDelta::from_web_attributes(
  307. self.delta_mode(),
  308. self.delta_x(),
  309. self.delta_y(),
  310. self.delta_z(),
  311. )
  312. }
  313. fn as_any(&self) -> &dyn std::any::Any {
  314. self
  315. }
  316. }
  317. impl HasMouseData for WheelEvent {
  318. fn as_any(&self) -> &dyn std::any::Any {
  319. self
  320. }
  321. }
  322. impl InteractionLocation for WheelEvent {
  323. fn client_coordinates(&self) -> ClientPoint {
  324. ClientPoint::new(self.client_x().into(), self.client_y().into())
  325. }
  326. fn screen_coordinates(&self) -> ScreenPoint {
  327. ScreenPoint::new(self.screen_x().into(), self.screen_y().into())
  328. }
  329. fn page_coordinates(&self) -> PagePoint {
  330. PagePoint::new(self.page_x().into(), self.page_y().into())
  331. }
  332. }
  333. impl InteractionElementOffset for WheelEvent {
  334. fn element_coordinates(&self) -> ElementPoint {
  335. ElementPoint::new(self.offset_x().into(), self.offset_y().into())
  336. }
  337. }
  338. impl ModifiersInteraction for WheelEvent {
  339. fn modifiers(&self) -> Modifiers {
  340. let mut modifiers = Modifiers::empty();
  341. if self.alt_key() {
  342. modifiers.insert(Modifiers::ALT);
  343. }
  344. if self.ctrl_key() {
  345. modifiers.insert(Modifiers::CONTROL);
  346. }
  347. if self.meta_key() {
  348. modifiers.insert(Modifiers::META);
  349. }
  350. if self.shift_key() {
  351. modifiers.insert(Modifiers::SHIFT);
  352. }
  353. modifiers
  354. }
  355. }
  356. impl PointerInteraction for WheelEvent {
  357. fn held_buttons(&self) -> crate::input_data::MouseButtonSet {
  358. decode_mouse_button_set(self.buttons())
  359. }
  360. fn trigger_button(&self) -> Option<MouseButton> {
  361. Some(MouseButton::from_web_code(self.button()))
  362. }
  363. }
  364. impl HasAnimationData for AnimationEvent {
  365. fn animation_name(&self) -> String {
  366. self.animation_name()
  367. }
  368. fn pseudo_element(&self) -> String {
  369. self.pseudo_element()
  370. }
  371. fn elapsed_time(&self) -> f32 {
  372. self.elapsed_time()
  373. }
  374. fn as_any(&self) -> &dyn std::any::Any {
  375. self
  376. }
  377. }
  378. impl HasTransitionData for TransitionEvent {
  379. fn elapsed_time(&self) -> f32 {
  380. self.elapsed_time()
  381. }
  382. fn property_name(&self) -> String {
  383. self.property_name()
  384. }
  385. fn pseudo_element(&self) -> String {
  386. self.pseudo_element()
  387. }
  388. fn as_any(&self) -> &dyn std::any::Any {
  389. self
  390. }
  391. }
  392. #[cfg(feature = "mounted")]
  393. impl From<&web_sys::Element> for MountedData {
  394. fn from(e: &web_sys::Element) -> Self {
  395. MountedData::new(e.clone())
  396. }
  397. }
  398. #[cfg(feature = "mounted")]
  399. impl crate::RenderedElementBacking for web_sys::Element {
  400. fn get_scroll_offset(
  401. &self,
  402. ) -> std::pin::Pin<
  403. Box<
  404. dyn std::future::Future<Output = crate::MountedResult<crate::geometry::PixelsVector2D>>,
  405. >,
  406. > {
  407. let left = self.scroll_left();
  408. let top = self.scroll_top();
  409. let result = Ok(crate::geometry::PixelsVector2D::new(
  410. left as f64,
  411. top as f64,
  412. ));
  413. Box::pin(async { result })
  414. }
  415. fn get_scroll_size(
  416. &self,
  417. ) -> std::pin::Pin<
  418. Box<dyn std::future::Future<Output = crate::MountedResult<crate::geometry::PixelsSize>>>,
  419. > {
  420. let width = self.scroll_width();
  421. let height = self.scroll_height();
  422. let result = Ok(crate::geometry::PixelsSize::new(
  423. width as f64,
  424. height as f64,
  425. ));
  426. Box::pin(async { result })
  427. }
  428. fn get_client_rect(
  429. &self,
  430. ) -> std::pin::Pin<
  431. Box<dyn std::future::Future<Output = crate::MountedResult<crate::geometry::PixelsRect>>>,
  432. > {
  433. let rect = self.get_bounding_client_rect();
  434. let result = Ok(crate::geometry::PixelsRect::new(
  435. euclid::Point2D::new(rect.left(), rect.top()),
  436. euclid::Size2D::new(rect.width(), rect.height()),
  437. ));
  438. Box::pin(async { result })
  439. }
  440. fn as_any(&self) -> &dyn std::any::Any {
  441. self
  442. }
  443. fn scroll_to(
  444. &self,
  445. behavior: crate::ScrollBehavior,
  446. ) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<()>>>> {
  447. let options = web_sys::ScrollIntoViewOptions::new();
  448. match behavior {
  449. crate::ScrollBehavior::Instant => {
  450. options.set_behavior(web_sys::ScrollBehavior::Instant);
  451. }
  452. crate::ScrollBehavior::Smooth => {
  453. options.set_behavior(web_sys::ScrollBehavior::Smooth);
  454. }
  455. }
  456. self.scroll_into_view_with_scroll_into_view_options(&options);
  457. Box::pin(async { Ok(()) })
  458. }
  459. fn set_focus(
  460. &self,
  461. focus: bool,
  462. ) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<()>>>> {
  463. #[derive(Debug)]
  464. struct FocusError(wasm_bindgen::JsValue);
  465. impl std::fmt::Display for FocusError {
  466. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  467. write!(f, "failed to focus element {:?}", self.0)
  468. }
  469. }
  470. impl std::error::Error for FocusError {}
  471. let result = self
  472. .dyn_ref::<web_sys::HtmlElement>()
  473. .ok_or_else(|| crate::MountedError::OperationFailed(Box::new(FocusError(self.into()))))
  474. .and_then(|e| {
  475. (if focus { e.focus() } else { e.blur() })
  476. .map_err(|err| crate::MountedError::OperationFailed(Box::new(FocusError(err))))
  477. });
  478. Box::pin(async { result })
  479. }
  480. }
  481. impl HasScrollData for Event {
  482. fn as_any(&self) -> &dyn std::any::Any {
  483. self
  484. }
  485. }
  486. impl HasClipboardData for Event {
  487. fn as_any(&self) -> &dyn std::any::Any {
  488. self
  489. }
  490. }
  491. impl From<&Event> for ClipboardData {
  492. fn from(e: &Event) -> Self {
  493. ClipboardData::new(e.clone())
  494. }
  495. }
  496. impl HasFocusData for web_sys::FocusEvent {
  497. fn as_any(&self) -> &dyn std::any::Any {
  498. self
  499. }
  500. }
  501. impl HasToggleData for web_sys::Event {
  502. fn as_any(&self) -> &dyn std::any::Any {
  503. self
  504. }
  505. }
  506. impl HasSelectionData for web_sys::Event {
  507. fn as_any(&self) -> &dyn std::any::Any {
  508. self
  509. }
  510. }
  511. impl HasMediaData for web_sys::Event {
  512. fn as_any(&self) -> &dyn std::any::Any {
  513. self
  514. }
  515. }
  516. impl HasFileData for web_sys::Event {
  517. #[cfg(feature = "file-engine")]
  518. fn files(&self) -> Option<std::sync::Arc<dyn crate::file_data::FileEngine>> {
  519. let files = self
  520. .dyn_ref()
  521. .and_then(|input: &web_sys::HtmlInputElement| {
  522. input.files().and_then(|files| {
  523. #[allow(clippy::arc_with_non_send_sync)]
  524. crate::web_sys_bind::file_engine::WebFileEngine::new(files)
  525. .map(|f| std::sync::Arc::new(f) as std::sync::Arc<dyn crate::FileEngine>)
  526. })
  527. });
  528. files
  529. }
  530. }