input.nim 6.2 KB

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