events.rs 27 KB

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