keyboard.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. use crate::input_data::{decode_key_location, encode_key_location};
  2. use dioxus_core::Event;
  3. use keyboard_types::{Code, Key, Location, Modifiers};
  4. use std::convert::TryInto;
  5. use std::fmt::{Debug, Formatter};
  6. use std::str::FromStr;
  7. #[cfg(feature = "serialize")]
  8. fn resilient_deserialize_code<'de, D>(deserializer: D) -> Result<Code, D::Error>
  9. where
  10. D: serde::Deserializer<'de>,
  11. {
  12. use serde::Deserialize;
  13. // If we fail to deserialize the code for any reason, just return Unidentified instead of failing.
  14. Ok(Code::deserialize(deserializer).unwrap_or(Code::Unidentified))
  15. }
  16. pub type KeyboardEvent = Event<KeyboardData>;
  17. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  18. #[derive(Clone, PartialEq, Eq)]
  19. pub struct KeyboardData {
  20. #[deprecated(
  21. since = "0.3.0",
  22. note = "This may not work in all environments. Use key() instead."
  23. )]
  24. pub char_code: u32,
  25. /// Identify which "key" was entered.
  26. #[deprecated(since = "0.3.0", note = "use key() instead")]
  27. pub key: String,
  28. /// Get the key code as an enum Variant.
  29. #[deprecated(
  30. since = "0.3.0",
  31. note = "This may not work in all environments. Use code() instead."
  32. )]
  33. pub key_code: KeyCode,
  34. /// the physical key on the keyboard
  35. #[cfg_attr(
  36. feature = "serialize",
  37. serde(deserialize_with = "resilient_deserialize_code")
  38. )]
  39. code: Code,
  40. /// Indicate if the `alt` modifier key was pressed during this keyboard event
  41. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  42. pub alt_key: bool,
  43. /// Indicate if the `ctrl` modifier key was pressed during this keyboard event
  44. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  45. pub ctrl_key: bool,
  46. /// Indicate if the `meta` modifier key was pressed during this keyboard event
  47. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  48. pub meta_key: bool,
  49. /// Indicate if the `shift` modifier key was pressed during this keyboard event
  50. #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
  51. pub shift_key: bool,
  52. #[deprecated(since = "0.3.0", note = "use location() instead")]
  53. pub location: usize,
  54. #[deprecated(since = "0.3.0", note = "use is_auto_repeating() instead")]
  55. pub repeat: bool,
  56. #[deprecated(since = "0.3.0", note = "use code() or key() instead")]
  57. pub which: usize,
  58. }
  59. impl_event! {
  60. KeyboardData;
  61. /// onkeydown
  62. onkeydown
  63. /// onkeypress
  64. onkeypress
  65. /// onkeyup
  66. onkeyup
  67. }
  68. impl KeyboardData {
  69. pub fn new(
  70. key: Key,
  71. code: Code,
  72. location: Location,
  73. is_auto_repeating: bool,
  74. modifiers: Modifiers,
  75. ) -> Self {
  76. #[allow(deprecated)]
  77. KeyboardData {
  78. char_code: key.legacy_charcode(),
  79. key: key.to_string(),
  80. key_code: KeyCode::from_raw_code(
  81. key.legacy_keycode()
  82. .try_into()
  83. .expect("could not convert keycode to u8"),
  84. ),
  85. code,
  86. alt_key: modifiers.contains(Modifiers::ALT),
  87. ctrl_key: modifiers.contains(Modifiers::CONTROL),
  88. meta_key: modifiers.contains(Modifiers::META),
  89. shift_key: modifiers.contains(Modifiers::SHIFT),
  90. location: encode_key_location(location),
  91. repeat: is_auto_repeating,
  92. which: key
  93. .legacy_charcode()
  94. .try_into()
  95. .expect("could not convert charcode to usize"),
  96. }
  97. }
  98. /// The value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
  99. pub fn key(&self) -> Key {
  100. #[allow(deprecated)]
  101. FromStr::from_str(&self.key).unwrap_or(Key::Unidentified)
  102. }
  103. /// A physical key on the keyboard (as opposed to the character generated by pressing the key). In other words, this property returns a value that isn't altered by keyboard layout or the state of the modifier keys.
  104. pub fn code(&self) -> Code {
  105. self.code
  106. }
  107. /// The set of modifier keys which were pressed when the event occurred
  108. pub fn modifiers(&self) -> Modifiers {
  109. let mut modifiers = Modifiers::empty();
  110. #[allow(deprecated)]
  111. {
  112. if self.alt_key {
  113. modifiers.insert(Modifiers::ALT);
  114. }
  115. if self.ctrl_key {
  116. modifiers.insert(Modifiers::CONTROL);
  117. }
  118. if self.meta_key {
  119. modifiers.insert(Modifiers::META);
  120. }
  121. if self.shift_key {
  122. modifiers.insert(Modifiers::SHIFT);
  123. }
  124. }
  125. modifiers
  126. }
  127. /// The location of the key on the keyboard or other input device.
  128. pub fn location(&self) -> Location {
  129. #[allow(deprecated)]
  130. decode_key_location(self.location)
  131. }
  132. /// `true` iff the key is being held down such that it is automatically repeating.
  133. pub fn is_auto_repeating(&self) -> bool {
  134. #[allow(deprecated)]
  135. self.repeat
  136. }
  137. }
  138. impl Debug for KeyboardData {
  139. fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
  140. f.debug_struct("KeyboardData")
  141. .field("key", &self.key())
  142. .field("code", &self.code())
  143. .field("modifiers", &self.modifiers())
  144. .field("location", &self.location())
  145. .field("is_auto_repeating", &self.is_auto_repeating())
  146. .finish()
  147. }
  148. }
  149. #[cfg(feature = "serialize")]
  150. impl<'de> serde::Deserialize<'de> for KeyCode {
  151. fn deserialize<D>(deserializer: D) -> Result<KeyCode, D::Error>
  152. where
  153. D: serde::Deserializer<'de>,
  154. {
  155. // We could be deserializing a unicode character, so we need to use u64 even if the output only takes u8
  156. let value = u64::deserialize(deserializer)?;
  157. if let Ok(smaller_uint) = value.try_into() {
  158. Ok(KeyCode::from_raw_code(smaller_uint))
  159. } else {
  160. Ok(KeyCode::Unknown)
  161. }
  162. }
  163. }
  164. #[cfg_attr(feature = "serialize", derive(serde_repr::Serialize_repr))]
  165. #[derive(Clone, Copy, Debug, Eq, PartialEq)]
  166. #[repr(u8)]
  167. pub enum KeyCode {
  168. // That key has no keycode, = 0
  169. // break, = 3
  170. // backspace / delete, = 8
  171. // tab, = 9
  172. // clear, = 12
  173. // enter, = 13
  174. // shift, = 16
  175. // ctrl, = 17
  176. // alt, = 18
  177. // pause/break, = 19
  178. // caps lock, = 20
  179. // hangul, = 21
  180. // hanja, = 25
  181. // escape, = 27
  182. // conversion, = 28
  183. // non-conversion, = 29
  184. // spacebar, = 32
  185. // page up, = 33
  186. // page down, = 34
  187. // end, = 35
  188. // home, = 36
  189. // left arrow, = 37
  190. // up arrow, = 38
  191. // right arrow, = 39
  192. // down arrow, = 40
  193. // select, = 41
  194. // print, = 42
  195. // execute, = 43
  196. // Print Screen, = 44
  197. // insert, = 45
  198. // delete, = 46
  199. // help, = 47
  200. // 0, = 48
  201. // 1, = 49
  202. // 2, = 50
  203. // 3, = 51
  204. // 4, = 52
  205. // 5, = 53
  206. // 6, = 54
  207. // 7, = 55
  208. // 8, = 56
  209. // 9, = 57
  210. // :, = 58
  211. // semicolon (firefox), equals, = 59
  212. // <, = 60
  213. // equals (firefox), = 61
  214. // ß, = 63
  215. // @ (firefox), = 64
  216. // a, = 65
  217. // b, = 66
  218. // c, = 67
  219. // d, = 68
  220. // e, = 69
  221. // f, = 70
  222. // g, = 71
  223. // h, = 72
  224. // i, = 73
  225. // j, = 74
  226. // k, = 75
  227. // l, = 76
  228. // m, = 77
  229. // n, = 78
  230. // o, = 79
  231. // p, = 80
  232. // q, = 81
  233. // r, = 82
  234. // s, = 83
  235. // t, = 84
  236. // u, = 85
  237. // v, = 86
  238. // w, = 87
  239. // x, = 88
  240. // y, = 89
  241. // z, = 90
  242. // Windows Key / Left ⌘ / Chromebook Search key, = 91
  243. // right window key, = 92
  244. // Windows Menu / Right ⌘, = 93
  245. // sleep, = 95
  246. // numpad 0, = 96
  247. // numpad 1, = 97
  248. // numpad 2, = 98
  249. // numpad 3, = 99
  250. // numpad 4, = 100
  251. // numpad 5, = 101
  252. // numpad 6, = 102
  253. // numpad 7, = 103
  254. // numpad 8, = 104
  255. // numpad 9, = 105
  256. // multiply, = 106
  257. // add, = 107
  258. // numpad period (firefox), = 108
  259. // subtract, = 109
  260. // decimal point, = 110
  261. // divide, = 111
  262. // f1, = 112
  263. // f2, = 113
  264. // f3, = 114
  265. // f4, = 115
  266. // f5, = 116
  267. // f6, = 117
  268. // f7, = 118
  269. // f8, = 119
  270. // f9, = 120
  271. // f10, = 121
  272. // f11, = 122
  273. // f12, = 123
  274. // f13, = 124
  275. // f14, = 125
  276. // f15, = 126
  277. // f16, = 127
  278. // f17, = 128
  279. // f18, = 129
  280. // f19, = 130
  281. // f20, = 131
  282. // f21, = 132
  283. // f22, = 133
  284. // f23, = 134
  285. // f24, = 135
  286. // f25, = 136
  287. // f26, = 137
  288. // f27, = 138
  289. // f28, = 139
  290. // f29, = 140
  291. // f30, = 141
  292. // f31, = 142
  293. // f32, = 143
  294. // num lock, = 144
  295. // scroll lock, = 145
  296. // airplane mode, = 151
  297. // ^, = 160
  298. // !, = 161
  299. // ؛ (arabic semicolon), = 162
  300. // #, = 163
  301. // $, = 164
  302. // ù, = 165
  303. // page backward, = 166
  304. // page forward, = 167
  305. // refresh, = 168
  306. // closing paren (AZERTY), = 169
  307. // *, = 170
  308. // ~ + * key, = 171
  309. // home key, = 172
  310. // minus (firefox), mute/unmute, = 173
  311. // decrease volume level, = 174
  312. // increase volume level, = 175
  313. // next, = 176
  314. // previous, = 177
  315. // stop, = 178
  316. // play/pause, = 179
  317. // e-mail, = 180
  318. // mute/unmute (firefox), = 181
  319. // decrease volume level (firefox), = 182
  320. // increase volume level (firefox), = 183
  321. // semi-colon / ñ, = 186
  322. // equal sign, = 187
  323. // comma, = 188
  324. // dash, = 189
  325. // period, = 190
  326. // forward slash / ç, = 191
  327. // grave accent / ñ / æ / ö, = 192
  328. // ?, / or °, = 193
  329. // numpad period (chrome), = 194
  330. // open bracket, = 219
  331. // back slash, = 220
  332. // close bracket / å, = 221
  333. // single quote / ø / ä, = 222
  334. // `, = 223
  335. // left or right ⌘ key (firefox), = 224
  336. // altgr, = 225
  337. // < /git >, left back slash, = 226
  338. // GNOME Compose Key, = 230
  339. // ç, = 231
  340. // XF86Forward, = 233
  341. // XF86Back, = 234
  342. // non-conversion, = 235
  343. // alphanumeric, = 240
  344. // hiragana/katakana, = 242
  345. // half-width/full-width, = 243
  346. // kanji, = 244
  347. // unlock trackpad (Chrome/Edge), = 251
  348. // toggle touchpad, = 255
  349. NA = 0,
  350. Break = 3,
  351. Backspace = 8,
  352. Tab = 9,
  353. Clear = 12,
  354. Enter = 13,
  355. Shift = 16,
  356. Ctrl = 17,
  357. Alt = 18,
  358. Pause = 19,
  359. CapsLock = 20,
  360. // hangul, = 21
  361. // hanja, = 25
  362. Escape = 27,
  363. // conversion, = 28
  364. // non-conversion, = 29
  365. Space = 32,
  366. PageUp = 33,
  367. PageDown = 34,
  368. End = 35,
  369. Home = 36,
  370. LeftArrow = 37,
  371. UpArrow = 38,
  372. RightArrow = 39,
  373. DownArrow = 40,
  374. // select, = 41
  375. // print, = 42
  376. // execute, = 43
  377. // Print Screen, = 44
  378. Insert = 45,
  379. Delete = 46,
  380. // help, = 47
  381. Num0 = 48,
  382. Num1 = 49,
  383. Num2 = 50,
  384. Num3 = 51,
  385. Num4 = 52,
  386. Num5 = 53,
  387. Num6 = 54,
  388. Num7 = 55,
  389. Num8 = 56,
  390. Num9 = 57,
  391. // :, = 58
  392. // semicolon (firefox), equals, = 59
  393. // <, = 60
  394. // equals (firefox), = 61
  395. // ß, = 63
  396. // @ (firefox), = 64
  397. A = 65,
  398. B = 66,
  399. C = 67,
  400. D = 68,
  401. E = 69,
  402. F = 70,
  403. G = 71,
  404. H = 72,
  405. I = 73,
  406. J = 74,
  407. K = 75,
  408. L = 76,
  409. M = 77,
  410. N = 78,
  411. O = 79,
  412. P = 80,
  413. Q = 81,
  414. R = 82,
  415. S = 83,
  416. T = 84,
  417. U = 85,
  418. V = 86,
  419. W = 87,
  420. X = 88,
  421. Y = 89,
  422. Z = 90,
  423. LeftWindow = 91,
  424. RightWindow = 92,
  425. SelectKey = 93,
  426. Numpad0 = 96,
  427. Numpad1 = 97,
  428. Numpad2 = 98,
  429. Numpad3 = 99,
  430. Numpad4 = 100,
  431. Numpad5 = 101,
  432. Numpad6 = 102,
  433. Numpad7 = 103,
  434. Numpad8 = 104,
  435. Numpad9 = 105,
  436. Multiply = 106,
  437. Add = 107,
  438. Subtract = 109,
  439. DecimalPoint = 110,
  440. Divide = 111,
  441. F1 = 112,
  442. F2 = 113,
  443. F3 = 114,
  444. F4 = 115,
  445. F5 = 116,
  446. F6 = 117,
  447. F7 = 118,
  448. F8 = 119,
  449. F9 = 120,
  450. F10 = 121,
  451. F11 = 122,
  452. F12 = 123,
  453. // f13, = 124
  454. // f14, = 125
  455. // f15, = 126
  456. // f16, = 127
  457. // f17, = 128
  458. // f18, = 129
  459. // f19, = 130
  460. // f20, = 131
  461. // f21, = 132
  462. // f22, = 133
  463. // f23, = 134
  464. // f24, = 135
  465. // f25, = 136
  466. // f26, = 137
  467. // f27, = 138
  468. // f28, = 139
  469. // f29, = 140
  470. // f30, = 141
  471. // f31, = 142
  472. // f32, = 143
  473. NumLock = 144,
  474. ScrollLock = 145,
  475. // airplane mode, = 151
  476. // ^, = 160
  477. // !, = 161
  478. // ؛ (arabic semicolon), = 162
  479. // #, = 163
  480. // $, = 164
  481. // ù, = 165
  482. // page backward, = 166
  483. // page forward, = 167
  484. // refresh, = 168
  485. // closing paren (AZERTY), = 169
  486. // *, = 170
  487. // ~ + * key, = 171
  488. // home key, = 172
  489. // minus (firefox), mute/unmute, = 173
  490. // decrease volume level, = 174
  491. // increase volume level, = 175
  492. // next, = 176
  493. // previous, = 177
  494. // stop, = 178
  495. // play/pause, = 179
  496. // e-mail, = 180
  497. // mute/unmute (firefox), = 181
  498. // decrease volume level (firefox), = 182
  499. // increase volume level (firefox), = 183
  500. Semicolon = 186,
  501. EqualSign = 187,
  502. Comma = 188,
  503. Dash = 189,
  504. Period = 190,
  505. ForwardSlash = 191,
  506. GraveAccent = 192,
  507. // ?, / or °, = 193
  508. // numpad period (chrome), = 194
  509. OpenBracket = 219,
  510. BackSlash = 220,
  511. CloseBraket = 221,
  512. SingleQuote = 222,
  513. // `, = 223
  514. // left or right ⌘ key (firefox), = 224
  515. // altgr, = 225
  516. // < /git >, left back slash, = 226
  517. // GNOME Compose Key, = 230
  518. // ç, = 231
  519. // XF86Forward, = 233
  520. // XF86Back, = 234
  521. // non-conversion, = 235
  522. // alphanumeric, = 240
  523. // hiragana/katakana, = 242
  524. // half-width/full-width, = 243
  525. // kanji, = 244
  526. // unlock trackpad (Chrome/Edge), = 251
  527. // toggle touchpad, = 255
  528. Unknown,
  529. }
  530. impl KeyCode {
  531. pub fn from_raw_code(i: u8) -> Self {
  532. use KeyCode::*;
  533. match i {
  534. 8 => Backspace,
  535. 9 => Tab,
  536. 13 => Enter,
  537. 16 => Shift,
  538. 17 => Ctrl,
  539. 18 => Alt,
  540. 19 => Pause,
  541. 20 => CapsLock,
  542. 27 => Escape,
  543. 33 => PageUp,
  544. 34 => PageDown,
  545. 35 => End,
  546. 36 => Home,
  547. 37 => LeftArrow,
  548. 38 => UpArrow,
  549. 39 => RightArrow,
  550. 40 => DownArrow,
  551. 45 => Insert,
  552. 46 => Delete,
  553. 48 => Num0,
  554. 49 => Num1,
  555. 50 => Num2,
  556. 51 => Num3,
  557. 52 => Num4,
  558. 53 => Num5,
  559. 54 => Num6,
  560. 55 => Num7,
  561. 56 => Num8,
  562. 57 => Num9,
  563. 65 => A,
  564. 66 => B,
  565. 67 => C,
  566. 68 => D,
  567. 69 => E,
  568. 70 => F,
  569. 71 => G,
  570. 72 => H,
  571. 73 => I,
  572. 74 => J,
  573. 75 => K,
  574. 76 => L,
  575. 77 => M,
  576. 78 => N,
  577. 79 => O,
  578. 80 => P,
  579. 81 => Q,
  580. 82 => R,
  581. 83 => S,
  582. 84 => T,
  583. 85 => U,
  584. 86 => V,
  585. 87 => W,
  586. 88 => X,
  587. 89 => Y,
  588. 90 => Z,
  589. 91 => LeftWindow,
  590. 92 => RightWindow,
  591. 93 => SelectKey,
  592. 96 => Numpad0,
  593. 97 => Numpad1,
  594. 98 => Numpad2,
  595. 99 => Numpad3,
  596. 100 => Numpad4,
  597. 101 => Numpad5,
  598. 102 => Numpad6,
  599. 103 => Numpad7,
  600. 104 => Numpad8,
  601. 105 => Numpad9,
  602. 106 => Multiply,
  603. 107 => Add,
  604. 109 => Subtract,
  605. 110 => DecimalPoint,
  606. 111 => Divide,
  607. 112 => F1,
  608. 113 => F2,
  609. 114 => F3,
  610. 115 => F4,
  611. 116 => F5,
  612. 117 => F6,
  613. 118 => F7,
  614. 119 => F8,
  615. 120 => F9,
  616. 121 => F10,
  617. 122 => F11,
  618. 123 => F12,
  619. 144 => NumLock,
  620. 145 => ScrollLock,
  621. 186 => Semicolon,
  622. 187 => EqualSign,
  623. 188 => Comma,
  624. 189 => Dash,
  625. 190 => Period,
  626. 191 => ForwardSlash,
  627. 192 => GraveAccent,
  628. 219 => OpenBracket,
  629. 220 => BackSlash,
  630. 221 => CloseBraket,
  631. 222 => SingleQuote,
  632. _ => Unknown,
  633. }
  634. }
  635. // get the raw code
  636. pub fn raw_code(&self) -> u32 {
  637. *self as u32
  638. }
  639. }