events.rs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. //! An event system that's less confusing than Traits + RC;
  2. //! This should hopefully make it easier to port to other platforms.
  3. //!
  4. //! Unfortunately, it is less efficient than the original, but hopefully it's negligible.
  5. use crate::{
  6. innerlude::Listener,
  7. innerlude::{ElementId, NodeFactory, ScopeId},
  8. };
  9. use bumpalo::boxed::Box as BumpBox;
  10. use std::{
  11. any::Any,
  12. cell::{Cell, RefCell},
  13. fmt::Debug,
  14. ops::Deref,
  15. };
  16. pub use on::*;
  17. #[derive(Debug)]
  18. pub struct UserEvent {
  19. /// The originator of the event trigger
  20. pub scope: ScopeId,
  21. /// The optional real node associated with the trigger
  22. pub mounted_dom_id: Option<ElementId>,
  23. /// The event type IE "onclick" or "onmouseover"
  24. ///
  25. /// The name that the renderer will use to mount the listener.
  26. pub name: &'static str,
  27. /// The type of event
  28. pub event: SyntheticEvent,
  29. }
  30. #[derive(Debug)]
  31. pub enum SyntheticEvent {
  32. AnimationEvent(on::AnimationEvent),
  33. ClipboardEvent(on::ClipboardEvent),
  34. CompositionEvent(on::CompositionEvent),
  35. FocusEvent(on::FocusEvent),
  36. FormEvent(on::FormEvent),
  37. KeyboardEvent(on::KeyboardEvent),
  38. GenericEvent(DioxusEvent<()>),
  39. TouchEvent(on::TouchEvent),
  40. ToggleEvent(on::ToggleEvent),
  41. MediaEvent(on::MediaEvent),
  42. MouseEvent(on::MouseEvent),
  43. WheelEvent(on::WheelEvent),
  44. SelectionEvent(on::SelectionEvent),
  45. TransitionEvent(on::TransitionEvent),
  46. PointerEvent(on::PointerEvent),
  47. }
  48. /// Priority of Event Triggers.
  49. ///
  50. /// Internally, Dioxus will abort work that's taking too long if new, more important, work arrives. Unlike React, Dioxus
  51. /// won't be afraid to pause work or flush changes to the RealDOM. This is called "cooperative scheduling". Some Renderers
  52. /// implement this form of scheduling internally, however Dioxus will perform its own scheduling as well.
  53. ///
  54. /// The ultimate goal of the scheduler is to manage latency of changes, prioritizing "flashier" changes over "subtler" changes.
  55. ///
  56. /// React has a 5-tier priority system. However, they break things into "Continuous" and "Discrete" priority. For now,
  57. /// we keep it simple, and just use a 3-tier priority system.
  58. ///
  59. /// - NoPriority = 0
  60. /// - LowPriority = 1
  61. /// - NormalPriority = 2
  62. /// - UserBlocking = 3
  63. /// - HighPriority = 4
  64. /// - ImmediatePriority = 5
  65. ///
  66. /// We still have a concept of discrete vs continuous though - discrete events won't be batched, but continuous events will.
  67. /// This means that multiple "scroll" events will be processed in a single frame, but multiple "click" events will be
  68. /// flushed before proceeding. Multiple discrete events is highly unlikely, though.
  69. #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
  70. pub enum EventPriority {
  71. /// Work that must be completed during the EventHandler phase.
  72. ///
  73. /// Currently this is reserved for controlled inputs.
  74. Immediate = 3,
  75. /// "High Priority" work will not interrupt other high priority work, but will interrupt medium and low priority work.
  76. ///
  77. /// This is typically reserved for things like user interaction.
  78. ///
  79. /// React calls these "discrete" events, but with an extra category of "user-blocking" (Immediate).
  80. High = 2,
  81. /// "Medium priority" work is generated by page events not triggered by the user. These types of events are less important
  82. /// than "High Priority" events and will take presedence over low priority events.
  83. ///
  84. /// This is typically reserved for VirtualEvents that are not related to keyboard or mouse input.
  85. ///
  86. /// React calls these "continuous" events (e.g. mouse move, mouse wheel, touch move, etc).
  87. Medium = 1,
  88. /// "Low Priority" work will always be pre-empted unless the work is significantly delayed, in which case it will be
  89. /// advanced to the front of the work queue until completed.
  90. ///
  91. /// The primary user of Low Priority work is the asynchronous work system (suspense).
  92. ///
  93. /// This is considered "idle" work or "background" work.
  94. Low = 0,
  95. }
  96. #[derive(Debug)]
  97. pub struct DioxusEvent<T: Send + Sync> {
  98. inner: T,
  99. raw: Box<dyn Any + Send>,
  100. }
  101. impl<T: Send + Sync> DioxusEvent<T> {
  102. pub fn new<F: Send + 'static>(inner: T, raw: F) -> Self {
  103. let raw = Box::new(raw);
  104. Self { inner, raw }
  105. }
  106. /// Return a reference to the raw event. User will need to downcast the event to the right platform-specific type.
  107. pub fn native<E: 'static>(&self) -> Option<&E> {
  108. self.raw.downcast_ref()
  109. }
  110. /// Returns whether or not a specific event is a bubbling event
  111. pub fn bubbles(&self) -> bool {
  112. todo!()
  113. }
  114. /// Sets or returns whether the event should propagate up the hierarchy or not
  115. pub fn cancel_bubble(&self) {
  116. todo!()
  117. }
  118. /// Returns whether or not an event can have its default action prevented
  119. pub fn cancelable(&self) -> bool {
  120. todo!()
  121. }
  122. /// Returns whether the event is composed or not
  123. pub fn composed(&self) -> bool {
  124. todo!()
  125. }
  126. // Currently not supported because those no way we could possibly support it
  127. // just cast the event to the right platform-specific type and return it
  128. // /// Returns the event's path
  129. // pub fn composed_path(&self) -> String {
  130. // todo!()
  131. // }
  132. /// Returns the element whose event listeners triggered the event
  133. pub fn current_target(&self) {
  134. todo!()
  135. }
  136. /// Returns whether or not the preventDefault method was called for the event
  137. pub fn default_prevented(&self) -> bool {
  138. todo!()
  139. }
  140. /// Returns which phase of the event flow is currently being evaluated
  141. pub fn event_phase(&self) -> u16 {
  142. todo!()
  143. }
  144. /// Returns whether or not an event is trusted
  145. pub fn is_trusted(&self) -> bool {
  146. todo!()
  147. }
  148. /// Cancels the event if it is cancelable, meaning that the default action that belongs to the event will
  149. pub fn prevent_default(&self) {
  150. todo!()
  151. }
  152. /// Prevents other listeners of the same event from being called
  153. pub fn stop_immediate_propagation(&self) {
  154. todo!()
  155. }
  156. /// Prevents further propagation of an event during event flow
  157. pub fn stop_propagation(&self) {
  158. todo!()
  159. }
  160. /// Returns the element that triggered the event
  161. pub fn target(&self) -> Option<Box<dyn Any>> {
  162. todo!()
  163. }
  164. /// Returns the time (in milliseconds relative to the epoch) at which the event was created
  165. pub fn time_stamp(&self) -> f64 {
  166. todo!()
  167. }
  168. }
  169. impl<T: Send + Sync> std::ops::Deref for DioxusEvent<T> {
  170. type Target = T;
  171. fn deref(&self) -> &Self::Target {
  172. &self.inner
  173. }
  174. }
  175. pub mod on {
  176. use super::*;
  177. macro_rules! event_directory {
  178. ( $(
  179. $( #[$attr:meta] )*
  180. $eventdata:ident($wrapper:ident): [
  181. $(
  182. $( #[$method_attr:meta] )*
  183. $name:ident
  184. )*
  185. ];
  186. )* ) => {
  187. $(
  188. $(#[$attr])*
  189. #[derive(Debug)]
  190. pub struct $wrapper(pub DioxusEvent<$eventdata>);
  191. // todo: derefing to the event is fine (and easy) but breaks some IDE stuff like (go to source)
  192. // going to source in fact takes you to the source of Rc which is... less than useful
  193. // Either we ask for this to be changed in Rust-analyzer or manually impkement the trait
  194. impl Deref for $wrapper {
  195. type Target = DioxusEvent<$eventdata>;
  196. fn deref(&self) -> &Self::Target {
  197. &self.0
  198. }
  199. }
  200. $(
  201. $(#[$method_attr])*
  202. pub fn $name<'a, F>(
  203. c: NodeFactory<'a>,
  204. mut callback: F,
  205. ) -> Listener<'a>
  206. where F: FnMut($wrapper) + 'a
  207. {
  208. let bump = &c.bump();
  209. let cb: &mut dyn FnMut(SyntheticEvent) = bump.alloc(move |evt: SyntheticEvent| match evt {
  210. SyntheticEvent::$wrapper(event) => callback(event),
  211. _ => unreachable!("Downcasted SyntheticEvent to wrong event type - this is an internal bug!")
  212. });
  213. let callback: BumpBox<dyn FnMut(SyntheticEvent) + 'a> = unsafe { BumpBox::from_raw(cb) };
  214. // ie oncopy
  215. let event_name = stringify!($name);
  216. // ie copy
  217. let shortname: &'static str = &event_name[2..];
  218. Listener {
  219. event: shortname,
  220. mounted_node: Cell::new(None),
  221. callback: RefCell::new(Some(callback)),
  222. }
  223. }
  224. )*
  225. )*
  226. };
  227. }
  228. // The Dioxus Synthetic event system
  229. event_directory! {
  230. ClipboardEventInner(ClipboardEvent): [
  231. /// Called when "copy"
  232. oncopy
  233. /// oncut
  234. oncut
  235. /// onpaste
  236. onpaste
  237. ];
  238. CompositionEventInner(CompositionEvent): [
  239. /// oncompositionend
  240. oncompositionend
  241. /// oncompositionstart
  242. oncompositionstart
  243. /// oncompositionupdate
  244. oncompositionupdate
  245. ];
  246. KeyboardEventInner(KeyboardEvent): [
  247. /// onkeydown
  248. onkeydown
  249. /// onkeypress
  250. onkeypress
  251. /// onkeyup
  252. onkeyup
  253. ];
  254. FocusEventInner(FocusEvent): [
  255. /// onfocus
  256. onfocus
  257. /// onblur
  258. onblur
  259. ];
  260. FormEventInner(FormEvent): [
  261. /// onchange
  262. onchange
  263. /// oninput handler
  264. oninput
  265. /// oninvalid
  266. oninvalid
  267. /// onreset
  268. onreset
  269. /// onsubmit
  270. onsubmit
  271. ];
  272. /// A synthetic event that wraps a web-style [`MouseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
  273. ///
  274. ///
  275. /// The MouseEvent interface represents events that occur due to the user interacting with a pointing device (such as a mouse).
  276. ///
  277. /// ## Trait implementation:
  278. /// ```rust
  279. /// fn alt_key(&self) -> bool;
  280. /// fn button(&self) -> i16;
  281. /// fn buttons(&self) -> u16;
  282. /// fn client_x(&self) -> i32;
  283. /// fn client_y(&self) -> i32;
  284. /// fn ctrl_key(&self) -> bool;
  285. /// fn meta_key(&self) -> bool;
  286. /// fn page_x(&self) -> i32;
  287. /// fn page_y(&self) -> i32;
  288. /// fn screen_x(&self) -> i32;
  289. /// fn screen_y(&self) -> i32;
  290. /// fn shift_key(&self) -> bool;
  291. /// fn get_modifier_state(&self, key_code: &str) -> bool;
  292. /// ```
  293. ///
  294. /// ## Event Handlers
  295. /// - [`onclick`]
  296. /// - [`oncontextmenu`]
  297. /// - [`ondoubleclick`]
  298. /// - [`ondrag`]
  299. /// - [`ondragend`]
  300. /// - [`ondragenter`]
  301. /// - [`ondragexit`]
  302. /// - [`ondragleave`]
  303. /// - [`ondragover`]
  304. /// - [`ondragstart`]
  305. /// - [`ondrop`]
  306. /// - [`onmousedown`]
  307. /// - [`onmouseenter`]
  308. /// - [`onmouseleave`]
  309. /// - [`onmousemove`]
  310. /// - [`onmouseout`]
  311. /// - [`onmouseover`]
  312. /// - [`onmouseup`]
  313. MouseEventInner(MouseEvent): [
  314. /// Execute a callback when a button is clicked.
  315. ///
  316. /// ## Description
  317. ///
  318. /// An element receives a click event when a pointing device button (such as a mouse's primary mouse button)
  319. /// is both pressed and released while the pointer is located inside the element.
  320. ///
  321. /// - Bubbles: Yes
  322. /// - Cancelable: Yes
  323. /// - Interface: [`MouseEvent`]
  324. ///
  325. /// If the button is pressed on one element and the pointer is moved outside the element before the button
  326. /// is released, the event is fired on the most specific ancestor element that contained both elements.
  327. /// `click` fires after both the `mousedown` and `mouseup` events have fired, in that order.
  328. ///
  329. /// ## Example
  330. /// ```
  331. /// rsx!( button { "click me", onclick: move |_| log::info!("Clicked!`") } )
  332. /// ```
  333. ///
  334. /// ## Reference
  335. /// - https://www.w3schools.com/tags/ev_onclick.asp
  336. /// - https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
  337. onclick
  338. /// oncontextmenu
  339. oncontextmenu
  340. /// ondoubleclick
  341. ondoubleclick
  342. /// ondrag
  343. ondrag
  344. /// ondragend
  345. ondragend
  346. /// ondragenter
  347. ondragenter
  348. /// ondragexit
  349. ondragexit
  350. /// ondragleave
  351. ondragleave
  352. /// ondragover
  353. ondragover
  354. /// ondragstart
  355. ondragstart
  356. /// ondrop
  357. ondrop
  358. /// onmousedown
  359. onmousedown
  360. /// onmouseenter
  361. onmouseenter
  362. /// onmouseleave
  363. onmouseleave
  364. /// onmousemove
  365. onmousemove
  366. /// onmouseout
  367. onmouseout
  368. ///
  369. onscroll
  370. /// onmouseover
  371. ///
  372. /// Triggered when the users's mouse hovers over an element.
  373. onmouseover
  374. /// onmouseup
  375. onmouseup
  376. ];
  377. PointerEventInner(PointerEvent): [
  378. /// pointerdown
  379. onpointerdown
  380. /// pointermove
  381. onpointermove
  382. /// pointerup
  383. onpointerup
  384. /// pointercancel
  385. onpointercancel
  386. /// gotpointercapture
  387. ongotpointercapture
  388. /// lostpointercapture
  389. onlostpointercapture
  390. /// pointerenter
  391. onpointerenter
  392. /// pointerleave
  393. onpointerleave
  394. /// pointerover
  395. onpointerover
  396. /// pointerout
  397. onpointerout
  398. ];
  399. SelectionEventInner(SelectionEvent): [
  400. /// onselect
  401. onselect
  402. ];
  403. TouchEventInner(TouchEvent): [
  404. /// ontouchcancel
  405. ontouchcancel
  406. /// ontouchend
  407. ontouchend
  408. /// ontouchmove
  409. ontouchmove
  410. /// ontouchstart
  411. ontouchstart
  412. ];
  413. WheelEventInner(WheelEvent): [
  414. ///
  415. onwheel
  416. ];
  417. MediaEventInner(MediaEvent): [
  418. ///abort
  419. onabort
  420. ///canplay
  421. oncanplay
  422. ///canplaythrough
  423. oncanplaythrough
  424. ///durationchange
  425. ondurationchange
  426. ///emptied
  427. onemptied
  428. ///encrypted
  429. onencrypted
  430. ///ended
  431. onended
  432. ///error
  433. onerror
  434. ///loadeddata
  435. onloadeddata
  436. ///loadedmetadata
  437. onloadedmetadata
  438. ///loadstart
  439. onloadstart
  440. ///pause
  441. onpause
  442. ///play
  443. onplay
  444. ///playing
  445. onplaying
  446. ///progress
  447. onprogress
  448. ///ratechange
  449. onratechange
  450. ///seeked
  451. onseeked
  452. ///seeking
  453. onseeking
  454. ///stalled
  455. onstalled
  456. ///suspend
  457. onsuspend
  458. ///timeupdate
  459. ontimeupdate
  460. ///volumechange
  461. onvolumechange
  462. ///waiting
  463. onwaiting
  464. ];
  465. AnimationEventInner(AnimationEvent): [
  466. /// onanimationstart
  467. onanimationstart
  468. /// onanimationend
  469. onanimationend
  470. /// onanimationiteration
  471. onanimationiteration
  472. ];
  473. TransitionEventInner(TransitionEvent): [
  474. ///
  475. ontransitionend
  476. ];
  477. ToggleEventInner(ToggleEvent): [
  478. ///
  479. ontoggle
  480. ];
  481. }
  482. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  483. #[derive(Debug)]
  484. pub struct ClipboardEventInner(
  485. // DOMDataTransfer clipboardData
  486. );
  487. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  488. #[derive(Debug)]
  489. pub struct CompositionEventInner {
  490. pub data: String,
  491. }
  492. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  493. #[derive(Debug)]
  494. pub struct KeyboardEventInner {
  495. pub char_code: u32,
  496. /// Identify which "key" was entered.
  497. ///
  498. /// This is the best method to use for all languages. They key gets mapped to a String sequence which you can match on.
  499. /// The key isn't an enum because there are just so many context-dependent keys.
  500. ///
  501. /// A full list on which keys to use is available at:
  502. /// <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
  503. ///
  504. /// # Example
  505. ///
  506. /// ```rust
  507. /// match event.key().as_str() {
  508. /// "Esc" | "Escape" => {}
  509. /// "ArrowDown" => {}
  510. /// "ArrowLeft" => {}
  511. /// _ => {}
  512. /// }
  513. /// ```
  514. ///
  515. pub key: String,
  516. /// Get the key code as an enum Variant.
  517. ///
  518. /// This is intended for things like arrow keys, escape keys, function keys, and other non-international keys.
  519. /// To match on unicode sequences, use the [`key`] method - this will return a string identifier instead of a limited enum.
  520. ///
  521. ///
  522. /// ## Example
  523. ///
  524. /// ```rust
  525. /// use dioxus::KeyCode;
  526. /// match event.key_code() {
  527. /// KeyCode::Escape => {}
  528. /// KeyCode::LeftArrow => {}
  529. /// KeyCode::RightArrow => {}
  530. /// _ => {}
  531. /// }
  532. /// ```
  533. ///
  534. pub key_code: KeyCode,
  535. /// Indicate if the `alt` modifier key was pressed during this keyboard event
  536. pub alt_key: bool,
  537. /// Indicate if the `ctrl` modifier key was pressed during this keyboard event
  538. pub ctrl_key: bool,
  539. /// Indicate if the `meta` modifier key was pressed during this keyboard event
  540. pub meta_key: bool,
  541. /// Indicate if the `shift` modifier key was pressed during this keyboard event
  542. pub shift_key: bool,
  543. pub locale: String,
  544. pub location: usize,
  545. pub repeat: bool,
  546. pub which: usize,
  547. // get_modifier_state: bool,
  548. }
  549. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  550. #[derive(Debug)]
  551. pub struct FocusEventInner {/* DOMEventInner: Send + SyncTarget relatedTarget */}
  552. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  553. #[derive(Debug)]
  554. pub struct FormEventInner {
  555. /* DOMEventInner: Send + SyncTarget relatedTarget */
  556. pub value: String,
  557. }
  558. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  559. #[derive(Debug)]
  560. pub struct MouseEventInner {
  561. pub alt_key: bool,
  562. pub button: i16,
  563. pub buttons: u16,
  564. pub client_x: i32,
  565. pub client_y: i32,
  566. pub ctrl_key: bool,
  567. pub meta_key: bool,
  568. pub page_x: i32,
  569. pub page_y: i32,
  570. pub screen_x: i32,
  571. pub screen_y: i32,
  572. pub shift_key: bool,
  573. // fn get_modifier_state(&self, key_code: &str) -> bool;
  574. }
  575. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  576. #[derive(Debug)]
  577. pub struct PointerEventInner {
  578. // Mouse only
  579. pub alt_key: bool,
  580. pub button: i16,
  581. pub buttons: u16,
  582. pub client_x: i32,
  583. pub client_y: i32,
  584. pub ctrl_key: bool,
  585. pub meta_key: bool,
  586. pub page_x: i32,
  587. pub page_y: i32,
  588. pub screen_x: i32,
  589. pub screen_y: i32,
  590. pub shift_key: bool,
  591. pub pointer_id: i32,
  592. pub width: i32,
  593. pub height: i32,
  594. pub pressure: f32,
  595. pub tangential_pressure: f32,
  596. pub tilt_x: i32,
  597. pub tilt_y: i32,
  598. pub twist: i32,
  599. pub pointer_type: String,
  600. pub is_primary: bool,
  601. // pub get_modifier_state: bool,
  602. }
  603. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  604. #[derive(Debug)]
  605. pub struct SelectionEventInner {}
  606. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  607. #[derive(Debug)]
  608. pub struct TouchEventInner {
  609. pub alt_key: bool,
  610. pub ctrl_key: bool,
  611. pub meta_key: bool,
  612. pub shift_key: bool,
  613. // get_modifier_state: bool,
  614. // changedTouches: DOMTouchList,
  615. // targetTouches: DOMTouchList,
  616. // touches: DOMTouchList,
  617. }
  618. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  619. #[derive(Debug)]
  620. pub struct WheelEventInner {
  621. pub delta_mode: u32,
  622. pub delta_x: f64,
  623. pub delta_y: f64,
  624. pub delta_z: f64,
  625. }
  626. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  627. #[derive(Debug)]
  628. pub struct MediaEventInner {}
  629. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  630. #[derive(Debug)]
  631. pub struct ImageEventInner {
  632. // load error
  633. pub load_error: bool,
  634. }
  635. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  636. #[derive(Debug)]
  637. pub struct AnimationEventInner {
  638. pub animation_name: String,
  639. pub pseudo_element: String,
  640. pub elapsed_time: f32,
  641. }
  642. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  643. #[derive(Debug)]
  644. pub struct TransitionEventInner {
  645. pub property_name: String,
  646. pub pseudo_element: String,
  647. pub elapsed_time: f32,
  648. }
  649. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  650. #[derive(Debug)]
  651. pub struct ToggleEventInner {}
  652. }
  653. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  654. #[derive(Clone, Copy, Debug)]
  655. pub enum KeyCode {
  656. Backspace = 8,
  657. Tab = 9,
  658. Enter = 13,
  659. Shift = 16,
  660. Ctrl = 17,
  661. Alt = 18,
  662. Pause = 19,
  663. CapsLock = 20,
  664. Escape = 27,
  665. PageUp = 33,
  666. PageDown = 34,
  667. End = 35,
  668. Home = 36,
  669. LeftArrow = 37,
  670. UpArrow = 38,
  671. RightArrow = 39,
  672. DownArrow = 40,
  673. Insert = 45,
  674. Delete = 46,
  675. Num0 = 48,
  676. Num1 = 49,
  677. Num2 = 50,
  678. Num3 = 51,
  679. Num4 = 52,
  680. Num5 = 53,
  681. Num6 = 54,
  682. Num7 = 55,
  683. Num8 = 56,
  684. Num9 = 57,
  685. A = 65,
  686. B = 66,
  687. C = 67,
  688. D = 68,
  689. E = 69,
  690. F = 70,
  691. G = 71,
  692. H = 72,
  693. I = 73,
  694. J = 74,
  695. K = 75,
  696. L = 76,
  697. M = 77,
  698. N = 78,
  699. O = 79,
  700. P = 80,
  701. Q = 81,
  702. R = 82,
  703. S = 83,
  704. T = 84,
  705. U = 85,
  706. V = 86,
  707. W = 87,
  708. X = 88,
  709. Y = 89,
  710. Z = 90,
  711. LeftWindow = 91,
  712. RightWindow = 92,
  713. SelectKey = 93,
  714. Numpad0 = 96,
  715. Numpad1 = 97,
  716. Numpad2 = 98,
  717. Numpad3 = 99,
  718. Numpad4 = 100,
  719. Numpad5 = 101,
  720. Numpad6 = 102,
  721. Numpad7 = 103,
  722. Numpad8 = 104,
  723. Numpad9 = 105,
  724. Multiply = 106,
  725. Add = 107,
  726. Subtract = 109,
  727. DecimalPoint = 110,
  728. Divide = 111,
  729. F1 = 112,
  730. F2 = 113,
  731. F3 = 114,
  732. F4 = 115,
  733. F5 = 116,
  734. F6 = 117,
  735. F7 = 118,
  736. F8 = 119,
  737. F9 = 120,
  738. F10 = 121,
  739. F11 = 122,
  740. F12 = 123,
  741. NumLock = 144,
  742. ScrollLock = 145,
  743. Semicolon = 186,
  744. EqualSign = 187,
  745. Comma = 188,
  746. Dash = 189,
  747. Period = 190,
  748. ForwardSlash = 191,
  749. GraveAccent = 192,
  750. OpenBracket = 219,
  751. BackSlash = 220,
  752. CloseBraket = 221,
  753. SingleQuote = 222,
  754. Unknown,
  755. }
  756. impl KeyCode {
  757. pub fn from_raw_code(i: u8) -> Self {
  758. use KeyCode::*;
  759. match i {
  760. 8 => Backspace,
  761. 9 => Tab,
  762. 13 => Enter,
  763. 16 => Shift,
  764. 17 => Ctrl,
  765. 18 => Alt,
  766. 19 => Pause,
  767. 20 => CapsLock,
  768. 27 => Escape,
  769. 33 => PageUp,
  770. 34 => PageDown,
  771. 35 => End,
  772. 36 => Home,
  773. 37 => LeftArrow,
  774. 38 => UpArrow,
  775. 39 => RightArrow,
  776. 40 => DownArrow,
  777. 45 => Insert,
  778. 46 => Delete,
  779. 48 => Num0,
  780. 49 => Num1,
  781. 50 => Num2,
  782. 51 => Num3,
  783. 52 => Num4,
  784. 53 => Num5,
  785. 54 => Num6,
  786. 55 => Num7,
  787. 56 => Num8,
  788. 57 => Num9,
  789. 65 => A,
  790. 66 => B,
  791. 67 => C,
  792. 68 => D,
  793. 69 => E,
  794. 70 => F,
  795. 71 => G,
  796. 72 => H,
  797. 73 => I,
  798. 74 => J,
  799. 75 => K,
  800. 76 => L,
  801. 77 => M,
  802. 78 => N,
  803. 79 => O,
  804. 80 => P,
  805. 81 => Q,
  806. 82 => R,
  807. 83 => S,
  808. 84 => T,
  809. 85 => U,
  810. 86 => V,
  811. 87 => W,
  812. 88 => X,
  813. 89 => Y,
  814. 90 => Z,
  815. 91 => LeftWindow,
  816. 92 => RightWindow,
  817. 93 => SelectKey,
  818. 96 => Numpad0,
  819. 97 => Numpad1,
  820. 98 => Numpad2,
  821. 99 => Numpad3,
  822. 100 => Numpad4,
  823. 101 => Numpad5,
  824. 102 => Numpad6,
  825. 103 => Numpad7,
  826. 104 => Numpad8,
  827. 105 => Numpad9,
  828. 106 => Multiply,
  829. 107 => Add,
  830. 109 => Subtract,
  831. 110 => DecimalPoint,
  832. 111 => Divide,
  833. 112 => F1,
  834. 113 => F2,
  835. 114 => F3,
  836. 115 => F4,
  837. 116 => F5,
  838. 117 => F6,
  839. 118 => F7,
  840. 119 => F8,
  841. 120 => F9,
  842. 121 => F10,
  843. 122 => F11,
  844. 123 => F12,
  845. 144 => NumLock,
  846. 145 => ScrollLock,
  847. 186 => Semicolon,
  848. 187 => EqualSign,
  849. 188 => Comma,
  850. 189 => Dash,
  851. 190 => Period,
  852. 191 => ForwardSlash,
  853. 192 => GraveAccent,
  854. 219 => OpenBracket,
  855. 220 => BackSlash,
  856. 221 => CloseBraket,
  857. 222 => SingleQuote,
  858. _ => Unknown,
  859. }
  860. }
  861. // get the raw code
  862. pub fn raw_code(&self) -> u32 {
  863. *self as u32
  864. }
  865. }
  866. pub(crate) fn event_meta(event: &UserEvent) -> (bool, EventPriority) {
  867. use EventPriority::*;
  868. match event.name {
  869. // clipboard
  870. "copy" | "cut" | "paste" => (true, Medium),
  871. // Composition
  872. "compositionend" | "compositionstart" | "compositionupdate" => (true, Low),
  873. // Keyboard
  874. "keydown" | "keypress" | "keyup" => (true, High),
  875. // Focus
  876. "focus" | "blur" => (true, Low),
  877. // Form
  878. "change" | "input" | "invalid" | "reset" | "submit" => (true, Medium),
  879. // Mouse
  880. "click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit"
  881. | "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter"
  882. | "mouseleave" | "mouseout" | "mouseover" | "mouseup" => (true, High),
  883. "mousemove" => (false, Medium),
  884. // Pointer
  885. "pointerdown" | "pointermove" | "pointerup" | "pointercancel" | "gotpointercapture"
  886. | "lostpointercapture" | "pointerenter" | "pointerleave" | "pointerover" | "pointerout" => {
  887. (true, Medium)
  888. }
  889. // Selection
  890. "select" | "touchcancel" | "touchend" => (true, Medium),
  891. // Touch
  892. "touchmove" | "touchstart" => (true, Medium),
  893. // Wheel
  894. "scroll" | "wheel" => (false, Medium),
  895. // Media
  896. "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted"
  897. | "ended" | "error" | "loadeddata" | "loadedmetadata" | "loadstart" | "pause" | "play"
  898. | "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
  899. | "timeupdate" | "volumechange" | "waiting" => (true, Medium),
  900. // Animation
  901. "animationstart" | "animationend" | "animationiteration" => (true, Medium),
  902. // Transition
  903. "transitionend" => (true, Medium),
  904. // Toggle
  905. "toggle" => (true, Medium),
  906. _ => (true, Low),
  907. }
  908. }