/kivy/input/providers/androidjoystick.py

https://github.com/geojeff/kivy · Python · 100 lines · 78 code · 16 blank · 6 comment · 15 complexity · b2d015b78fefe5adde41a190e6ddebd1 MD5 · raw file

  1. # pylint: disable=W0611
  2. __all__ = ('AndroidMotionEventProvider', )
  3. import os
  4. try:
  5. import android
  6. except ImportError:
  7. if 'KIVY_DOC' not in os.environ:
  8. raise Exception('android lib not found.')
  9. from kivy.logger import Logger
  10. from kivy.input.provider import MotionEventProvider
  11. from kivy.input.factory import MotionEventFactory
  12. from kivy.input.shape import ShapeRect
  13. from kivy.input.motionevent import MotionEvent
  14. import pygame.joystick
  15. class AndroidMotionEvent(MotionEvent):
  16. def depack(self, args):
  17. self.is_touch = True
  18. self.profile = ['pos', 'pressure', 'shape']
  19. self.sx, self.sy, self.pressure, radius = args
  20. self.shape = ShapeRect()
  21. self.shape.width = radius
  22. self.shape.height = radius
  23. super(AndroidMotionEvent, self).depack(args)
  24. class AndroidMotionEventProvider(MotionEventProvider):
  25. def __init__(self, device, args):
  26. super(AndroidMotionEventProvider, self).__init__(device, args)
  27. self.joysticks = []
  28. self.touches = {}
  29. self.uid = 0
  30. self.window = None
  31. def create_joystick(self, index):
  32. Logger.info('Android: create joystick <%d>' % index)
  33. js = pygame.joystick.Joystick(index)
  34. js.init()
  35. if js.get_numbuttons() == 0:
  36. Logger.info('Android: discard joystick <%d> cause no button' %
  37. index)
  38. return
  39. self.joysticks.append(js)
  40. def start(self):
  41. pygame.joystick.init()
  42. Logger.info('Android: found %d joystick' % pygame.joystick.get_count())
  43. for i in range(pygame.joystick.get_count()):
  44. self.create_joystick(i)
  45. def stop(self):
  46. self.joysticks = []
  47. def update(self, dispatch_fn):
  48. if not self.window:
  49. from kivy.core.window import Window
  50. self.window = Window
  51. w, h = self.window.system_size
  52. touches = self.touches
  53. for joy in self.joysticks:
  54. jid = joy.get_id()
  55. pressed = joy.get_button(0)
  56. x = joy.get_axis(0) * 32768. / w
  57. y = 1. - (joy.get_axis(1) * 32768. / h)
  58. # python for android do * 1000.
  59. pressure = joy.get_axis(2) / 1000.
  60. radius = joy.get_axis(3) / 1000.
  61. # new touche ?
  62. if pressed and jid not in touches:
  63. self.uid += 1
  64. touch = AndroidMotionEvent(self.device, self.uid,
  65. [x, y, pressure, radius])
  66. touches[jid] = touch
  67. dispatch_fn('begin', touch)
  68. # update touch
  69. elif pressed:
  70. touch = touches[jid]
  71. # avoid same touch position
  72. if touch.sx == x and touch.sy == y \
  73. and touch.pressure == pressure:
  74. continue
  75. touch.move([x, y, pressure, radius])
  76. dispatch_fn('update', touch)
  77. # disapear
  78. elif not pressed and jid in touches:
  79. touch = touches[jid]
  80. touch.move([x, y, pressure, radius])
  81. touch.update_time_end()
  82. dispatch_fn('end', touch)
  83. touches.pop(jid)
  84. MotionEventFactory.register('android', AndroidMotionEventProvider)