keyboard.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. from typing import Any, Callable, List, Literal
  2. from ..binding import BindableProperty
  3. from ..element import Element
  4. from ..events import (GenericEventArguments, KeyboardAction, KeyboardKey, KeyboardModifiers, KeyEventArguments,
  5. handle_event)
  6. class Keyboard(Element, component='keyboard.js'):
  7. active = BindableProperty()
  8. def __init__(self,
  9. on_key: Callable[..., Any], *,
  10. active: bool = True,
  11. repeating: bool = True,
  12. ignore: List[Literal['input', 'select', 'button', 'textarea']] = [
  13. 'input', 'select', 'button', 'textarea'],
  14. ) -> None:
  15. """Keyboard
  16. Adds global keyboard event tracking.
  17. :param on_key: callback to be executed when keyboard events occur.
  18. :param active: boolean flag indicating whether the callback should be executed or not (default: `True`)
  19. :param repeating: boolean flag indicating whether held keys should be sent repeatedly (default: `True`)
  20. :param ignore: ignore keys when one of these element types is focussed (default: `['input', 'select', 'button', 'textarea']`)
  21. """
  22. super().__init__()
  23. self.key_handler = on_key
  24. self.active = active
  25. self._props['events'] = ['keydown', 'keyup']
  26. self._props['repeating'] = repeating
  27. self._props['ignore'] = ignore
  28. self.on('key', self.handle_key)
  29. def handle_key(self, e: GenericEventArguments) -> None:
  30. if not self.active:
  31. return
  32. action = KeyboardAction(
  33. keydown=e.args['action'] == 'keydown',
  34. keyup=e.args['action'] == 'keyup',
  35. repeat=e.args['repeat'],
  36. )
  37. modifiers = KeyboardModifiers(
  38. alt=e.args['altKey'],
  39. ctrl=e.args['ctrlKey'],
  40. meta=e.args['metaKey'],
  41. shift=e.args['shiftKey'],
  42. )
  43. key = KeyboardKey(
  44. name=e.args['key'],
  45. code=e.args['code'],
  46. location=e.args['location'],
  47. )
  48. arguments = KeyEventArguments(
  49. sender=self,
  50. client=self.client,
  51. action=action,
  52. modifiers=modifiers,
  53. key=key,
  54. )
  55. handle_event(self.key_handler, arguments)