mouse_handlers.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from __future__ import annotations
  2. from collections import defaultdict
  3. from typing import TYPE_CHECKING, Callable
  4. from prompt_toolkit.mouse_events import MouseEvent
  5. if TYPE_CHECKING:
  6. from prompt_toolkit.key_binding.key_bindings import NotImplementedOrNone
  7. __all__ = [
  8. "MouseHandler",
  9. "MouseHandlers",
  10. ]
  11. MouseHandler = Callable[[MouseEvent], "NotImplementedOrNone"]
  12. class MouseHandlers:
  13. """
  14. Two dimensional raster of callbacks for mouse events.
  15. """
  16. def __init__(self) -> None:
  17. def dummy_callback(mouse_event: MouseEvent) -> NotImplementedOrNone:
  18. """
  19. :param mouse_event: `MouseEvent` instance.
  20. """
  21. return NotImplemented
  22. # NOTE: Previously, the data structure was a dictionary mapping (x,y)
  23. # to the handlers. This however would be more inefficient when copying
  24. # over the mouse handlers of the visible region in the scrollable pane.
  25. # Map y (row) to x (column) to handlers.
  26. self.mouse_handlers: defaultdict[
  27. int, defaultdict[int, MouseHandler]
  28. ] = defaultdict(lambda: defaultdict(lambda: dummy_callback))
  29. def set_mouse_handler_for_range(
  30. self,
  31. x_min: int,
  32. x_max: int,
  33. y_min: int,
  34. y_max: int,
  35. handler: Callable[[MouseEvent], NotImplementedOrNone],
  36. ) -> None:
  37. """
  38. Set mouse handler for a region.
  39. """
  40. for y in range(y_min, y_max):
  41. row = self.mouse_handlers[y]
  42. for x in range(x_min, x_max):
  43. row[x] = handler