Event.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. //
  2. // Evemts.cs: Events, Key mappings
  3. //
  4. // Authors:
  5. // Miguel de Icaza ([email protected])
  6. //
  7. using System;
  8. namespace Terminal.Gui {
  9. /// <summary>
  10. /// Identifies the state of the "shift"-keys within a event.
  11. /// </summary>
  12. public class KeyModifiers {
  13. /// <summary>
  14. /// Check if the Shift key was pressed or not.
  15. /// </summary>
  16. public bool Shift;
  17. /// <summary>
  18. /// Check if the Alt key was pressed or not.
  19. /// </summary>
  20. public bool Alt;
  21. /// <summary>
  22. /// Check if the Ctrl key was pressed or not.
  23. /// </summary>
  24. public bool Ctrl;
  25. /// <summary>
  26. /// Check if the Caps lock key was pressed or not.
  27. /// </summary>
  28. public bool Capslock;
  29. /// <summary>
  30. /// Check if the Num lock key was pressed or not.
  31. /// </summary>
  32. public bool Numlock;
  33. /// <summary>
  34. /// Check if the Scroll lock key was pressed or not.
  35. /// </summary>
  36. public bool Scrolllock;
  37. }
  38. /// <summary>
  39. /// The <see cref="Key"/> enumeration contains special encoding for some keys, but can also
  40. /// encode all the unicode values that can be passed.
  41. /// </summary>
  42. /// <remarks>
  43. /// <para>
  44. /// If the <see cref="SpecialMask"/> is set, then the value is that of the special mask,
  45. /// otherwise, the value is the one of the lower bits (as extracted by <see cref="CharMask"/>)
  46. /// </para>
  47. /// <para>
  48. /// Control keys are the values between 1 and 26 corresponding to Control-A to Control-Z
  49. /// </para>
  50. /// <para>
  51. /// Unicode runes are also stored here, the letter 'A" for example is encoded as a value 65 (not surfaced in the enum).
  52. /// </para>
  53. /// </remarks>
  54. [Flags]
  55. public enum Key : uint {
  56. /// <summary>
  57. /// Mask that indicates that this is a character value, values outside this range
  58. /// indicate special characters like Alt-key combinations or special keys on the
  59. /// keyboard like function keys, arrows keys and so on.
  60. /// </summary>
  61. CharMask = 0xfffff,
  62. /// <summary>
  63. /// If the <see cref="SpecialMask"/> is set, then the value is that of the special mask,
  64. /// otherwise, the value is the one of the lower bits (as extracted by <see cref="CharMask"/>).
  65. /// </summary>
  66. SpecialMask = 0xfff00000,
  67. /// <summary>
  68. /// The key code for the user pressing Control-spacebar
  69. /// </summary>
  70. ControlSpace = 0,
  71. /// <summary>
  72. /// The key code for the user pressing Control-A
  73. /// </summary>
  74. ControlA = 1,
  75. /// <summary>
  76. /// The key code for the user pressing Control-B
  77. /// </summary>
  78. ControlB,
  79. /// <summary>
  80. /// The key code for the user pressing Control-C
  81. /// </summary>
  82. ControlC,
  83. /// <summary>
  84. /// The key code for the user pressing Control-D
  85. /// </summary>
  86. ControlD,
  87. /// <summary>
  88. /// The key code for the user pressing Control-E
  89. /// </summary>
  90. ControlE,
  91. /// <summary>
  92. /// The key code for the user pressing Control-F
  93. /// </summary>
  94. ControlF,
  95. /// <summary>
  96. /// The key code for the user pressing Control-G
  97. /// </summary>
  98. ControlG,
  99. /// <summary>
  100. /// The key code for the user pressing Control-H
  101. /// </summary>
  102. ControlH,
  103. /// <summary>
  104. /// The key code for the user pressing Control-I (same as the tab key).
  105. /// </summary>
  106. ControlI,
  107. /// <summary>
  108. /// The key code for the user pressing Control-J
  109. /// </summary>
  110. ControlJ,
  111. /// <summary>
  112. /// The key code for the user pressing Control-K
  113. /// </summary>
  114. ControlK,
  115. /// <summary>
  116. /// The key code for the user pressing Control-L
  117. /// </summary>
  118. ControlL,
  119. /// <summary>
  120. /// The key code for the user pressing Control-M
  121. /// </summary>
  122. ControlM,
  123. /// <summary>
  124. /// The key code for the user pressing Control-N (same as the return key).
  125. /// </summary>
  126. ControlN,
  127. /// <summary>
  128. /// The key code for the user pressing Control-O
  129. /// </summary>
  130. ControlO,
  131. /// <summary>
  132. /// The key code for the user pressing Control-P
  133. /// </summary>
  134. ControlP,
  135. /// <summary>
  136. /// The key code for the user pressing Control-Q
  137. /// </summary>
  138. ControlQ,
  139. /// <summary>
  140. /// The key code for the user pressing Control-R
  141. /// </summary>
  142. ControlR,
  143. /// <summary>
  144. /// The key code for the user pressing Control-S
  145. /// </summary>
  146. ControlS,
  147. /// <summary>
  148. /// The key code for the user pressing Control-T
  149. /// </summary>
  150. ControlT,
  151. /// <summary>
  152. /// The key code for the user pressing Control-U
  153. /// </summary>
  154. ControlU,
  155. /// <summary>
  156. /// The key code for the user pressing Control-V
  157. /// </summary>
  158. ControlV,
  159. /// <summary>
  160. /// The key code for the user pressing Control-W
  161. /// </summary>
  162. ControlW,
  163. /// <summary>
  164. /// The key code for the user pressing Control-X
  165. /// </summary>
  166. ControlX,
  167. /// <summary>
  168. /// The key code for the user pressing Control-Y
  169. /// </summary>
  170. ControlY,
  171. /// <summary>
  172. /// The key code for the user pressing Control-Z
  173. /// </summary>
  174. ControlZ,
  175. /// <summary>
  176. /// The key code for the user pressing the escape key
  177. /// </summary>
  178. Esc = 27,
  179. /// <summary>
  180. /// The key code for the user pressing the return key.
  181. /// </summary>
  182. Enter = '\n',
  183. /// <summary>
  184. /// The key code for the user pressing the space bar
  185. /// </summary>
  186. Space = 32,
  187. /// <summary>
  188. /// The key code for the user pressing the delete key.
  189. /// </summary>
  190. Delete = 127,
  191. /// <summary>
  192. /// When this value is set, the Key encodes the sequence Shift-KeyValue.
  193. /// </summary>
  194. ShiftMask = 0x10000000,
  195. /// <summary>
  196. /// When this value is set, the Key encodes the sequence Alt-KeyValue.
  197. /// And the actual value must be extracted by removing the AltMask.
  198. /// </summary>
  199. AltMask = 0x80000000,
  200. /// <summary>
  201. /// When this value is set, the Key encodes the sequence Ctrl-KeyValue.
  202. /// And the actual value must be extracted by removing the CtrlMask.
  203. /// </summary>
  204. CtrlMask = 0x40000000,
  205. /// <summary>
  206. /// Backspace key.
  207. /// </summary>
  208. Backspace = 0x100000,
  209. /// <summary>
  210. /// Cursor up key
  211. /// </summary>
  212. CursorUp,
  213. /// <summary>
  214. /// Cursor down key.
  215. /// </summary>
  216. CursorDown,
  217. /// <summary>
  218. /// Cursor left key.
  219. /// </summary>
  220. CursorLeft,
  221. /// <summary>
  222. /// Cursor right key.
  223. /// </summary>
  224. CursorRight,
  225. /// <summary>
  226. /// Page Up key.
  227. /// </summary>
  228. PageUp,
  229. /// <summary>
  230. /// Page Down key.
  231. /// </summary>
  232. PageDown,
  233. /// <summary>
  234. /// Home key
  235. /// </summary>
  236. Home,
  237. /// <summary>
  238. /// End key
  239. /// </summary>
  240. End,
  241. /// <summary>
  242. /// Delete character key
  243. /// </summary>
  244. DeleteChar,
  245. /// <summary>
  246. /// Insert character key
  247. /// </summary>
  248. InsertChar,
  249. /// <summary>
  250. /// F1 key.
  251. /// </summary>
  252. F1,
  253. /// <summary>
  254. /// F2 key.
  255. /// </summary>
  256. F2,
  257. /// <summary>
  258. /// F3 key.
  259. /// </summary>
  260. F3,
  261. /// <summary>
  262. /// F4 key.
  263. /// </summary>
  264. F4,
  265. /// <summary>
  266. /// F5 key.
  267. /// </summary>
  268. F5,
  269. /// <summary>
  270. /// F6 key.
  271. /// </summary>
  272. F6,
  273. /// <summary>
  274. /// F7 key.
  275. /// </summary>
  276. F7,
  277. /// <summary>
  278. /// F8 key.
  279. /// </summary>
  280. F8,
  281. /// <summary>
  282. /// F9 key.
  283. /// </summary>
  284. F9,
  285. /// <summary>
  286. /// F10 key.
  287. /// </summary>
  288. F10,
  289. /// <summary>
  290. /// F11 key.
  291. /// </summary>
  292. F11,
  293. /// <summary>
  294. /// F12 key.
  295. /// </summary>
  296. F12,
  297. /// <summary>
  298. /// The key code for the user pressing the tab key (forwards tab key).
  299. /// </summary>
  300. Tab,
  301. /// <summary>
  302. /// Shift-tab key (backwards tab key).
  303. /// </summary>
  304. BackTab,
  305. /// <summary>
  306. /// A key with an unknown mapping was raised.
  307. /// </summary>
  308. Unknown
  309. }
  310. /// <summary>
  311. /// Describes a keyboard event.
  312. /// </summary>
  313. public class KeyEvent {
  314. KeyModifiers keyModifiers;
  315. /// <summary>
  316. /// Symb olid definition for the key.
  317. /// </summary>
  318. public Key Key;
  319. /// <summary>
  320. /// The key value cast to an integer, you will typical use this for
  321. /// extracting the Unicode rune value out of a key, when none of the
  322. /// symbolic options are in use.
  323. /// </summary>
  324. public int KeyValue => (int)Key;
  325. /// <summary>
  326. /// Gets a value indicating whether the Shift key was pressed.
  327. /// </summary>
  328. /// <value><c>true</c> if is shift; otherwise, <c>false</c>.</value>
  329. public bool IsShift => keyModifiers.Shift;
  330. /// <summary>
  331. /// Gets a value indicating whether the Alt key was pressed (real or synthesized)
  332. /// </summary>
  333. /// <value><c>true</c> if is alternate; otherwise, <c>false</c>.</value>
  334. public bool IsAlt => keyModifiers.Alt;
  335. /// <summary>
  336. /// Determines whether the value is a control key (and NOT just the ctrl key)
  337. /// </summary>
  338. /// <value><c>true</c> if is ctrl; otherwise, <c>false</c>.</value>
  339. //public bool IsCtrl => ((uint)Key >= 1) && ((uint)Key <= 26);
  340. public bool IsCtrl => keyModifiers.Ctrl;
  341. /// <summary>
  342. /// Gets a value indicating whether the Caps lock key was pressed (real or synthesized)
  343. /// </summary>
  344. /// <value><c>true</c> if is alternate; otherwise, <c>false</c>.</value>
  345. public bool IsCapslock => keyModifiers.Capslock;
  346. /// <summary>
  347. /// Gets a value indicating whether the Num lock key was pressed (real or synthesized)
  348. /// </summary>
  349. /// <value><c>true</c> if is alternate; otherwise, <c>false</c>.</value>
  350. public bool IsNumlock => keyModifiers.Numlock;
  351. /// <summary>
  352. /// Gets a value indicating whether the Scroll lock key was pressed (real or synthesized)
  353. /// </summary>
  354. /// <value><c>true</c> if is alternate; otherwise, <c>false</c>.</value>
  355. public bool IsScrolllock => keyModifiers.Scrolllock;
  356. /// <summary>
  357. /// Constructs a new <see cref="KeyEvent"/>
  358. /// </summary>
  359. public KeyEvent ()
  360. {
  361. Key = Key.Unknown;
  362. keyModifiers = new KeyModifiers ();
  363. }
  364. /// <summary>
  365. /// Constructs a new <see cref="KeyEvent"/> from the provided Key value - can be a rune cast into a Key value
  366. /// </summary>
  367. public KeyEvent (Key k, KeyModifiers km)
  368. {
  369. Key = k;
  370. keyModifiers = km;
  371. }
  372. /// <summary>
  373. /// Pretty prints the KeyEvent
  374. /// </summary>
  375. /// <returns></returns>
  376. public override string ToString ()
  377. {
  378. string msg = "";
  379. var key = this.Key;
  380. if (keyModifiers.Shift) {
  381. msg += "Shift-";
  382. }
  383. if (keyModifiers.Alt) {
  384. msg += "Alt-";
  385. }
  386. if (keyModifiers.Ctrl) {
  387. msg += "Ctrl-";
  388. }
  389. if (keyModifiers.Capslock) {
  390. msg += "Capslock-";
  391. }
  392. if (keyModifiers.Numlock) {
  393. msg += "Numlock-";
  394. }
  395. if (keyModifiers.Scrolllock) {
  396. msg += "Scrolllock-";
  397. }
  398. msg += $"{(((uint)this.KeyValue & (uint)Key.CharMask) > 27 ? $"{(char)this.KeyValue}" : $"{key}")}";
  399. return msg;
  400. }
  401. }
  402. /// <summary>
  403. /// Mouse flags reported in <see cref="MouseEvent"/>.
  404. /// </summary>
  405. /// <remarks>
  406. /// They just happen to map to the ncurses ones.
  407. /// </remarks>
  408. [Flags]
  409. public enum MouseFlags {
  410. /// <summary>
  411. /// The first mouse button was pressed.
  412. /// </summary>
  413. Button1Pressed = unchecked((int)0x2),
  414. /// <summary>
  415. /// The first mouse button was released.
  416. /// </summary>
  417. Button1Released = unchecked((int)0x1),
  418. /// <summary>
  419. /// The first mouse button was clicked (press+release).
  420. /// </summary>
  421. Button1Clicked = unchecked((int)0x4),
  422. /// <summary>
  423. /// The first mouse button was double-clicked.
  424. /// </summary>
  425. Button1DoubleClicked = unchecked((int)0x8),
  426. /// <summary>
  427. /// The first mouse button was triple-clicked.
  428. /// </summary>
  429. Button1TripleClicked = unchecked((int)0x10),
  430. /// <summary>
  431. /// The second mouse button was pressed.
  432. /// </summary>
  433. Button2Pressed = unchecked((int)0x80),
  434. /// <summary>
  435. /// The second mouse button was released.
  436. /// </summary>
  437. Button2Released = unchecked((int)0x40),
  438. /// <summary>
  439. /// The second mouse button was clicked (press+release).
  440. /// </summary>
  441. Button2Clicked = unchecked((int)0x100),
  442. /// <summary>
  443. /// The second mouse button was double-clicked.
  444. /// </summary>
  445. Button2DoubleClicked = unchecked((int)0x200),
  446. /// <summary>
  447. /// The second mouse button was triple-clicked.
  448. /// </summary>
  449. Button2TripleClicked = unchecked((int)0x400),
  450. /// <summary>
  451. /// The third mouse button was pressed.
  452. /// </summary>
  453. Button3Pressed = unchecked((int)0x2000),
  454. /// <summary>
  455. /// The third mouse button was released.
  456. /// </summary>
  457. Button3Released = unchecked((int)0x1000),
  458. /// <summary>
  459. /// The third mouse button was clicked (press+release).
  460. /// </summary>
  461. Button3Clicked = unchecked((int)0x4000),
  462. /// <summary>
  463. /// The third mouse button was double-clicked.
  464. /// </summary>
  465. Button3DoubleClicked = unchecked((int)0x8000),
  466. /// <summary>
  467. /// The third mouse button was triple-clicked.
  468. /// </summary>
  469. Button3TripleClicked = unchecked((int)0x10000),
  470. /// <summary>
  471. /// The fourth mouse button was pressed.
  472. /// </summary>
  473. Button4Pressed = unchecked((int)0x80000),
  474. /// <summary>
  475. /// The fourth mouse button was released.
  476. /// </summary>
  477. Button4Released = unchecked((int)0x40000),
  478. /// <summary>
  479. /// The fourth button was clicked (press+release).
  480. /// </summary>
  481. Button4Clicked = unchecked((int)0x100000),
  482. /// <summary>
  483. /// The fourth button was double-clicked.
  484. /// </summary>
  485. Button4DoubleClicked = unchecked((int)0x200000),
  486. /// <summary>
  487. /// The fourth button was triple-clicked.
  488. /// </summary>
  489. Button4TripleClicked = unchecked((int)0x400000),
  490. /// <summary>
  491. /// Flag: the shift key was pressed when the mouse button took place.
  492. /// </summary>
  493. ButtonShift = unchecked((int)0x2000000),
  494. /// <summary>
  495. /// Flag: the ctrl key was pressed when the mouse button took place.
  496. /// </summary>
  497. ButtonCtrl = unchecked((int)0x1000000),
  498. /// <summary>
  499. /// Flag: the alt key was pressed when the mouse button took place.
  500. /// </summary>
  501. ButtonAlt = unchecked((int)0x4000000),
  502. /// <summary>
  503. /// The mouse position is being reported in this event.
  504. /// </summary>
  505. ReportMousePosition = unchecked((int)0x8000000),
  506. /// <summary>
  507. /// Vertical button wheeled up.
  508. /// </summary>
  509. WheeledUp = unchecked((int)0x10000000),
  510. /// <summary>
  511. /// Vertical button wheeled up.
  512. /// </summary>
  513. WheeledDown = unchecked((int)0x20000000),
  514. /// <summary>
  515. /// Vertical button wheeled up while pressing ButtonShift.
  516. /// </summary>
  517. WheeledLeft = ButtonShift | WheeledUp,
  518. /// <summary>
  519. /// Vertical button wheeled down while pressing ButtonShift.
  520. /// </summary>
  521. WheeledRight = ButtonShift | WheeledDown,
  522. /// <summary>
  523. /// Mask that captures all the events.
  524. /// </summary>
  525. AllEvents = unchecked((int)0x7ffffff),
  526. }
  527. /// <summary>
  528. /// Describes a mouse event
  529. /// </summary>
  530. public struct MouseEvent {
  531. /// <summary>
  532. /// The X (column) location for the mouse event.
  533. /// </summary>
  534. public int X;
  535. /// <summary>
  536. /// The Y (column) location for the mouse event.
  537. /// </summary>
  538. public int Y;
  539. /// <summary>
  540. /// Flags indicating the kind of mouse event that is being posted.
  541. /// </summary>
  542. public MouseFlags Flags;
  543. /// <summary>
  544. /// The offset X (column) location for the mouse event.
  545. /// </summary>
  546. public int OfX;
  547. /// <summary>
  548. /// The offset Y (column) location for the mouse event.
  549. /// </summary>
  550. public int OfY;
  551. /// <summary>
  552. /// The current view at the location for the mouse event.
  553. /// </summary>
  554. public View View;
  555. /// <summary>
  556. /// Returns a <see cref="T:System.String"/> that represents the current <see cref="MouseEvent"/>.
  557. /// </summary>
  558. /// <returns>A <see cref="T:System.String"/> that represents the current <see cref="MouseEvent"/>.</returns>
  559. public override string ToString ()
  560. {
  561. return $"({X},{Y}:{Flags}";
  562. }
  563. }
  564. }