ui: improve Button widget (#35861)

* bnt

* more

* dup
pull/35864/head
Maxime Desroches 1 week ago committed by GitHub
parent fc58c866c6
commit 1de1640689
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 70
      system/ui/widgets/button.py

@ -26,6 +26,7 @@ class TextAlignment(IntEnum):
ICON_PADDING = 15 ICON_PADDING = 15
DEFAULT_BUTTON_FONT_SIZE = 60 DEFAULT_BUTTON_FONT_SIZE = 60
BUTTON_DISABLED_TEXT_COLOR = rl.Color(228, 228, 228, 51) BUTTON_DISABLED_TEXT_COLOR = rl.Color(228, 228, 228, 51)
BUTTON_DISABLED_BACKGROUND_COLOR = rl.Color(51, 51, 51, 255)
ACTION_BUTTON_FONT_SIZE = 48 ACTION_BUTTON_FONT_SIZE = 48
BUTTON_TEXT_COLOR = { BUTTON_TEXT_COLOR = {
@ -162,6 +163,9 @@ class Button(Widget):
font_weight: FontWeight = FontWeight.MEDIUM, font_weight: FontWeight = FontWeight.MEDIUM,
button_style: ButtonStyle = ButtonStyle.NORMAL, button_style: ButtonStyle = ButtonStyle.NORMAL,
border_radius: int = 10, border_radius: int = 10,
text_alignment: TextAlignment = TextAlignment.CENTER,
text_padding: int = 20,
enabled: bool = True,
): ):
super().__init__() super().__init__()
@ -169,27 +173,77 @@ class Button(Widget):
self._click_callback = click_callback self._click_callback = click_callback
self._label_font = gui_app.font(FontWeight.SEMI_BOLD) self._label_font = gui_app.font(FontWeight.SEMI_BOLD)
self._button_style = button_style self._button_style = button_style
self._font_size = font_size
self._border_radius = border_radius self._border_radius = border_radius
self._font_size = font_size self._font_size = font_size
self._text_color = BUTTON_TEXT_COLOR[button_style] self._text_color = BUTTON_TEXT_COLOR[button_style]
self._background_color = BUTTON_BACKGROUND_COLORS[button_style]
self._text_size = measure_text_cached(gui_app.font(font_weight), text, font_size) self._text_size = measure_text_cached(gui_app.font(font_weight), text, font_size)
self._text_alignment = text_alignment
self._text_padding = text_padding
self.enabled = enabled
def _handle_mouse_release(self, mouse_pos: MousePos): def _handle_mouse_release(self, mouse_pos: MousePos):
if self._click_callback and self.enabled:
self._click_callback()
def _update_state(self):
if self.enabled:
self._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]
else:
self._background_color = BUTTON_DISABLED_BACKGROUND_COLOR
self._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)
text_pos = rl.Vector2(0, self._rect.y + (self._rect.height - self._text_size.y) // 2)
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,
text: str,
icon,
click_callback: Callable[[], None] = None,
font_size: int = DEFAULT_BUTTON_FONT_SIZE,
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)
self._icon = icon
self.selected = False
def _handle_mouse_release(self, mouse_pos: MousePos):
self.selected = not self.selected
if self._click_callback: if self._click_callback:
print(f"Button clicked: {self._text}")
self._click_callback() self._click_callback()
def _get_background_color(self) -> rl.Color: def _update_state(self):
if self._is_pressed: if self.selected:
return BUTTON_PRESSED_BACKGROUND_COLORS[self._button_style] self._background_color = BUTTON_BACKGROUND_COLORS[ButtonStyle.PRIMARY]
else: else:
return BUTTON_BACKGROUND_COLORS[self._button_style] self._background_color = BUTTON_BACKGROUND_COLORS[ButtonStyle.NORMAL]
def _render(self, _): def _render(self, _):
roundness = self._border_radius / (min(self._rect.width, self._rect.height) / 2) roundness = self._border_radius / (min(self._rect.width, self._rect.height) / 2)
rl.draw_rectangle_rounded(self._rect, roundness, 10, self._get_background_color()) 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 = rl.Vector2(0, self._rect.y + (self._rect.height - self._text_size.y) // 2)
text_pos.x = self._rect.x + (self._rect.width - self._text_size.x) // 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) rl.draw_text_ex(self._label_font, self._text, text_pos, self._font_size, 0, self._text_color)
if self._icon and self.selected:
icon_y = self._rect.y + (self._rect.height - self._icon.height) / 2
icon_x = self._rect.x + self._rect.width - self._icon.width - self._text_padding - ICON_PADDING
rl.draw_texture_v(self._icon, rl.Vector2(icon_x, icon_y), rl.WHITE if self.enabled else rl.Color(255, 255, 255, 100))

Loading…
Cancel
Save