input_manager.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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 > InputManager.long_click_min_time:
  83. longpress = True
  84. else:
  85. longpress = False
  86. return InputEvent(InputManager.key, None, None, None,
  87. direction, self.last_key, longpress=longpress)
  88. def mouse_down(self, event):
  89. self.down_pos = event.pos
  90. self.down_button = event.button
  91. self.down_time = time.time()
  92. def mouse_up(self, event):
  93. self.up_pos = event.pos
  94. if abs(self.down_pos[0] -
  95. self.up_pos[0]) < self.max_move_margin:
  96. if abs(self.down_pos[1] -
  97. self.up_pos[1]) < self.max_move_margin:
  98. if time.time() - InputManager.long_click_min_time > \
  99. self.down_time:
  100. return InputEvent(InputManager.long_click,
  101. self.down_pos,
  102. self.up_pos, None, None)
  103. else:
  104. return InputEvent(InputManager.click,
  105. self.down_pos,
  106. self.up_pos, None, None)
  107. elif abs(self.down_pos[1] - self.up_pos[1])\
  108. > self.min_swipe_move:
  109. return InputEvent(InputManager.swipe, self.down_pos,
  110. self.up_pos, True, None)
  111. elif self.down_pos[1] - self.up_pos[1] < self.max_move_margin:
  112. if abs(self.down_pos[0] - self.up_pos[0]) > \
  113. self.min_swipe_move:
  114. return InputEvent(InputManager.swipe, self.down_pos,
  115. self.up_pos, False, None)
  116. class InputEvent:
  117. def __init__(self, event_type, down_pos, current_pos, vertical,
  118. direction, unicode=None, longpress=False):
  119. self.type = event_type
  120. self.down_pos = down_pos
  121. self.current_pos = current_pos
  122. self.unicode = unicode
  123. self.longpress = longpress
  124. if event_type is InputManager.swipe and direction is None:
  125. if vertical:
  126. if self.down_pos[1] < self.current_pos[1]:
  127. self.direction = InputManager.down
  128. else:
  129. self.direction = InputManager.up
  130. else:
  131. if self.down_pos[0] < self.current_pos[0]:
  132. self.direction = InputManager.right
  133. else:
  134. self.direction = InputManager.left
  135. else:
  136. self.direction = direction