keyboard.monkey2 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. Namespace mojo.input
  2. #Import "native/keyinfo.h"
  3. #Import "native/keyinfo.cpp"
  4. Extern Private
  5. Struct bbKeyInfo
  6. Field name:Void Ptr
  7. Field scanCode:Int
  8. Field keyCode:Int
  9. End
  10. Global bbKeyInfos:bbKeyInfo Ptr
  11. Public
  12. #rem monkeydoc Global instance of the KeyboardDevice class.
  13. #end
  14. Const Keyboard:=New KeyboardDevice
  15. #rem monkeydoc The KeyboardDevice class.
  16. All method that take a `key` parameter can also be used with 'raw' keys.
  17. A raw key represents the physical location of a key on US keyboards. For example, `Key.Q|Key.Raw` indicates the key at the top left of the
  18. 'qwerty' keys regardless of the current keyboard layout.
  19. Please see the [[Key]] enum for more information on raw keys.
  20. To access the keyboard device, use the global [[Keyboard]] constant.
  21. The keyboard device should only used after a new [[app.AppInstance]] is created.
  22. #end
  23. Class KeyboardDevice Extends InputDevice
  24. #rem monkeydoc The current state of the modifier keys.
  25. #end
  26. Property Modifiers:Modifier()
  27. Return _modifiers
  28. End
  29. #rem monkeydoc Gets the name of a key.
  30. If `key` is a raw key, returns the name 'printed' on that key.
  31. if `key` is a virtual key
  32. #end
  33. Method KeyName:String( key:Key )
  34. If key & key.Raw key=TranslateKey( key )
  35. Return _names[key]
  36. End
  37. #rem monkeydoc Translates a key to/from a raw key.
  38. If `key` is a raw key, returns the corresponding virual key.
  39. If `key` is a virtual key, returns the corresponding raw key.
  40. #end
  41. Method TranslateKey:Key( key:Key )
  42. If key & Key.Raw
  43. #If __TARGET__="emscripten"
  44. Return key & ~Key.Raw
  45. #Else
  46. Local keyCode:=SDL_GetKeyFromScancode( Cast<SDL_Scancode>( _raw2scan[ key & ~Key.Raw ] ) )
  47. Return KeyCodeToKey( keyCode )
  48. #Endif
  49. Else
  50. Local scanCode:=_key2scan[key]
  51. Return _scan2raw[scanCode]
  52. Endif
  53. Return Key.None
  54. End
  55. #rem monkeydoc Checks the current up/down state of a key.
  56. Returns true if `key` is currently held down.
  57. If `key` is a raw key, the state of the key as it is physically positioned on US keyboards is returned.
  58. @param key Key to check.
  59. #end
  60. Method KeyDown:Bool( key:Key )
  61. Local scode:=ScanCode( key )
  62. Return _matrix[scode]
  63. End
  64. #rem monkeydoc Checks if a key was pressed.
  65. Returns true if `key` was pressed since the last call to KeyPressed with the same key.
  66. If `key` is a raw key, the state of the key as it is physically positioned on US keyboards is returned.
  67. @param key Key to check.
  68. #end
  69. Method KeyPressed:Bool( key:Key )
  70. Local scode:=ScanCode( key )
  71. If _matrix[scode]
  72. If _pressed[scode] Return False
  73. _pressed[scode]=True
  74. Return True
  75. Endif
  76. _pressed[scode]=False
  77. Return False
  78. End
  79. #rem monkeydoc Checks if a key was released.
  80. Returns true if `key` was released since the last call to KeyReleased with the same key.
  81. If `key` is a raw key, the state of the key as it is physically positioned on US keyboards is returned.
  82. @param key Key to check.
  83. #end
  84. Method KeyReleased:Bool( key:Key )
  85. Local scode:=ScanCode( key )
  86. If Not _matrix[scode]
  87. If _released[scode] Return False
  88. _released[scode]=True
  89. Return True
  90. Endif
  91. _released[scode]=False
  92. Return False
  93. End
  94. #rem monkeydoc @hidden
  95. #end
  96. Method KeyHit:Bool( key:Key )
  97. Return KeyPressed( key )
  98. End
  99. '***** Internal *****
  100. #rem monkeydoc @hidden
  101. #end
  102. Method Reset()
  103. For Local i:=0 Until 512
  104. _matrix[i]=False
  105. _pressed[i]=True
  106. _released[i]=True
  107. Next
  108. _modifiers=Null
  109. End
  110. #rem monkeydoc @hidden
  111. #end
  112. Method ScanCode:Int( key:Key )
  113. If key & Key.Raw Return _raw2scan[ key & ~Key.Raw ]
  114. Return _key2scan[ key ]
  115. End
  116. #rem monkeydoc @hidden
  117. #end
  118. Method KeyCodeToKey:Key( keyCode:Int )
  119. If (keyCode & $40000000) keyCode=(keyCode & ~$40000000)+$80
  120. Return Cast<Key>( keyCode )
  121. End
  122. #rem monkeydoc @hidden
  123. #end
  124. Method ScanCodeToRawKey:Key( scanCode:Int )
  125. Return _scan2raw[ scanCode ]
  126. End
  127. #rem monkeydoc @hidden
  128. #end
  129. Method Init()
  130. If _init Return
  131. _init=True
  132. Local p:=bbKeyInfos
  133. While p->name
  134. Local name:=String.FromCString( p->name )
  135. Local scanCode:=p->scanCode
  136. Local keyCode:=p->keyCode
  137. Local key:=KeyCodeToKey( keyCode )
  138. _names[key]=name
  139. _raw2scan[key]=scanCode
  140. _scan2raw[scanCode]=key | Key.Raw
  141. #If __TARGET__="emscripten"
  142. _key2scan[key]=scanCode
  143. #Else
  144. _key2scan[key]=SDL_GetScancodeFromKey( Cast<SDL_Keycode>( keyCode ) )
  145. #Endif
  146. _scan2key[_key2scan[key]]=scanCode
  147. p=p+1
  148. Wend
  149. Reset()
  150. End
  151. #rem monkeydoc @hidden
  152. #end
  153. Method SendEvent( event:SDL_Event Ptr )
  154. OnEvent( event )
  155. End
  156. Private
  157. Field _init:Bool
  158. Field _modifiers:Modifier
  159. Field _matrix:=New Bool[512]
  160. Field _pressed:=New Bool[512]
  161. Field _released:=New Bool[512]
  162. Field _names:=New String[512]
  163. Field _raw2scan:=New Int[512] 'no translate
  164. Field _scan2raw:=New Key[512] 'no translate
  165. Field _key2scan:=New Int[512] 'translate
  166. Field _scan2key:=New Int[512] 'translate
  167. Method New()
  168. End
  169. Method OnEvent( event:SDL_Event Ptr )
  170. Select event->type
  171. Case SDL_KEYDOWN
  172. Local kevent:=Cast<SDL_KeyboardEvent Ptr>( event )
  173. _matrix[kevent->keysym.scancode]=True
  174. Select kevent->keysym.sym
  175. Case $400000e0 _modifiers|=Modifier.LeftControl
  176. Case $400000e1 _modifiers|=Modifier.LeftShift
  177. Case $400000e2 _modifiers|=Modifier.LeftAlt
  178. Case $400000e3 _modifiers|=Modifier.LeftGui
  179. Case $400000e4 _modifiers|=Modifier.RightControl
  180. Case $400000e5 _modifiers|=Modifier.RightShift
  181. Case $400000e6 _modifiers|=Modifier.RightAlt
  182. Case $400000e7 _modifiers|=Modifier.RightGui
  183. End
  184. Case SDL_KEYUP
  185. Local kevent:=Cast<SDL_KeyboardEvent Ptr>( event )
  186. _matrix[kevent->keysym.scancode]=False
  187. Select kevent->keysym.sym
  188. Case $400000e0 _modifiers&=~Modifier.LeftControl
  189. Case $400000e1 _modifiers&=~Modifier.LeftShift
  190. Case $400000e2 _modifiers&=~Modifier.LeftAlt
  191. Case $400000e3 _modifiers&=~Modifier.LeftGui
  192. Case $400000e4 _modifiers&=~Modifier.RightControl
  193. Case $400000e5 _modifiers&=~Modifier.RightShift
  194. Case $400000e6 _modifiers&=~Modifier.RightAlt
  195. Case $400000e7 _modifiers&=~Modifier.RightGui
  196. End
  197. End
  198. End
  199. End