events.rs 40 KB

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