|
|
|
@ -6,6 +6,7 @@ import pyray as rl |
|
|
|
|
from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos |
|
|
|
|
from openpilot.system.ui.lib.text_measure import measure_text_cached |
|
|
|
|
from openpilot.system.ui.widgets import Widget |
|
|
|
|
from openpilot.system.ui.widgets.label import TextAlignment, Label |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ButtonStyle(IntEnum): |
|
|
|
@ -20,12 +21,6 @@ class ButtonStyle(IntEnum): |
|
|
|
|
FORGET_WIFI = 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TextAlignment(IntEnum): |
|
|
|
|
LEFT = 0 |
|
|
|
|
CENTER = 1 |
|
|
|
|
RIGHT = 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ICON_PADDING = 15 |
|
|
|
|
DEFAULT_BUTTON_FONT_SIZE = 60 |
|
|
|
|
BUTTON_DISABLED_TEXT_COLOR = rl.Color(228, 228, 228, 51) |
|
|
|
@ -183,25 +178,19 @@ class Button(Widget): |
|
|
|
|
): |
|
|
|
|
|
|
|
|
|
super().__init__() |
|
|
|
|
self._text = text |
|
|
|
|
self._click_callback = click_callback |
|
|
|
|
self._label_font = gui_app.font(FontWeight.SEMI_BOLD) |
|
|
|
|
self._button_style = button_style |
|
|
|
|
self._border_radius = border_radius |
|
|
|
|
self._font_size = font_size |
|
|
|
|
self._font_weight = font_weight |
|
|
|
|
self._text_color = BUTTON_TEXT_COLOR[button_style] |
|
|
|
|
self._background_color = BUTTON_BACKGROUND_COLORS[button_style] |
|
|
|
|
self._text_alignment = text_alignment |
|
|
|
|
self._text_padding = text_padding |
|
|
|
|
self._text_size = measure_text_cached(gui_app.font(self._font_weight), self._text, self._font_size) |
|
|
|
|
self._icon = icon |
|
|
|
|
self._background_color = BUTTON_BACKGROUND_COLORS[self._button_style] |
|
|
|
|
|
|
|
|
|
self._label = Label(text, font_size, font_weight, text_alignment, text_padding, |
|
|
|
|
BUTTON_TEXT_COLOR[self._button_style], icon=icon) |
|
|
|
|
|
|
|
|
|
self._click_callback = click_callback |
|
|
|
|
self._multi_touch = multi_touch |
|
|
|
|
self.enabled = enabled |
|
|
|
|
|
|
|
|
|
def set_text(self, text): |
|
|
|
|
self._text = text |
|
|
|
|
self._text_size = measure_text_cached(gui_app.font(self._font_weight), self._text, self._font_size) |
|
|
|
|
self._label.set_text(text) |
|
|
|
|
|
|
|
|
|
def _handle_mouse_release(self, mouse_pos: MousePos): |
|
|
|
|
if self._click_callback and self.enabled: |
|
|
|
@ -209,44 +198,20 @@ class Button(Widget): |
|
|
|
|
|
|
|
|
|
def _update_state(self): |
|
|
|
|
if self.enabled: |
|
|
|
|
self._text_color = BUTTON_TEXT_COLOR[self._button_style] |
|
|
|
|
self._label.set_text_color(BUTTON_TEXT_COLOR[self._button_style]) |
|
|
|
|
if self.is_pressed: |
|
|
|
|
self._background_color = BUTTON_PRESSED_BACKGROUND_COLORS[self._button_style] |
|
|
|
|
else: |
|
|
|
|
self._background_color = BUTTON_BACKGROUND_COLORS[self._button_style] |
|
|
|
|
elif self._button_style != ButtonStyle.NO_EFFECT: |
|
|
|
|
self._background_color = BUTTON_DISABLED_BACKGROUND_COLOR |
|
|
|
|
self._text_color = BUTTON_DISABLED_TEXT_COLOR |
|
|
|
|
self._label.set_text_color(BUTTON_DISABLED_TEXT_COLOR) |
|
|
|
|
|
|
|
|
|
def _render(self, _): |
|
|
|
|
roundness = self._border_radius / (min(self._rect.width, self._rect.height) / 2) |
|
|
|
|
rl.draw_rectangle_rounded(self._rect, roundness, 10, self._background_color) |
|
|
|
|
self._label.render(self._rect) |
|
|
|
|
|
|
|
|
|
text_pos = rl.Vector2(0, self._rect.y + (self._rect.height - self._text_size.y) // 2) |
|
|
|
|
if self._icon: |
|
|
|
|
icon_y = self._rect.y + (self._rect.height - self._icon.height) / 2 |
|
|
|
|
if self._text: |
|
|
|
|
if self._text_alignment == TextAlignment.LEFT: |
|
|
|
|
icon_x = self._rect.x + self._text_padding |
|
|
|
|
text_pos.x = icon_x + self._icon.width + ICON_PADDING |
|
|
|
|
elif self._text_alignment == TextAlignment.CENTER: |
|
|
|
|
total_width = self._icon.width + ICON_PADDING + self._text_size.x |
|
|
|
|
icon_x = self._rect.x + (self._rect.width - total_width) / 2 |
|
|
|
|
text_pos.x = icon_x + self._icon.width + ICON_PADDING |
|
|
|
|
else: |
|
|
|
|
text_pos.x = self._rect.x + self._rect.width - self._text_size.x - self._text_padding |
|
|
|
|
icon_x = text_pos.x - ICON_PADDING - self._icon.width |
|
|
|
|
else: |
|
|
|
|
icon_x = self._rect.x + (self._rect.width - self._icon.width) / 2 |
|
|
|
|
rl.draw_texture_v(self._icon, rl.Vector2(icon_x, icon_y), rl.WHITE if self.enabled else rl.Color(255, 255, 255, 100)) |
|
|
|
|
else: |
|
|
|
|
if self._text_alignment == TextAlignment.LEFT: |
|
|
|
|
text_pos.x = self._rect.x + self._text_padding |
|
|
|
|
elif self._text_alignment == TextAlignment.CENTER: |
|
|
|
|
text_pos.x = self._rect.x + (self._rect.width - self._text_size.x) // 2 |
|
|
|
|
elif self._text_alignment == TextAlignment.RIGHT: |
|
|
|
|
text_pos.x = self._rect.x + self._rect.width - self._text_size.x - self._text_padding |
|
|
|
|
rl.draw_text_ex(self._label_font, self._text, text_pos, self._font_size, 0, self._text_color) |
|
|
|
|
|
|
|
|
|
class ButtonRadio(Button): |
|
|
|
|
def __init__(self, |
|
|
|
@ -254,11 +219,16 @@ class ButtonRadio(Button): |
|
|
|
|
icon, |
|
|
|
|
click_callback: Callable[[], None] = None, |
|
|
|
|
font_size: int = DEFAULT_BUTTON_FONT_SIZE, |
|
|
|
|
text_alignment: TextAlignment = TextAlignment.LEFT, |
|
|
|
|
border_radius: int = 10, |
|
|
|
|
text_padding: int = 20, |
|
|
|
|
): |
|
|
|
|
|
|
|
|
|
super().__init__(text, click_callback=click_callback, font_size=font_size, border_radius=border_radius, text_padding=text_padding, icon=icon) |
|
|
|
|
super().__init__(text, click_callback=click_callback, font_size=font_size, |
|
|
|
|
border_radius=border_radius, text_padding=text_padding, |
|
|
|
|
text_alignment=text_alignment) |
|
|
|
|
self._text_padding = text_padding |
|
|
|
|
self._icon = icon |
|
|
|
|
self.selected = False |
|
|
|
|
|
|
|
|
|
def _handle_mouse_release(self, mouse_pos: MousePos): |
|
|
|
@ -275,10 +245,7 @@ class ButtonRadio(Button): |
|
|
|
|
def _render(self, _): |
|
|
|
|
roundness = self._border_radius / (min(self._rect.width, self._rect.height) / 2) |
|
|
|
|
rl.draw_rectangle_rounded(self._rect, roundness, 10, self._background_color) |
|
|
|
|
|
|
|
|
|
text_pos = rl.Vector2(0, self._rect.y + (self._rect.height - self._text_size.y) // 2) |
|
|
|
|
text_pos.x = self._rect.x + self._text_padding |
|
|
|
|
rl.draw_text_ex(self._label_font, self._text, text_pos, self._font_size, 0, self._text_color) |
|
|
|
|
self._label.render(self._rect) |
|
|
|
|
|
|
|
|
|
if self._icon and self.selected: |
|
|
|
|
icon_y = self._rect.y + (self._rect.height - self._icon.height) / 2 |
|
|
|
|