keyboard.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from typing import Any, Callable, List
  2. from typing_extensions import Literal
  3. from ..binding import BindableProperty
  4. from ..element import Element
  5. from ..events import (GenericEventArguments, KeyboardAction, KeyboardKey, KeyboardModifiers, KeyEventArguments,
  6. handle_event)
  7. class Keyboard(Element, component='keyboard.js'):
  8. active = BindableProperty()
  9. def __init__(self,
  10. on_key: Callable[..., Any], *,
  11. active: bool = True,
  12. repeating: bool = True,
  13. ignore: List[Literal['input', 'select', 'button', 'textarea']] = ['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. return handle_event(self.key_handler, arguments)