* emoji

* label

* back

* default

* type

* more

* ico

* device

* clean

* brew
This commit is contained in:
Maxime Desroches
2025-08-06 16:04:19 -07:00
committed by GitHub
parent 52a4b52628
commit 3a78eee2f9
4 changed files with 148 additions and 52 deletions
+18 -51
View File
@@ -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