events.rs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. use bumpalo::boxed::Box as BumpBox;
  2. use dioxus_core::exports::bumpalo;
  3. use dioxus_core::*;
  4. pub mod on {
  5. //! Input events and associated data
  6. use crate::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint};
  7. use crate::input_data::{
  8. decode_mouse_button_set, encode_mouse_button_set, MouseButton, MouseButtonSet,
  9. };
  10. use keyboard_types::Modifiers;
  11. use std::collections::HashMap;
  12. use super::*;
  13. macro_rules! event_directory {
  14. ( $(
  15. $( #[$attr:meta] )*
  16. $wrapper:ident($data:ident): [
  17. $(
  18. $( #[$method_attr:meta] )*
  19. $name:ident
  20. )*
  21. ];
  22. )* ) => {
  23. $(
  24. $(
  25. $(#[$method_attr])*
  26. pub fn $name<'a>(
  27. factory: NodeFactory<'a>,
  28. mut callback: impl FnMut($wrapper) + 'a,
  29. // mut callback: impl FnMut(UiEvent<$data>) + 'a,
  30. ) -> Listener<'a>
  31. {
  32. let bump = &factory.bump();
  33. use dioxus_core::{AnyEvent};
  34. // we can't allocate unsized in bumpalo's box, so we need to craft the box manually
  35. // safety: this is essentially the same as calling Box::new() but manually
  36. // The box is attached to the lifetime of the bumpalo allocator
  37. let cb: &mut dyn FnMut(AnyEvent) = bump.alloc(move |evt: AnyEvent| {
  38. let event = evt.downcast::<$data>().unwrap();
  39. callback(event)
  40. });
  41. let callback: BumpBox<dyn FnMut(AnyEvent) + 'a> = unsafe { BumpBox::from_raw(cb) };
  42. // ie oncopy
  43. let event_name = stringify!($name);
  44. // ie copy
  45. let shortname: &'static str = &event_name[2..];
  46. let handler = bump.alloc(std::cell::RefCell::new(Some(callback)));
  47. factory.listener(shortname, handler)
  48. }
  49. )*
  50. )*
  51. };
  52. }
  53. // The Dioxus Synthetic event system
  54. // todo: move these into the html event system. dioxus accepts *any* event, so having these here doesn't make sense.
  55. event_directory! {
  56. ClipboardEvent(ClipboardData): [
  57. /// Called when "copy"
  58. oncopy
  59. /// oncut
  60. oncut
  61. /// onpaste
  62. onpaste
  63. ];
  64. CompositionEvent(CompositionData): [
  65. /// oncompositionend
  66. oncompositionend
  67. /// oncompositionstart
  68. oncompositionstart
  69. /// oncompositionupdate
  70. oncompositionupdate
  71. ];
  72. KeyboardEvent(KeyboardData): [
  73. /// onkeydown
  74. onkeydown
  75. /// onkeypress
  76. onkeypress
  77. /// onkeyup
  78. onkeyup
  79. ];
  80. FocusEvent(FocusData): [
  81. /// onfocus
  82. onfocus
  83. // onfocusout
  84. onfocusout
  85. // onfocusin
  86. onfocusin
  87. /// onblur
  88. onblur
  89. ];
  90. FormEvent(FormData): [
  91. /// onchange
  92. onchange
  93. /// oninput handler
  94. oninput
  95. /// oninvalid
  96. oninvalid
  97. /// onreset
  98. onreset
  99. /// onsubmit
  100. onsubmit
  101. ];
  102. /// A synthetic event that wraps a web-style [`MouseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
  103. ///
  104. ///
  105. /// The MouseEvent interface represents events that occur due to the user interacting with a pointing device (such as a mouse).
  106. ///
  107. /// ## Trait implementation:
  108. /// ```rust, ignore
  109. /// fn alt_key(&self) -> bool;
  110. /// fn button(&self) -> i16;
  111. /// fn buttons(&self) -> u16;
  112. /// fn client_x(&self) -> i32;
  113. /// fn client_y(&self) -> i32;
  114. /// fn ctrl_key(&self) -> bool;
  115. /// fn meta_key(&self) -> bool;
  116. /// fn page_x(&self) -> i32;
  117. /// fn page_y(&self) -> i32;
  118. /// fn screen_x(&self) -> i32;
  119. /// fn screen_y(&self) -> i32;
  120. /// fn shift_key(&self) -> bool;
  121. /// fn get_modifier_state(&self, key_code: &str) -> bool;
  122. /// ```
  123. ///
  124. /// ## Event Handlers
  125. /// - [`onclick`]
  126. /// - [`oncontextmenu`]
  127. /// - [`ondoubleclick`]
  128. /// - [`ondrag`]
  129. /// - [`ondragend`]
  130. /// - [`ondragenter`]
  131. /// - [`ondragexit`]
  132. /// - [`ondragleave`]
  133. /// - [`ondragover`]
  134. /// - [`ondragstart`]
  135. /// - [`ondrop`]
  136. /// - [`onmousedown`]
  137. /// - [`onmouseenter`]
  138. /// - [`onmouseleave`]
  139. /// - [`onmousemove`]
  140. /// - [`onmouseout`]
  141. /// - [`onmouseover`]
  142. /// - [`onmouseup`]
  143. MouseEvent(MouseData): [
  144. /// Execute a callback when a button is clicked.
  145. ///
  146. /// ## Description
  147. ///
  148. /// An element receives a click event when a pointing device button (such as a mouse's primary mouse button)
  149. /// is both pressed and released while the pointer is located inside the element.
  150. ///
  151. /// - Bubbles: Yes
  152. /// - Cancelable: Yes
  153. /// - Interface(InteData): [`MouseEvent`]
  154. ///
  155. /// If the button is pressed on one element and the pointer is moved outside the element before the button
  156. /// is released, the event is fired on the most specific ancestor element that contained both elements.
  157. /// `click` fires after both the `mousedown` and `mouseup` events have fired, in that order.
  158. ///
  159. /// ## Example
  160. /// ```
  161. /// rsx!( button { "click me", onclick: move |_| log::info!("Clicked!`") } )
  162. /// ```
  163. ///
  164. /// ## Reference
  165. /// - <https://www.w3schools.com/tags/ev_onclick.asp>
  166. /// - <https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event>
  167. onclick
  168. /// oncontextmenu
  169. oncontextmenu
  170. /// ondoubleclick
  171. ondoubleclick
  172. /// ondoubleclick
  173. ondblclick
  174. /// ondrag
  175. ondrag
  176. /// ondragend
  177. ondragend
  178. /// ondragenter
  179. ondragenter
  180. /// ondragexit
  181. ondragexit
  182. /// ondragleave
  183. ondragleave
  184. /// ondragover
  185. ondragover
  186. /// ondragstart
  187. ondragstart
  188. /// ondrop
  189. ondrop
  190. /// onmousedown
  191. onmousedown
  192. /// onmouseenter
  193. onmouseenter
  194. /// onmouseleave
  195. onmouseleave
  196. /// onmousemove
  197. onmousemove
  198. /// onmouseout
  199. onmouseout
  200. ///
  201. onscroll
  202. /// onmouseover
  203. ///
  204. /// Triggered when the users's mouse hovers over an element.
  205. onmouseover
  206. /// onmouseup
  207. onmouseup
  208. ];
  209. PointerEvent(PointerData): [
  210. /// pointerdown
  211. onpointerdown
  212. /// pointermove
  213. onpointermove
  214. /// pointerup
  215. onpointerup
  216. /// pointercancel
  217. onpointercancel
  218. /// gotpointercapture
  219. ongotpointercapture
  220. /// lostpointercapture
  221. onlostpointercapture
  222. /// pointerenter
  223. onpointerenter
  224. /// pointerleave
  225. onpointerleave
  226. /// pointerover
  227. onpointerover
  228. /// pointerout
  229. onpointerout
  230. ];
  231. SelectionEvent(SelectionData): [
  232. /// onselect
  233. onselect
  234. ];
  235. TouchEvent(TouchData): [
  236. /// ontouchcancel
  237. ontouchcancel
  238. /// ontouchend
  239. ontouchend
  240. /// ontouchmove
  241. ontouchmove
  242. /// ontouchstart
  243. ontouchstart
  244. ];
  245. WheelEvent(WheelData): [
  246. ///
  247. onwheel
  248. ];
  249. MediaEvent(MediaData): [
  250. ///abort
  251. onabort
  252. ///canplay
  253. oncanplay
  254. ///canplaythrough
  255. oncanplaythrough
  256. ///durationchange
  257. ondurationchange
  258. ///emptied
  259. onemptied
  260. ///encrypted
  261. onencrypted
  262. ///ended
  263. onended
  264. ///error
  265. onerror
  266. ///loadeddata
  267. onloadeddata
  268. ///loadedmetadata
  269. onloadedmetadata
  270. ///loadstart
  271. onloadstart
  272. ///pause
  273. onpause
  274. ///play
  275. onplay
  276. ///playing
  277. onplaying
  278. ///progress
  279. onprogress
  280. ///ratechange
  281. onratechange
  282. ///seeked
  283. onseeked
  284. ///seeking
  285. onseeking
  286. ///stalled
  287. onstalled
  288. ///suspend
  289. onsuspend
  290. ///timeupdate
  291. ontimeupdate
  292. ///volumechange
  293. onvolumechange
  294. ///waiting
  295. onwaiting
  296. ];
  297. AnimationEvent(AnimationData): [
  298. /// onanimationstart
  299. onanimationstart
  300. /// onanimationend
  301. onanimationend
  302. /// onanimationiteration
  303. onanimationiteration
  304. ];
  305. TransitionEvent(TransitionData): [
  306. ///
  307. ontransitionend
  308. ];
  309. ToggleEvent(ToggleData): [
  310. ///
  311. ontoggle
  312. ];
  313. }
  314. pub type ClipboardEvent = UiEvent<ClipboardData>;
  315. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  316. #[derive(Debug, Clone)]
  317. pub struct ClipboardData {
  318. // DOMDataTransfer clipboardData
  319. }
  320. pub type CompositionEvent = UiEvent<CompositionData>;
  321. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  322. #[derive(Debug, Clone)]
  323. pub struct CompositionData {
  324. pub data: String,
  325. }
  326. pub type KeyboardEvent = UiEvent<KeyboardData>;
  327. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  328. #[derive(Debug, Clone)]
  329. pub struct KeyboardData {
  330. pub char_code: u32,
  331. /// Identify which "key" was entered.
  332. ///
  333. /// This is the best method to use for all languages. They key gets mapped to a String sequence which you can match on.
  334. /// The key isn't an enum because there are just so many context-dependent keys.
  335. ///
  336. /// A full list on which keys to use is available at:
  337. /// <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
  338. ///
  339. /// # Example
  340. ///
  341. /// ```rust, ignore
  342. /// match event.key().as_str() {
  343. /// "Esc" | "Escape" => {}
  344. /// "ArrowDown" => {}
  345. /// "ArrowLeft" => {}
  346. /// _ => {}
  347. /// }
  348. /// ```
  349. ///
  350. pub key: String,
  351. /// Get the key code as an enum Variant.
  352. ///
  353. /// This is intended for things like arrow keys, escape keys, function keys, and other non-international keys.
  354. /// To match on unicode sequences, use the [`KeyboardData::key`] method - this will return a string identifier instead of a limited enum.
  355. ///
  356. ///
  357. /// ## Example
  358. ///
  359. /// ```rust, ignore
  360. /// use dioxus::KeyCode;
  361. /// match event.key_code() {
  362. /// KeyCode::Escape => {}
  363. /// KeyCode::LeftArrow => {}
  364. /// KeyCode::RightArrow => {}
  365. /// _ => {}
  366. /// }
  367. /// ```
  368. ///
  369. pub key_code: KeyCode,
  370. /// Indicate if the `alt` modifier key was pressed during this keyboard event
  371. pub alt_key: bool,
  372. /// Indicate if the `ctrl` modifier key was pressed during this keyboard event
  373. pub ctrl_key: bool,
  374. /// Indicate if the `meta` modifier key was pressed during this keyboard event
  375. pub meta_key: bool,
  376. /// Indicate if the `shift` modifier key was pressed during this keyboard event
  377. pub shift_key: bool,
  378. pub locale: String,
  379. pub location: usize,
  380. pub repeat: bool,
  381. pub which: usize,
  382. // get_modifier_state: bool,
  383. }
  384. pub type FocusEvent = UiEvent<FocusData>;
  385. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  386. #[derive(Debug, Clone)]
  387. pub struct FocusData {/* DOMEventInner: Send + SyncTarget relatedTarget */}
  388. pub type FormEvent = UiEvent<FormData>;
  389. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  390. #[derive(Debug, Clone)]
  391. pub struct FormData {
  392. pub value: String,
  393. pub values: HashMap<String, String>,
  394. /* DOMEvent: Send + SyncTarget relatedTarget */
  395. }
  396. pub type MouseEvent = UiEvent<MouseData>;
  397. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  398. #[derive(Debug, Clone)]
  399. /// Data associated with a mouse event
  400. ///
  401. /// Do not use the deprecated fields; they may change or become private in the future.
  402. pub struct MouseData {
  403. /// True if the alt key was down when the mouse event was fired.
  404. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  405. pub alt_key: bool,
  406. /// The button number that was pressed (if applicable) when the mouse event was fired.
  407. #[deprecated(since = "0.3.0", note = "use trigger_button() instead")]
  408. pub button: i16,
  409. /// Indicates which buttons are pressed on the mouse (or other input device) when a mouse event is triggered.
  410. ///
  411. /// Each button that can be pressed is represented by a given number (see below). If more than one button is pressed, the button values are added together to produce a new number. For example, if the secondary (2) and auxiliary (4) buttons are pressed simultaneously, the value is 6 (i.e., 2 + 4).
  412. ///
  413. /// - 1: Primary button (usually the left button)
  414. /// - 2: Secondary button (usually the right button)
  415. /// - 4: Auxiliary button (usually the mouse wheel button or middle button)
  416. /// - 8: 4th button (typically the "Browser Back" button)
  417. /// - 16 : 5th button (typically the "Browser Forward" button)
  418. #[deprecated(since = "0.3.0", note = "use held_buttons() instead")]
  419. pub buttons: u16,
  420. /// The horizontal coordinate within the application's viewport at which the event occurred (as opposed to the coordinate within the page).
  421. ///
  422. /// For example, clicking on the left edge of the viewport will always result in a mouse event with a clientX value of 0, regardless of whether the page is scrolled horizontally.
  423. #[deprecated(since = "0.3.0", note = "use client_coordinates() instead")]
  424. pub client_x: i32,
  425. /// The vertical coordinate within the application's viewport at which the event occurred (as opposed to the coordinate within the page).
  426. ///
  427. /// For example, clicking on the top edge of the viewport will always result in a mouse event with a clientY value of 0, regardless of whether the page is scrolled vertically.
  428. #[deprecated(since = "0.3.0", note = "use client_coordinates() instead")]
  429. pub client_y: i32,
  430. /// True if the control key was down when the mouse event was fired.
  431. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  432. pub ctrl_key: bool,
  433. /// True if the meta key was down when the mouse event was fired.
  434. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  435. pub meta_key: bool,
  436. /// The offset in the X coordinate of the mouse pointer between that event and the padding edge of the target node.
  437. #[deprecated(since = "0.3.0", note = "use element_coordinates() instead")]
  438. pub offset_x: i32,
  439. /// The offset in the Y coordinate of the mouse pointer between that event and the padding edge of the target node.
  440. #[deprecated(since = "0.3.0", note = "use element_coordinates() instead")]
  441. pub offset_y: i32,
  442. /// The X (horizontal) coordinate (in pixels) of the mouse, relative to the left edge of the entire document. This includes any portion of the document not currently visible.
  443. ///
  444. /// Being based on the edge of the document as it is, this property takes into account any horizontal scrolling of the page. For example, if the page is scrolled such that 200 pixels of the left side of the document are scrolled out of view, and the mouse is clicked 100 pixels inward from the left edge of the view, the value returned by pageX will be 300.
  445. #[deprecated(since = "0.3.0", note = "use page_coordinates() instead")]
  446. pub page_x: i32,
  447. /// The Y (vertical) coordinate in pixels of the event relative to the whole document.
  448. ///
  449. /// See `page_x`.
  450. #[deprecated(since = "0.3.0", note = "use page_coordinates() instead")]
  451. pub page_y: i32,
  452. /// The X coordinate of the mouse pointer in global (screen) coordinates.
  453. #[deprecated(since = "0.3.0", note = "use screen_coordinates() instead")]
  454. pub screen_x: i32,
  455. /// The Y coordinate of the mouse pointer in global (screen) coordinates.
  456. #[deprecated(since = "0.3.0", note = "use screen_coordinates() instead")]
  457. pub screen_y: i32,
  458. /// True if the shift key was down when the mouse event was fired.
  459. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  460. pub shift_key: bool,
  461. // fn get_modifier_state(&self, key_code: &str) -> bool;
  462. }
  463. impl MouseData {
  464. /// Construct MouseData with the specified properties
  465. ///
  466. /// Note: the current implementation truncates coordinates. In the future, when we change the internal representation, it may also support a fractional part.
  467. pub fn new(
  468. coordinates: Coordinates,
  469. trigger_button: Option<MouseButton>,
  470. held_buttons: MouseButtonSet,
  471. modifiers: Modifiers,
  472. ) -> Self {
  473. let alt_key = modifiers.contains(Modifiers::ALT);
  474. let ctrl_key = modifiers.contains(Modifiers::CONTROL);
  475. let meta_key = modifiers.contains(Modifiers::META);
  476. let shift_key = modifiers.contains(Modifiers::SHIFT);
  477. let [client_x, client_y]: [i32; 2] = coordinates.client().cast().into();
  478. let [offset_x, offset_y]: [i32; 2] = coordinates.element().cast().into();
  479. let [page_x, page_y]: [i32; 2] = coordinates.page().cast().into();
  480. let [screen_x, screen_y]: [i32; 2] = coordinates.screen().cast().into();
  481. #[allow(deprecated)]
  482. Self {
  483. alt_key,
  484. ctrl_key,
  485. meta_key,
  486. shift_key,
  487. button: trigger_button.map_or(0, |b| b.into_web_code()),
  488. buttons: encode_mouse_button_set(held_buttons),
  489. client_x,
  490. client_y,
  491. offset_x,
  492. offset_y,
  493. page_x,
  494. page_y,
  495. screen_x,
  496. screen_y,
  497. }
  498. }
  499. /// The event's coordinates relative to the application's viewport (as opposed to the coordinate within the page).
  500. ///
  501. /// For example, clicking in the top left corner of the viewport will always result in a mouse event with client coordinates (0., 0.), regardless of whether the page is scrolled horizontally.
  502. pub fn client_coordinates(&self) -> ClientPoint {
  503. #[allow(deprecated)]
  504. ClientPoint::new(self.client_x.into(), self.client_y.into())
  505. }
  506. /// The event's coordinates relative to the padding edge of the target element
  507. ///
  508. /// For example, clicking in the top left corner of an element will result in element coordinates (0., 0.)
  509. pub fn element_coordinates(&self) -> ElementPoint {
  510. #[allow(deprecated)]
  511. ElementPoint::new(self.offset_x.into(), self.offset_y.into())
  512. }
  513. /// The event's coordinates relative to the entire document. This includes any portion of the document not currently visible.
  514. ///
  515. /// For example, if the page is scrolled 200 pixels to the right and 300 pixels down, clicking in the top left corner of the viewport would result in page coordinates (200., 300.)
  516. pub fn page_coordinates(&self) -> PagePoint {
  517. #[allow(deprecated)]
  518. PagePoint::new(self.page_x.into(), self.page_y.into())
  519. }
  520. /// The event's coordinates relative to the entire screen. This takes into account the window's offset.
  521. pub fn screen_coordinates(&self) -> ScreenPoint {
  522. #[allow(deprecated)]
  523. ScreenPoint::new(self.screen_x.into(), self.screen_y.into())
  524. }
  525. pub fn coordinates(&self) -> Coordinates {
  526. Coordinates::new(
  527. self.screen_coordinates(),
  528. self.client_coordinates(),
  529. self.element_coordinates(),
  530. self.page_coordinates(),
  531. )
  532. }
  533. /// The set of modifier keys which were pressed when the event occurred
  534. pub fn modifiers(&self) -> Modifiers {
  535. let mut modifiers = Modifiers::empty();
  536. #[allow(deprecated)]
  537. {
  538. if self.alt_key {
  539. modifiers.insert(Modifiers::ALT);
  540. }
  541. if self.ctrl_key {
  542. modifiers.insert(Modifiers::CONTROL);
  543. }
  544. if self.meta_key {
  545. modifiers.insert(Modifiers::META);
  546. }
  547. if self.shift_key {
  548. modifiers.insert(Modifiers::SHIFT);
  549. }
  550. }
  551. modifiers
  552. }
  553. /// The set of mouse buttons which were held when the event occurred.
  554. pub fn held_buttons(&self) -> MouseButtonSet {
  555. #[allow(deprecated)]
  556. decode_mouse_button_set(self.buttons)
  557. }
  558. /// The mouse button that triggered the event
  559. ///
  560. // todo the following is kind of bad; should we just return None when the trigger_button is unreliable (and frankly irrelevant)? i guess we would need the event_type here
  561. /// This is only guaranteed to indicate which button was pressed during events caused by pressing or releasing a button. As such, it is not reliable for events such as mouseenter, mouseleave, mouseover, mouseout, or mousemove. For example, a value of MouseButton::Primary may also indicate that no button was pressed.
  562. pub fn trigger_button(&self) -> Option<MouseButton> {
  563. #[allow(deprecated)]
  564. Some(MouseButton::from_web_code(self.button))
  565. }
  566. }
  567. pub type PointerEvent = UiEvent<PointerData>;
  568. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  569. #[derive(Debug, Clone)]
  570. pub struct PointerData {
  571. // Mouse only
  572. pub alt_key: bool,
  573. pub button: i16,
  574. pub buttons: u16,
  575. pub client_x: i32,
  576. pub client_y: i32,
  577. pub ctrl_key: bool,
  578. pub meta_key: bool,
  579. pub page_x: i32,
  580. pub page_y: i32,
  581. pub screen_x: i32,
  582. pub screen_y: i32,
  583. pub shift_key: bool,
  584. pub pointer_id: i32,
  585. pub width: i32,
  586. pub height: i32,
  587. pub pressure: f32,
  588. pub tangential_pressure: f32,
  589. pub tilt_x: i32,
  590. pub tilt_y: i32,
  591. pub twist: i32,
  592. pub pointer_type: String,
  593. pub is_primary: bool,
  594. // pub get_modifier_state: bool,
  595. }
  596. pub type SelectionEvent = UiEvent<SelectionData>;
  597. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  598. #[derive(Debug, Clone)]
  599. pub struct SelectionData {}
  600. pub type TouchEvent = UiEvent<TouchData>;
  601. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  602. #[derive(Debug, Clone)]
  603. pub struct TouchData {
  604. pub alt_key: bool,
  605. pub ctrl_key: bool,
  606. pub meta_key: bool,
  607. pub shift_key: bool,
  608. // get_modifier_state: bool,
  609. // changedTouches: DOMTouchList,
  610. // targetTouches: DOMTouchList,
  611. // touches: DOMTouchList,
  612. }
  613. pub type WheelEvent = UiEvent<WheelData>;
  614. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  615. #[derive(Debug, Clone)]
  616. pub struct WheelData {
  617. pub delta_mode: u32,
  618. pub delta_x: f64,
  619. pub delta_y: f64,
  620. pub delta_z: f64,
  621. }
  622. pub type MediaEvent = UiEvent<MediaData>;
  623. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  624. #[derive(Debug, Clone)]
  625. pub struct MediaData {}
  626. pub type ImageEvent = UiEvent<ImageData>;
  627. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  628. #[derive(Debug, Clone)]
  629. pub struct ImageData {
  630. pub load_error: bool,
  631. }
  632. pub type AnimationEvent = UiEvent<AnimationData>;
  633. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  634. #[derive(Debug, Clone)]
  635. pub struct AnimationData {
  636. pub animation_name: String,
  637. pub pseudo_element: String,
  638. pub elapsed_time: f32,
  639. }
  640. pub type TransitionEvent = UiEvent<TransitionData>;
  641. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  642. #[derive(Debug, Clone)]
  643. pub struct TransitionData {
  644. pub property_name: String,
  645. pub pseudo_element: String,
  646. pub elapsed_time: f32,
  647. }
  648. pub type ToggleEvent = UiEvent<ToggleData>;
  649. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  650. #[derive(Debug, Clone)]
  651. pub struct ToggleData {}
  652. }
  653. #[cfg_attr(
  654. feature = "serialize",
  655. derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr)
  656. )]
  657. #[derive(Clone, Copy, Debug, PartialEq)]
  658. #[repr(u8)]
  659. pub enum KeyCode {
  660. // That key has no keycode, = 0
  661. // break, = 3
  662. // backspace / delete, = 8
  663. // tab, = 9
  664. // clear, = 12
  665. // enter, = 13
  666. // shift, = 16
  667. // ctrl, = 17
  668. // alt, = 18
  669. // pause/break, = 19
  670. // caps lock, = 20
  671. // hangul, = 21
  672. // hanja, = 25
  673. // escape, = 27
  674. // conversion, = 28
  675. // non-conversion, = 29
  676. // spacebar, = 32
  677. // page up, = 33
  678. // page down, = 34
  679. // end, = 35
  680. // home, = 36
  681. // left arrow, = 37
  682. // up arrow, = 38
  683. // right arrow, = 39
  684. // down arrow, = 40
  685. // select, = 41
  686. // print, = 42
  687. // execute, = 43
  688. // Print Screen, = 44
  689. // insert, = 45
  690. // delete, = 46
  691. // help, = 47
  692. // 0, = 48
  693. // 1, = 49
  694. // 2, = 50
  695. // 3, = 51
  696. // 4, = 52
  697. // 5, = 53
  698. // 6, = 54
  699. // 7, = 55
  700. // 8, = 56
  701. // 9, = 57
  702. // :, = 58
  703. // semicolon (firefox), equals, = 59
  704. // <, = 60
  705. // equals (firefox), = 61
  706. // ß, = 63
  707. // @ (firefox), = 64
  708. // a, = 65
  709. // b, = 66
  710. // c, = 67
  711. // d, = 68
  712. // e, = 69
  713. // f, = 70
  714. // g, = 71
  715. // h, = 72
  716. // i, = 73
  717. // j, = 74
  718. // k, = 75
  719. // l, = 76
  720. // m, = 77
  721. // n, = 78
  722. // o, = 79
  723. // p, = 80
  724. // q, = 81
  725. // r, = 82
  726. // s, = 83
  727. // t, = 84
  728. // u, = 85
  729. // v, = 86
  730. // w, = 87
  731. // x, = 88
  732. // y, = 89
  733. // z, = 90
  734. // Windows Key / Left ⌘ / Chromebook Search key, = 91
  735. // right window key, = 92
  736. // Windows Menu / Right ⌘, = 93
  737. // sleep, = 95
  738. // numpad 0, = 96
  739. // numpad 1, = 97
  740. // numpad 2, = 98
  741. // numpad 3, = 99
  742. // numpad 4, = 100
  743. // numpad 5, = 101
  744. // numpad 6, = 102
  745. // numpad 7, = 103
  746. // numpad 8, = 104
  747. // numpad 9, = 105
  748. // multiply, = 106
  749. // add, = 107
  750. // numpad period (firefox), = 108
  751. // subtract, = 109
  752. // decimal point, = 110
  753. // divide, = 111
  754. // f1, = 112
  755. // f2, = 113
  756. // f3, = 114
  757. // f4, = 115
  758. // f5, = 116
  759. // f6, = 117
  760. // f7, = 118
  761. // f8, = 119
  762. // f9, = 120
  763. // f10, = 121
  764. // f11, = 122
  765. // f12, = 123
  766. // f13, = 124
  767. // f14, = 125
  768. // f15, = 126
  769. // f16, = 127
  770. // f17, = 128
  771. // f18, = 129
  772. // f19, = 130
  773. // f20, = 131
  774. // f21, = 132
  775. // f22, = 133
  776. // f23, = 134
  777. // f24, = 135
  778. // f25, = 136
  779. // f26, = 137
  780. // f27, = 138
  781. // f28, = 139
  782. // f29, = 140
  783. // f30, = 141
  784. // f31, = 142
  785. // f32, = 143
  786. // num lock, = 144
  787. // scroll lock, = 145
  788. // airplane mode, = 151
  789. // ^, = 160
  790. // !, = 161
  791. // ؛ (arabic semicolon), = 162
  792. // #, = 163
  793. // $, = 164
  794. // ù, = 165
  795. // page backward, = 166
  796. // page forward, = 167
  797. // refresh, = 168
  798. // closing paren (AZERTY), = 169
  799. // *, = 170
  800. // ~ + * key, = 171
  801. // home key, = 172
  802. // minus (firefox), mute/unmute, = 173
  803. // decrease volume level, = 174
  804. // increase volume level, = 175
  805. // next, = 176
  806. // previous, = 177
  807. // stop, = 178
  808. // play/pause, = 179
  809. // e-mail, = 180
  810. // mute/unmute (firefox), = 181
  811. // decrease volume level (firefox), = 182
  812. // increase volume level (firefox), = 183
  813. // semi-colon / ñ, = 186
  814. // equal sign, = 187
  815. // comma, = 188
  816. // dash, = 189
  817. // period, = 190
  818. // forward slash / ç, = 191
  819. // grave accent / ñ / æ / ö, = 192
  820. // ?, / or °, = 193
  821. // numpad period (chrome), = 194
  822. // open bracket, = 219
  823. // back slash, = 220
  824. // close bracket / å, = 221
  825. // single quote / ø / ä, = 222
  826. // `, = 223
  827. // left or right ⌘ key (firefox), = 224
  828. // altgr, = 225
  829. // < /git >, left back slash, = 226
  830. // GNOME Compose Key, = 230
  831. // ç, = 231
  832. // XF86Forward, = 233
  833. // XF86Back, = 234
  834. // non-conversion, = 235
  835. // alphanumeric, = 240
  836. // hiragana/katakana, = 242
  837. // half-width/full-width, = 243
  838. // kanji, = 244
  839. // unlock trackpad (Chrome/Edge), = 251
  840. // toggle touchpad, = 255
  841. NA = 0,
  842. Break = 3,
  843. Backspace = 8,
  844. Tab = 9,
  845. Clear = 12,
  846. Enter = 13,
  847. Shift = 16,
  848. Ctrl = 17,
  849. Alt = 18,
  850. Pause = 19,
  851. CapsLock = 20,
  852. // hangul, = 21
  853. // hanja, = 25
  854. Escape = 27,
  855. // conversion, = 28
  856. // non-conversion, = 29
  857. Space = 32,
  858. PageUp = 33,
  859. PageDown = 34,
  860. End = 35,
  861. Home = 36,
  862. LeftArrow = 37,
  863. UpArrow = 38,
  864. RightArrow = 39,
  865. DownArrow = 40,
  866. // select, = 41
  867. // print, = 42
  868. // execute, = 43
  869. // Print Screen, = 44
  870. Insert = 45,
  871. Delete = 46,
  872. // help, = 47
  873. Num0 = 48,
  874. Num1 = 49,
  875. Num2 = 50,
  876. Num3 = 51,
  877. Num4 = 52,
  878. Num5 = 53,
  879. Num6 = 54,
  880. Num7 = 55,
  881. Num8 = 56,
  882. Num9 = 57,
  883. // :, = 58
  884. // semicolon (firefox), equals, = 59
  885. // <, = 60
  886. // equals (firefox), = 61
  887. // ß, = 63
  888. // @ (firefox), = 64
  889. A = 65,
  890. B = 66,
  891. C = 67,
  892. D = 68,
  893. E = 69,
  894. F = 70,
  895. G = 71,
  896. H = 72,
  897. I = 73,
  898. J = 74,
  899. K = 75,
  900. L = 76,
  901. M = 77,
  902. N = 78,
  903. O = 79,
  904. P = 80,
  905. Q = 81,
  906. R = 82,
  907. S = 83,
  908. T = 84,
  909. U = 85,
  910. V = 86,
  911. W = 87,
  912. X = 88,
  913. Y = 89,
  914. Z = 90,
  915. LeftWindow = 91,
  916. RightWindow = 92,
  917. SelectKey = 93,
  918. Numpad0 = 96,
  919. Numpad1 = 97,
  920. Numpad2 = 98,
  921. Numpad3 = 99,
  922. Numpad4 = 100,
  923. Numpad5 = 101,
  924. Numpad6 = 102,
  925. Numpad7 = 103,
  926. Numpad8 = 104,
  927. Numpad9 = 105,
  928. Multiply = 106,
  929. Add = 107,
  930. Subtract = 109,
  931. DecimalPoint = 110,
  932. Divide = 111,
  933. F1 = 112,
  934. F2 = 113,
  935. F3 = 114,
  936. F4 = 115,
  937. F5 = 116,
  938. F6 = 117,
  939. F7 = 118,
  940. F8 = 119,
  941. F9 = 120,
  942. F10 = 121,
  943. F11 = 122,
  944. F12 = 123,
  945. // f13, = 124
  946. // f14, = 125
  947. // f15, = 126
  948. // f16, = 127
  949. // f17, = 128
  950. // f18, = 129
  951. // f19, = 130
  952. // f20, = 131
  953. // f21, = 132
  954. // f22, = 133
  955. // f23, = 134
  956. // f24, = 135
  957. // f25, = 136
  958. // f26, = 137
  959. // f27, = 138
  960. // f28, = 139
  961. // f29, = 140
  962. // f30, = 141
  963. // f31, = 142
  964. // f32, = 143
  965. NumLock = 144,
  966. ScrollLock = 145,
  967. // airplane mode, = 151
  968. // ^, = 160
  969. // !, = 161
  970. // ؛ (arabic semicolon), = 162
  971. // #, = 163
  972. // $, = 164
  973. // ù, = 165
  974. // page backward, = 166
  975. // page forward, = 167
  976. // refresh, = 168
  977. // closing paren (AZERTY), = 169
  978. // *, = 170
  979. // ~ + * key, = 171
  980. // home key, = 172
  981. // minus (firefox), mute/unmute, = 173
  982. // decrease volume level, = 174
  983. // increase volume level, = 175
  984. // next, = 176
  985. // previous, = 177
  986. // stop, = 178
  987. // play/pause, = 179
  988. // e-mail, = 180
  989. // mute/unmute (firefox), = 181
  990. // decrease volume level (firefox), = 182
  991. // increase volume level (firefox), = 183
  992. Semicolon = 186,
  993. EqualSign = 187,
  994. Comma = 188,
  995. Dash = 189,
  996. Period = 190,
  997. ForwardSlash = 191,
  998. GraveAccent = 192,
  999. // ?, / or °, = 193
  1000. // numpad period (chrome), = 194
  1001. OpenBracket = 219,
  1002. BackSlash = 220,
  1003. CloseBraket = 221,
  1004. SingleQuote = 222,
  1005. // `, = 223
  1006. // left or right ⌘ key (firefox), = 224
  1007. // altgr, = 225
  1008. // < /git >, left back slash, = 226
  1009. // GNOME Compose Key, = 230
  1010. // ç, = 231
  1011. // XF86Forward, = 233
  1012. // XF86Back, = 234
  1013. // non-conversion, = 235
  1014. // alphanumeric, = 240
  1015. // hiragana/katakana, = 242
  1016. // half-width/full-width, = 243
  1017. // kanji, = 244
  1018. // unlock trackpad (Chrome/Edge), = 251
  1019. // toggle touchpad, = 255
  1020. #[cfg_attr(feature = "serialize", serde(other))]
  1021. Unknown,
  1022. }
  1023. impl KeyCode {
  1024. pub fn from_raw_code(i: u8) -> Self {
  1025. use KeyCode::*;
  1026. match i {
  1027. 8 => Backspace,
  1028. 9 => Tab,
  1029. 13 => Enter,
  1030. 16 => Shift,
  1031. 17 => Ctrl,
  1032. 18 => Alt,
  1033. 19 => Pause,
  1034. 20 => CapsLock,
  1035. 27 => Escape,
  1036. 33 => PageUp,
  1037. 34 => PageDown,
  1038. 35 => End,
  1039. 36 => Home,
  1040. 37 => LeftArrow,
  1041. 38 => UpArrow,
  1042. 39 => RightArrow,
  1043. 40 => DownArrow,
  1044. 45 => Insert,
  1045. 46 => Delete,
  1046. 48 => Num0,
  1047. 49 => Num1,
  1048. 50 => Num2,
  1049. 51 => Num3,
  1050. 52 => Num4,
  1051. 53 => Num5,
  1052. 54 => Num6,
  1053. 55 => Num7,
  1054. 56 => Num8,
  1055. 57 => Num9,
  1056. 65 => A,
  1057. 66 => B,
  1058. 67 => C,
  1059. 68 => D,
  1060. 69 => E,
  1061. 70 => F,
  1062. 71 => G,
  1063. 72 => H,
  1064. 73 => I,
  1065. 74 => J,
  1066. 75 => K,
  1067. 76 => L,
  1068. 77 => M,
  1069. 78 => N,
  1070. 79 => O,
  1071. 80 => P,
  1072. 81 => Q,
  1073. 82 => R,
  1074. 83 => S,
  1075. 84 => T,
  1076. 85 => U,
  1077. 86 => V,
  1078. 87 => W,
  1079. 88 => X,
  1080. 89 => Y,
  1081. 90 => Z,
  1082. 91 => LeftWindow,
  1083. 92 => RightWindow,
  1084. 93 => SelectKey,
  1085. 96 => Numpad0,
  1086. 97 => Numpad1,
  1087. 98 => Numpad2,
  1088. 99 => Numpad3,
  1089. 100 => Numpad4,
  1090. 101 => Numpad5,
  1091. 102 => Numpad6,
  1092. 103 => Numpad7,
  1093. 104 => Numpad8,
  1094. 105 => Numpad9,
  1095. 106 => Multiply,
  1096. 107 => Add,
  1097. 109 => Subtract,
  1098. 110 => DecimalPoint,
  1099. 111 => Divide,
  1100. 112 => F1,
  1101. 113 => F2,
  1102. 114 => F3,
  1103. 115 => F4,
  1104. 116 => F5,
  1105. 117 => F6,
  1106. 118 => F7,
  1107. 119 => F8,
  1108. 120 => F9,
  1109. 121 => F10,
  1110. 122 => F11,
  1111. 123 => F12,
  1112. 144 => NumLock,
  1113. 145 => ScrollLock,
  1114. 186 => Semicolon,
  1115. 187 => EqualSign,
  1116. 188 => Comma,
  1117. 189 => Dash,
  1118. 190 => Period,
  1119. 191 => ForwardSlash,
  1120. 192 => GraveAccent,
  1121. 219 => OpenBracket,
  1122. 220 => BackSlash,
  1123. 221 => CloseBraket,
  1124. 222 => SingleQuote,
  1125. _ => Unknown,
  1126. }
  1127. }
  1128. // get the raw code
  1129. pub fn raw_code(&self) -> u32 {
  1130. *self as u32
  1131. }
  1132. }
  1133. pub(crate) fn _event_meta(event: &UserEvent) -> (bool, EventPriority) {
  1134. use EventPriority::*;
  1135. match event.name {
  1136. // clipboard
  1137. "copy" | "cut" | "paste" => (true, Medium),
  1138. // Composition
  1139. "compositionend" | "compositionstart" | "compositionupdate" => (true, Low),
  1140. // Keyboard
  1141. "keydown" | "keypress" | "keyup" => (true, High),
  1142. // Focus
  1143. "focus" | "blur" | "focusout" | "focusin" => (true, Low),
  1144. // Form
  1145. "change" | "input" | "invalid" | "reset" | "submit" => (true, Medium),
  1146. // Mouse
  1147. "click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit"
  1148. | "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter"
  1149. | "mouseleave" | "mouseout" | "mouseover" | "mouseup" => (true, High),
  1150. "mousemove" => (false, Medium),
  1151. // Pointer
  1152. "pointerdown" | "pointermove" | "pointerup" | "pointercancel" | "gotpointercapture"
  1153. | "lostpointercapture" | "pointerenter" | "pointerleave" | "pointerover" | "pointerout" => {
  1154. (true, Medium)
  1155. }
  1156. // Selection
  1157. "select" | "touchcancel" | "touchend" => (true, Medium),
  1158. // Touch
  1159. "touchmove" | "touchstart" => (true, Medium),
  1160. // Wheel
  1161. "scroll" | "wheel" => (false, Medium),
  1162. // Media
  1163. "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted"
  1164. | "ended" | "error" | "loadeddata" | "loadedmetadata" | "loadstart" | "pause" | "play"
  1165. | "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
  1166. | "timeupdate" | "volumechange" | "waiting" => (true, Medium),
  1167. // Animation
  1168. "animationstart" | "animationend" | "animationiteration" => (true, Medium),
  1169. // Transition
  1170. "transitionend" => (true, Medium),
  1171. // Toggle
  1172. "toggle" => (true, Medium),
  1173. _ => (true, Low),
  1174. }
  1175. }