events.rs 27 KB

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