visibility.py 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from typing import TYPE_CHECKING, Any, Callable
  2. from typing_extensions import Self
  3. from ...binding import BindableProperty, bind, bind_from, bind_to
  4. if TYPE_CHECKING:
  5. from ...element import Element
  6. class Visibility:
  7. visible = BindableProperty(on_change=lambda sender, visible: sender.on_visibility_change(visible))
  8. def __init__(self, **kwargs: Any) -> None:
  9. super().__init__(**kwargs)
  10. self.visible = True
  11. def bind_visibility_to(self,
  12. target_object: Any,
  13. target_name: str = 'visible',
  14. forward: Callable[..., Any] = lambda x: x,
  15. ) -> Self:
  16. """Bind the visibility of this element to the target object's target_name property.
  17. The binding works one way only, from this element to the target.
  18. :param target_object: The object to bind to.
  19. :param target_name: The name of the property to bind to.
  20. :param forward: A function to apply to the value before applying it to the target.
  21. """
  22. bind_to(self, 'visible', target_object, target_name, forward)
  23. return self
  24. def bind_visibility_from(self,
  25. target_object: Any,
  26. target_name: str = 'visible',
  27. backward: Callable[..., Any] = lambda x: x, *,
  28. value: Any = None) -> Self:
  29. """Bind the visibility of this element from the target object's target_name property.
  30. The binding works one way only, from the target to this element.
  31. :param target_object: The object to bind from.
  32. :param target_name: The name of the property to bind from.
  33. :param backward: A function to apply to the value before applying it to this element.
  34. :param value: If specified, the element will be visible only when the target value is equal to this value.
  35. """
  36. if value is not None:
  37. def backward(x): return x == value
  38. bind_from(self, 'visible', target_object, target_name, backward)
  39. return self
  40. def bind_visibility(self,
  41. target_object: Any,
  42. target_name: str = 'visible', *,
  43. forward: Callable[..., Any] = lambda x: x,
  44. backward: Callable[..., Any] = lambda x: x,
  45. value: Any = None,
  46. ) -> Self:
  47. """Bind the visibility of this element to the target object's target_name property.
  48. The binding works both ways, from this element to the target and from the target to this element.
  49. :param target_object: The object to bind to.
  50. :param target_name: The name of the property to bind to.
  51. :param forward: A function to apply to the value before applying it to the target.
  52. :param backward: A function to apply to the value before applying it to this element.
  53. :param value: If specified, the element will be visible only when the target value is equal to this value.
  54. """
  55. if value is not None:
  56. def backward(x): return x == value
  57. bind(self, 'visible', target_object, target_name, forward=forward, backward=backward)
  58. return self
  59. def set_visibility(self, visible: bool) -> None:
  60. """Set the visibility of this element.
  61. :param visible: Whether the element should be visible.
  62. """
  63. self.visible = visible
  64. def on_visibility_change(self: 'Element', visible: str) -> None:
  65. """Called when the visibility of this element changes.
  66. :param visible: Whether the element should be visible.
  67. """
  68. if visible and 'hidden' in self._classes:
  69. self._classes.remove('hidden')
  70. self.update()
  71. if not visible and 'hidden' not in self._classes:
  72. self._classes.append('hidden')
  73. self.update()