input.nim 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. # author: Ethosa
  2. import
  3. vector2,
  4. rect2
  5. {.used.}
  6. type
  7. InputEventType* {.size: sizeof(int8).} = enum
  8. MOUSE, TOUCH, MOTION, KEYBOARD, UNKNOWN
  9. InputAction* = object
  10. kind*: InputEventType
  11. key_int*: int8
  12. key_cint*: cint
  13. button_index*: cint
  14. name*, key*: string
  15. Input* = object
  16. InputEvent* = ref object
  17. kind*: InputEventType
  18. pressed*: bool
  19. key_int*: int8
  20. key_cint*: cint
  21. button_index*: cint
  22. x*, y*, xrel*, yrel*: float
  23. key*: string
  24. InputEventVoid* = distinct int8
  25. InputEventMouseButton* = distinct int8
  26. InputEventMouseMotion* = distinct int8
  27. InputEventTouchScreen* = distinct int8
  28. InputEventKeyboard* = distinct int8
  29. const
  30. BUTTON_LEFT* = 0
  31. BUTTON_MIDDLE* = 1
  32. BUTTON_RIGHT* = 2
  33. BUTTON_RELEASE* = 0
  34. BUTTON_CLICK* = 1
  35. K_F1* = 1
  36. K_F2* = 2
  37. K_F3* = 3
  38. K_F4* = 4
  39. K_F5* = 5
  40. K_F6* = 6
  41. K_F7* = 7
  42. K_F8* = 8
  43. K_F9* = 9
  44. K_TAB* = 9
  45. K_F10* = 10
  46. K_F11* = 11
  47. K_F12* = 12
  48. K_ENTER* = 13
  49. K_ESCAPE* = 27
  50. K_SPACE* = 32
  51. K_NUM_MUL* = 42
  52. K_NUM_SUB* = 45
  53. K_NUM_ADD* = 43
  54. K_NUM_POINT* = 46
  55. K_NUM_DIV* = 47
  56. K_0* = 48
  57. K_1* = 49
  58. K_2* = 50
  59. K_3* = 51
  60. K_4* = 52
  61. K_5* = 53
  62. K_6* = 54
  63. K_7* = 55
  64. K_8* = 56
  65. K_9* = 57
  66. K_LEFT* = 100
  67. K_UP* = 101
  68. K_RIGHT* = 102
  69. K_DOWN* = 103
  70. K_PAGE_UP* = 104
  71. K_PAGE_DOWN* = 105
  72. K_HOME* = 106
  73. K_END* = 107
  74. K_INSERT* = 108
  75. K_DELETE* = 127
  76. var
  77. pressed_keys*: seq[string] = @[]
  78. pressed_keys_ints*: seq[int8] = @[]
  79. pressed_keys_cints*: seq[cint] = @[]
  80. last_event*: InputEvent = InputEvent()
  81. last_key_state*: bool = false
  82. key_state*: bool = false
  83. press_state*: int = 0
  84. actionlist*: seq[InputAction] = @[]
  85. mouse_pressed*: bool = false
  86. proc isInputEventVoid*(a: InputEvent): bool =
  87. a.kind == UNKNOWN
  88. proc isInputEventMouseButton*(a: InputEvent): bool =
  89. a.kind == MOUSE
  90. proc isInputEventMouseMotion*(a: InputEvent): bool =
  91. a.kind == MOTION
  92. proc isInputEventTouchScreen*(a: InputEvent): bool =
  93. a.kind == TOUCH
  94. proc isInputEventKeyboard*(a: InputEvent): bool =
  95. a.kind == KEYBOARD
  96. proc addButtonAction*(a: type Input, name: string, button: cint) =
  97. ## Adds a new action on button.
  98. ##
  99. ## Arguments:
  100. ## - `name` - action name.
  101. ## - `button` - button index, e.g.: BUTTON_LEFT, BUTTON_RIGHT or BUTTON_MIDDLE.
  102. actionlist.add(InputAction(kind: MOUSE, name: name, button_index: button))
  103. proc addKeyAction*(a: type Input, name, key: string) =
  104. ## Adds a new action on keyboard.
  105. ##
  106. ## Arguments:
  107. ## - `name` - action name.
  108. ## - `key` - key, e.g.: "w", "1", etc.
  109. actionlist.add(InputAction(kind: KEYBOARD, name: name, key: key))
  110. proc addKeyAction*(a: type Input, name: string, key: int8) =
  111. ## Adds a new action on keyboard.
  112. ##
  113. ## Arguments:
  114. ## - `name` - action name.
  115. ## - `key` - key, e.g.: K_ESCAPE, K_0, etc.
  116. actionlist.add(InputAction(kind: KEYBOARD, name: name, key_int: key))
  117. proc addTouchAction*(a: type Input, name: string) =
  118. ## Adds a new action on touch screen.
  119. ##
  120. ## Arguments:
  121. ## - `name` - action name.
  122. actionlist.add(InputAction(kind: TOUCH, name: name))
  123. proc isActionJustPressed*(a: type Input, name: string): bool =
  124. ## Returns true, when action active one times.
  125. ##
  126. ## Arguments:
  127. ## - `name` - action name.
  128. result = false
  129. for action in actionlist:
  130. if action.name == name:
  131. if action.kind == MOUSE and (last_event.kind == MOUSE or last_event.kind == MOTION):
  132. if action.button_index == last_event.button_index and mouse_pressed:
  133. if press_state == 1:
  134. result = true
  135. elif action.kind == TOUCH and last_event.kind == TOUCH:
  136. if press_state == 1:
  137. result = true
  138. elif action.kind == KEYBOARD and last_event.kind == KEYBOARD:
  139. if (action.key == last_event.key or action.key_int == last_event.key_int) and last_key_state == false:
  140. if press_state == 1:
  141. result = true
  142. proc isActionPressed*(a: type Input, name: string): bool =
  143. ## Returns true, when action active one or more times.
  144. ##
  145. ## Arguments:
  146. ## - `name` - action name.
  147. result = false
  148. for action in actionlist:
  149. if action.name == name:
  150. if action.kind == MOUSE:
  151. if action.button_index == last_event.button_index and mouse_pressed:
  152. result = true
  153. elif action.kind == TOUCH and last_event.kind == TOUCH:
  154. if press_state > 0:
  155. result = true
  156. elif action.kind == KEYBOARD and last_event.kind == KEYBOARD:
  157. if action.key in pressed_keys or action.key_int in pressed_keys_ints:
  158. if press_state > 0:
  159. result = true
  160. proc isActionReleased*(a: type Input, name: string): bool =
  161. ## Returns true, when action no more active.
  162. ##
  163. ## Arguments:
  164. ## - `name` - action name.
  165. result = false
  166. for action in actionlist:
  167. if action.name == name:
  168. if action.kind == MOUSE and (last_event.kind == MOUSE or last_event.kind == MOTION):
  169. if action.button_index == last_event.button_index and not mouse_pressed:
  170. if press_state == 0:
  171. result = true
  172. elif action.kind == KEYBOARD and last_event.kind == KEYBOARD:
  173. if action.key notin pressed_keys or action.key_int notin pressed_keys_ints:
  174. if press_state == 0:
  175. result = true
  176. proc `$`*(event: InputEvent): string =
  177. case event.kind
  178. of UNKNOWN:
  179. "Unknown event."
  180. of MOUSE:
  181. var button =
  182. if event.button_index == BUTTON_RIGHT:
  183. "right"
  184. elif event.button_index == BUTTON_LEFT:
  185. "left"
  186. else:
  187. "middle"
  188. "InputEventMouseButton(x: " & $event.x & ", y: " & $event.y & ", pressed:" & $event.pressed & ", button: " & button & ")"
  189. of MOTION:
  190. "InputEventMotionButton(x: " & $event.x & ", y: " & $event.y & ", xrel:" & $event.xrel & ", yrel:" & $event.yrel & ")"
  191. of TOUCH:
  192. "InputEventTouchScreen(x: " & $event.x & ", y: " & $event.y & ")"
  193. of KEYBOARD:
  194. "InputEventKeyboard(key: " & event.key & ", pressed:" & $event.pressed & ")"