input_manager.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import logging
  2. import time
  3. import pygame
  4. logger = logging.getLogger(__name__)
  5. class InputManager():
  6. click = 1
  7. swipe = 2
  8. long_click = 3
  9. key = 4
  10. long_click_min_time = 0.3
  11. up = 0
  12. down = 1
  13. left = 2
  14. right = 3
  15. enter = 4
  16. special_keys = [pygame.K_DOWN, pygame.K_UP, pygame.K_LEFT,
  17. pygame.K_RIGHT, pygame.K_RETURN]
  18. def __init__(self, size):
  19. self.down_pos = (0, 0)
  20. self.up_pos = (0, 0)
  21. self.screen_size = size
  22. self.max_move_margin = self.screen_size[1] / 6
  23. self.min_swipe_move = self.screen_size[1] / 3
  24. self.down_button = -1
  25. self.down_time = -1
  26. self.last_key = -1
  27. def event(self, event):
  28. if event.type == pygame.MOUSEBUTTONUP:
  29. if event.button == 4:
  30. touch_event = InputEvent(InputManager.swipe,
  31. self.down_pos,
  32. self.up_pos, True,
  33. InputManager.up, None)
  34. return touch_event
  35. elif event.button == 5:
  36. touch_event = InputEvent(InputManager.swipe,
  37. self.down_pos,
  38. self.up_pos, True,
  39. InputManager.down, None)
  40. return touch_event
  41. elif event.button == 1 and self.down_button == 1:
  42. touch_event = self.mouse_up(event)
  43. return touch_event
  44. elif event.button == 3 and self.down_button == 3:
  45. touch_event = InputEvent(InputManager.long_click,
  46. self.down_pos, self.up_pos,
  47. None, None, None)
  48. return touch_event
  49. else:
  50. return None
  51. elif event.type == pygame.MOUSEBUTTONDOWN:
  52. self.mouse_down(event)
  53. return None
  54. elif event.type == pygame.KEYDOWN:
  55. return self.key_down(event)
  56. elif event.type == pygame.KEYUP:
  57. return self.key_up(event)
  58. def key_down(self, event):
  59. if event.unicode is not None\
  60. and len(event.unicode) > 0 and event.key not in \
  61. InputManager.special_keys:
  62. return InputEvent(InputManager.key, None, None, None,
  63. None, event.unicode)
  64. else:
  65. self.last_key = event.key
  66. self.down_time = time.time()
  67. return None
  68. def key_up(self, event):
  69. if self.last_key == event.key:
  70. if self.last_key == pygame.K_DOWN:
  71. direction = InputManager.down
  72. elif self.last_key == pygame.K_UP:
  73. direction = InputManager.up
  74. elif self.last_key == pygame.K_LEFT:
  75. direction = InputManager.left
  76. elif self.last_key == pygame.K_RIGHT:
  77. direction = InputManager.right
  78. elif self.last_key == pygame.K_RETURN:
  79. direction = InputManager.enter
  80. else:
  81. return None
  82. if direction is not None:
  83. if time.time() - self.down_time > \
  84. InputManager.long_click_min_time:
  85. longpress = True
  86. else:
  87. longpress = False
  88. return InputEvent(InputManager.key, None, None, None,
  89. direction, self.last_key,
  90. longpress=longpress)
  91. def mouse_down(self, event):
  92. self.down_pos = event.pos
  93. self.down_button = event.button
  94. self.down_time = time.time()
  95. def mouse_up(self, event):
  96. self.up_pos = event.pos
  97. if abs(self.down_pos[0] -
  98. self.up_pos[0]) < self.max_move_margin:
  99. if abs(self.down_pos[1] -
  100. self.up_pos[1]) < self.max_move_margin:
  101. if time.time() - InputManager.long_click_min_time > \
  102. self.down_time:
  103. return InputEvent(InputManager.long_click,
  104. self.down_pos,
  105. self.up_pos, None, None)
  106. else:
  107. return InputEvent(InputManager.click,
  108. self.down_pos,
  109. self.up_pos, None, None)
  110. elif abs(self.down_pos[1] - self.up_pos[1])\
  111. > self.min_swipe_move:
  112. return InputEvent(InputManager.swipe, self.down_pos,
  113. self.up_pos, True, None)
  114. elif self.down_pos[1] - self.up_pos[1] < self.max_move_margin:
  115. if abs(self.down_pos[0] - self.up_pos[0]) > \
  116. self.min_swipe_move:
  117. return InputEvent(InputManager.swipe, self.down_pos,
  118. self.up_pos, False, None)
  119. class InputEvent:
  120. def __init__(self, event_type, down_pos, current_pos, vertical,
  121. direction, unicode=None, longpress=False):
  122. self.type = event_type
  123. self.down_pos = down_pos
  124. self.current_pos = current_pos
  125. self.unicode = unicode
  126. self.longpress = longpress
  127. if event_type is InputManager.swipe and direction is None:
  128. if vertical:
  129. if self.down_pos[1] < self.current_pos[1]:
  130. self.direction = InputManager.down
  131. else:
  132. self.direction = InputManager.up
  133. else:
  134. if self.down_pos[0] < self.current_pos[0]:
  135. self.direction = InputManager.right
  136. else:
  137. self.direction = InputManager.left
  138. else:
  139. self.direction = direction