Files
sunnypilot/system/ui/lib/widget.py
Shane Smiskol cd657f35f0 ui: update layout rects on change (#35545)
* update_layout_rects

* check prev

* about it

* need this since touch can change :(

* looks nicer

* Revert "looks nicer"

This reverts commit 8f36c92675db66695f22f93a01682426db9c05e8.
2025-06-12 16:53:09 -07:00

65 lines
1.9 KiB
Python

import abc
import pyray as rl
from enum import IntEnum
from collections.abc import Callable
class DialogResult(IntEnum):
CANCEL = 0
CONFIRM = 1
NO_ACTION = -1
class Widget(abc.ABC):
def __init__(self):
self._rect: rl.Rectangle = rl.Rectangle(0, 0, 0, 0)
self._is_pressed = False
self._is_visible: bool | Callable[[], bool] = True
@property
def is_visible(self) -> bool:
return self._is_visible() if callable(self._is_visible) else self._is_visible
def set_visible(self, visible: bool | Callable[[], bool]) -> None:
self._is_visible = visible
def set_rect(self, rect: rl.Rectangle) -> None:
prev_rect = self._rect
self._rect = rect
if (rect.x != prev_rect.x or rect.y != prev_rect.y or
rect.width != prev_rect.width or rect.height != prev_rect.height):
self._update_layout_rects()
def render(self, rect: rl.Rectangle = None) -> bool | int | None:
if rect is not None:
self.set_rect(rect)
if not self.is_visible:
return None
ret = self._render(self._rect)
# Keep track of whether mouse down started within the widget's rectangle
mouse_pos = rl.get_mouse_position()
if rl.is_mouse_button_pressed(rl.MouseButton.MOUSE_BUTTON_LEFT):
if rl.check_collision_point_rec(mouse_pos, self._rect):
self._is_pressed = True
if rl.is_mouse_button_released(rl.MouseButton.MOUSE_BUTTON_LEFT):
if self._is_pressed and rl.check_collision_point_rec(mouse_pos, self._rect):
self._handle_mouse_release(mouse_pos)
self._is_pressed = False
return ret
@abc.abstractmethod
def _render(self, rect: rl.Rectangle) -> bool | int | None:
"""Render the widget within the given rectangle."""
def _update_layout_rects(self) -> None:
"""Optionally update any layout rects on Widget rect change."""
def _handle_mouse_release(self, mouse_pos: rl.Vector2) -> bool:
"""Optionally handle mouse release events."""
return False