Keyboard.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /******************************************************************************
  2. Use 'Kb' to access Keyboard input.
  3. Use 'KbSc' to describe keyboard shortcuts.
  4. /******************************************************************************/
  5. struct Keyboard // Keyboard Input
  6. {
  7. struct Key
  8. {
  9. Char c;
  10. KB_KEY k;
  11. Byte flags;
  12. Bool any ()C {return c || k ;} // if any character or key pressed
  13. Bool ctrl ()C {return FlagTest(flags, CTRL );} // if any Control pressed
  14. Bool shift ()C {return FlagTest(flags, SHIFT);} // if any Shift pressed
  15. Bool alt ()C {return FlagTest(flags, ALT );} // if any Alt pressed
  16. Bool win ()C {return FlagTest(flags, WIN );} // if any Win pressed
  17. Bool lalt ()C {return FlagTest(flags, LALT );} // if Left Alt pressed
  18. Bool first ()C {return FlagTest(flags, FIRST);} // if this is the first press of the key (if false then it's a repeated press)
  19. Bool ctrlCmd()C {return APPLE ? win () : ctrl();} // if any Ctrl is on (on platforms other than Apple), and if any Command is on (on Apple platforms)
  20. Bool winCtrl()C {return APPLE ? ctrl() : win ();} // if any Win is on (on platforms other than Apple), and if any Control is on (on Apple platforms)
  21. Bool operator()(Char c)C {return T.c==c;} // use simple == instead of 'EqualCS' for performance reasons
  22. Bool operator()(Char8 c)C {return T.c==c;} // use simple == instead of 'EqualCS' for performance reasons
  23. Bool operator()(KB_KEY k)C {return T.k==k;}
  24. Bool first (KB_KEY k)C {return T.k==k && first();} // if this is the first press of 'k' key
  25. void clear() {c='\0'; k=KB_NONE; flags=0;}
  26. void eat()C; // eat this key input from this frame so it will not be processed by the remaining codes in frame
  27. enum
  28. {
  29. CTRL =1<<0,
  30. SHIFT=1<<1,
  31. ALT =1<<2,
  32. WIN =1<<3,
  33. LALT =1<<4,
  34. FIRST=1<<5,
  35. };
  36. };
  37. // get
  38. #if EE_PRIVATE
  39. Key k;
  40. #else
  41. const Key k; // key pressed in this frame
  42. #endif
  43. Bool kf(KB_KEY k)C {return T.k.first(k);} // if key 'k' is pressed and it's the first press
  44. Bool b (KB_KEY k)C {return ButtonOn(_button[k]);} // if key 'k' is on
  45. Bool bp(KB_KEY k)C {return ButtonPd(_button[k]);} // if key 'k' pushed in this frame
  46. Bool br(KB_KEY k)C {return ButtonRs(_button[k]);} // if key 'k' released in this frame
  47. Bool bd(KB_KEY k)C {return ButtonDb(_button[k]);} // if key 'k' double clicked
  48. #if EE_PRIVATE
  49. void _assert() {ASSERT(1<<(8*SIZE(KB_KEY))==ELMS(_button));} // because we use 'KB_KEY' as index to '_button' in methods above
  50. Bool visibleWanted()C;
  51. #endif
  52. Bool ctrl ()C {return _ctrl ;} // if any Ctrl is on (this is equal to "b(KB_LCTRL ) || b(KB_RCTRL )")
  53. Bool shift()C {return _shift;} // if any Shift is on (this is equal to "b(KB_LSHIFT) || b(KB_RSHIFT)")
  54. Bool alt ()C {return _alt ;} // if any Alt is on (this is equal to "b(KB_LALT ) || b(KB_RALT )")
  55. Bool win ()C {return _win ;} // if any Win is on (this is equal to "b(KB_LWIN ) || b(KB_RWIN )")
  56. #if EE_PRIVATE // this checks the most recent state, to be used while receiving inputs from the system (unlike methods above which use cached values at the start of the frame)
  57. Bool anyCtrl ()C {return ButtonOn(_button[KB_LCTRL ]|_button[KB_RCTRL ]);}
  58. Bool anyShift()C {return ButtonOn(_button[KB_LSHIFT]|_button[KB_RSHIFT]);}
  59. Bool anyAlt ()C {return ButtonOn(_button[KB_LALT ]|_button[KB_RALT ]);}
  60. Bool anyWin ()C {return ButtonOn(_button[KB_LWIN ]|_button[KB_RWIN ]);}
  61. #endif
  62. Char keyChar(KB_KEY key)C; // get key character, example: keyChar(KB_SPACE) -> ' '
  63. CChar8* keyName(KB_KEY key)C; // get key name , example: keyName(KB_SPACE) -> "Space"
  64. Bool hwAvailable ( ); // if hardware keyboard is available
  65. Bool softCoverage(Rect &rect); // get soft keyboard (on-screen) coverage, false if no screen keyboard is currently displayed
  66. KB_KEY qwerty(KB_KEY qwerty)C; // convert key from QWERTY layout to layout of current keyboard
  67. // operations
  68. void eat( ); // eat all input from this frame so it will not be processed by the remaining codes in frame
  69. void eat(Char c ); // eat 'c' input from this frame so it will not be processed by the remaining codes in frame
  70. void eat(Char8 c ); // eat 'c' input from this frame so it will not be processed by the remaining codes in frame
  71. void eat(KB_KEY key); // eat 'key' input from this frame so it will not be processed by the remaining codes in frame
  72. void eatKey( ); // eat 'Kb.k' input from this frame so it will not be processed by the remaining codes in frame
  73. #if EE_PRIVATE
  74. void nextInQueue(); // proceed to next key from the buffer, same like 'nextKey' but without 'eatKey'
  75. Key* nextKeyPtr(); // get next key in the queue, without calling 'eatKey' and without moving it to 'Kb.k' but just return a pointer to it, null if none
  76. #endif
  77. void nextKey(); // specify that you've processed 'Kb.k' and would like to proceed to the next key in the queue
  78. void queue(C Key &key); // manually add 'key' to the buffer to be processed later
  79. Bool exclusive()C {return _exclusive;} void exclusive(Bool on); // get/set keyboard exclusive mode (which disables Windows key on Windows platform), default=false
  80. void requestTextInput(); // call this each frame if you wish to manually process the keyboard input in text format, this enables IMM on Windows and displays screen keyboard on Mobile platforms, this is automatically enabled if Gui keyboard focus is on 'TextLine' or 'TextBox' object
  81. #if EE_PRIVATE
  82. void refreshTextInput();
  83. void setTextInput(C Str &text, Int start, Int end, Bool password);
  84. #endif
  85. // IMM (Windows Input Method Manager) control
  86. #if EE_PRIVATE
  87. Bool imm ()C; void imm (Bool enable); // get/set if disable/enable the ability to use Windows Input Method Manager, this method is automatically called be the engine when keyboard focus is switched to text editing capable gui object
  88. #endif
  89. Bool immNative ()C; void immNative(Bool native); // get/set if native typing mode is currently enabled
  90. Int immCursor ()C {return _imm_cursor ;} // get IMM cursor position
  91. C VecI2 & immSelection()C {return _imm_selection;} // get IMM clause selection range, where x=min index, y=max index
  92. C Str & immBuffer ()C {return _imm_buffer ;} // get IMM text buffer
  93. C Memc<Str>& immCandidate()C {return _imm_candidate;} // get IMM candidate list
  94. #if EE_PRIVATE
  95. // manage
  96. void init ();
  97. void del ();
  98. void create ();
  99. void acquire(Bool on);
  100. void setLayout();
  101. // operations
  102. void clear ();
  103. void push (KB_KEY key, Int scan_code);
  104. void queue (Char chr, Int scan_code);
  105. void release(KB_KEY key);
  106. void update ();
  107. void swappedCtrlCmd(Bool swapped); Bool swappedCtrlCmd()C {return _swapped_ctrl_cmd;} // set/get if Ctrl is swapped with Cmd key under Mac OS, enable this method if you have swapped Ctrl with Cmd key under System Preferences but you wish to get their original mapping under the engine, this method is used only under Mac, default=false
  108. #endif
  109. Bool ctrlCmd ()C {return APPLE ? _win : _ctrl ;} // if any Ctrl is on (on platforms other than Apple), and if any Command is on (on Apple platforms)
  110. Bool winCtrl ()C {return APPLE ? _ctrl : _win ;} // if any Win is on (on platforms other than Apple), and if any Control is on (on Apple platforms)
  111. CChar8* ctrlCmdName()C {return APPLE ? "Cmd" : "Ctrl";}
  112. CChar8* winCtrlName()C {return APPLE ? "Ctrl": "Win" ;}
  113. #if !EE_PRIVATE
  114. private:
  115. #endif
  116. Bool _ctrl, _shift, _alt, _win, _hidden, _swapped_ctrl_cmd, _text_input, _visible, _refresh_visible, _imm, _imm_candidate_hidden, _exclusive;
  117. Byte _button[256], _key_buffer_pos, _key_buffer_len;
  118. Char8 _key_char[256];
  119. Key _key_buffer[256];
  120. KB_KEY _qwerty[256];
  121. Int _cur, _last, _imm_cursor, _last_key_scan_code;
  122. Flt _curh_t, _curh_tn;
  123. Dbl _last_t;
  124. RectI _recti;
  125. VecI2 _imm_selection;
  126. Str _imm_buffer;
  127. Memc<Str> _imm_candidate, _imm_candidate_temp;
  128. CChar8 *_key_name[256];
  129. #if EE_PRIVATE
  130. #if WINDOWS_OLD
  131. IDirectInputDevice8 *_did;
  132. #else
  133. Ptr _did;
  134. #endif
  135. PLATFORM(HIMC, Ptr) _imc;
  136. #else
  137. Ptr _did, _imc;
  138. #endif
  139. Keyboard();
  140. NO_COPY_CONSTRUCTOR(Keyboard);
  141. }extern
  142. Kb;
  143. /******************************************************************************/
  144. enum KBSC_FLAG // Keyboard Shortcut Flags
  145. {
  146. KBSC_CTRL =0x01, // Control required
  147. KBSC_SHIFT=0x02, // Shift required (this is ignored for KBSC_CHAR, instead please specify upper/lower case of the character)
  148. KBSC_ALT =0x04, // Alt required (for KBSC_CHAR - only left alt is checked, also for KBSC_CHAR this may not work well if KBSC_CTRL is enabled too, as on Windows pressing Ctrl+Alt triggers accented characters and regular characters may not get generated)
  149. KBSC_WIN =0x08, // Win required
  150. KBSC_CTRL_CMD=0x10, // Control required on non-Apple platforms, and Command required on Apple platforms
  151. KBSC_WIN_CTRL=0x20, // Win required on non-Apple platforms, and Control required on Apple platforms
  152. KBSC_REPEAT=0x40, // allow repeated execution when holding key for a long time (currently this affects only KBSC_KEY, as KBSC_CHAR always allow this)
  153. };
  154. enum KBSC_MODE : Byte // Keyboard Shortcut Mode
  155. {
  156. KBSC_NONE, // disabled
  157. KBSC_CHAR, // treat 'index' as Char
  158. KBSC_KEY , // treat 'index' as KB_KEY
  159. };
  160. struct KbSc // Keyboard Shortcut
  161. {
  162. Byte flag ; // KBSC_FLAG
  163. KBSC_MODE mode ; // mode
  164. UShort index; // Char/KB_KEY depending on 'mode'
  165. // get
  166. Bool is ()C {return mode!=KBSC_NONE;} // if shortcut is valid
  167. Bool pd ()C; // if pushed in this frame
  168. Str asText()C; // get text describing the shortcut
  169. // operations
  170. void eat()C; // eat this shortcut keys input from this frame so it will not be processed by the remaining codes in frame
  171. #if EE_PRIVATE
  172. Bool testFlag ()C;
  173. Bool testFlagChar()C;
  174. #endif
  175. KbSc( ) {T.index=0 ; T.flag=0 ; T.mode=KBSC_NONE;}
  176. KbSc(Char8 c , Byte flag=0) {T.index=Char8To16(c); T.flag=flag; T.mode=KBSC_CHAR;}
  177. KbSc(Char c , Byte flag=0) {T.index=c ; T.flag=flag; T.mode=KBSC_CHAR;}
  178. KbSc(KB_KEY key, Byte flag=0) {T.index=key ; T.flag=flag; T.mode=KBSC_KEY ;}
  179. };
  180. /******************************************************************************/
  181. #if EE_PRIVATE
  182. #if WINDOWS_OLD
  183. #define KB_RAW_INPUT 1
  184. #elif MAC
  185. extern const KB_KEY ScanCodeToQwertyKey[0x80]; extern KB_KEY ScanCodeToKey[Elms(ScanCodeToQwertyKey)];
  186. #elif LINUX
  187. extern const KB_KEY ScanCodeToQwertyKey[0x90]; extern KB_KEY ScanCodeToKey[Elms(ScanCodeToQwertyKey)];
  188. #endif
  189. #endif
  190. /******************************************************************************/