input_manager.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 len(event.unicode) > 0 and event.key not in \
  60. InputManager.special_keys:
  61. return InputEvent(InputManager.key, None, None, None,
  62. None, event.unicode)
  63. else:
  64. self.last_key = event.key
  65. self.down_time = time.time()
  66. return None
  67. def key_up(self, event):
  68. if self.last_key == event.key:
  69. if self.last_key == pygame.K_DOWN:
  70. direction = InputManager.down
  71. elif self.last_key == pygame.K_UP:
  72. direction = InputManager.up
  73. elif self.last_key == pygame.K_LEFT:
  74. direction = InputManager.left
  75. elif self.last_key == pygame.K_RIGHT:
  76. direction = InputManager.right
  77. elif self.last_key == pygame.K_RETURN:
  78. direction = InputManager.enter
  79. else:
  80. return None
  81. if direction is not None:
  82. if time.time() - self.down_time > \
  83. InputManager.long_click_min_time:
  84. longpress = True
  85. else:
  86. longpress = False
  87. return InputEvent(InputManager.key, None, None, None,
  88. direction, self.last_key,
  89. longpress=longpress)
  90. def mouse_down(self, event):
  91. self.down_pos = event.pos
  92. self.down_button = event.button
  93. self.down_time = time.time()
  94. def mouse_up(self, event):
  95. self.up_pos = event.pos
  96. if abs(self.down_pos[0] -
  97. self.up_pos[0]) < self.max_move_margin:
  98. if abs(self.down_pos[1] -
  99. self.up_pos[1]) < self.max_move_margin:
  100. if time.time() - InputManager.long_click_min_time > \
  101. self.down_time:
  102. return InputEvent(InputManager.long_click,
  103. self.down_pos,
  104. self.up_pos, None, None)
  105. else:
  106. return InputEvent(InputManager.click,
  107. self.down_pos,
  108. self.up_pos, None, None)
  109. elif abs(self.down_pos[1] - self.up_pos[1])\
  110. > self.min_swipe_move:
  111. return InputEvent(InputManager.swipe, self.down_pos,
  112. self.up_pos, True, None)
  113. elif self.down_pos[1] - self.up_pos[1] < self.max_move_margin:
  114. if abs(self.down_pos[0] - self.up_pos[0]) > \
  115. self.min_swipe_move:
  116. return InputEvent(InputManager.swipe, self.down_pos,
  117. self.up_pos, False, None)
  118. class InputEvent:
  119. def __init__(self, event_type, down_pos, current_pos, vertical,
  120. direction, unicode=None, longpress=False):
  121. self.type = event_type
  122. self.down_pos = down_pos
  123. self.current_pos = current_pos
  124. self.unicode = unicode
  125. self.longpress = longpress
  126. if event_type is InputManager.swipe and direction is None:
  127. if vertical:
  128. if self.down_pos[1] < self.current_pos[1]:
  129. self.direction = InputManager.down
  130. else:
  131. self.direction = InputManager.up
  132. else:
  133. if self.down_pos[0] < self.current_pos[0]:
  134. self.direction = InputManager.right
  135. else:
  136. self.direction = InputManager.left
  137. else:
  138. self.direction = direction