diff --git a/system/ui/widgets/list_view.py b/system/ui/widgets/list_view.py index 056aa2d90b..509c49be35 100644 --- a/system/ui/widgets/list_view.py +++ b/system/ui/widgets/list_view.py @@ -7,6 +7,7 @@ from openpilot.system.ui.lib.text_measure import measure_text_cached from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.button import Button, ButtonStyle from openpilot.system.ui.widgets.toggle import Toggle, WIDTH as TOGGLE_WIDTH, HEIGHT as TOGGLE_HEIGHT +from openpilot.system.ui.widgets.label import gui_label from openpilot.system.ui.widgets.html_render import HtmlRenderer, ElementType ITEM_BASE_WIDTH = 600 @@ -42,6 +43,10 @@ class ItemAction(Widget, ABC): self.set_rect(rl.Rectangle(0, 0, width, 0)) self._enabled_source = enabled + def get_width_hint(self) -> float: + # Return's action ideal width, 0 means use full width + return self._rect.width + def set_enabled(self, enabled: bool | Callable[[], bool]): self._enabled_source = enabled @@ -147,17 +152,14 @@ class TextAction(ItemAction): def text(self): return _resolve_value(self._text_source, "Error") - def _update_state(self): + def get_width_hint(self) -> float: text_width = measure_text_cached(self._font, self.text, ITEM_TEXT_FONT_SIZE).x - self._rect.width = int(text_width + TEXT_PADDING) + return text_width + TEXT_PADDING def _render(self, rect: rl.Rectangle) -> bool: - current_text = self.text - text_size = measure_text_cached(self._font, current_text, ITEM_TEXT_FONT_SIZE) - - text_x = rect.x + (rect.width - text_size.x) / 2 - text_y = rect.y + (rect.height - text_size.y) / 2 - rl.draw_text_ex(self._font, current_text, rl.Vector2(text_x, text_y), ITEM_TEXT_FONT_SIZE, 0, self.color) + gui_label(self._rect, self.text, font_size=ITEM_TEXT_FONT_SIZE, color=self.color, + font_weight=FontWeight.NORMAL, alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT, + alignment_vertical=rl.GuiTextAlignmentVertical.TEXT_ALIGN_MIDDLE) return False def set_text(self, text: str | Callable[[], str]): @@ -374,11 +376,16 @@ class ListItem(Widget): if not self.action_item: return rl.Rectangle(0, 0, 0, 0) - right_width = self.action_item.rect.width + right_width = self.action_item.get_width_hint() if right_width == 0: # Full width action (like DualButtonAction) return rl.Rectangle(item_rect.x + ITEM_PADDING, item_rect.y, item_rect.width - (ITEM_PADDING * 2), ITEM_BASE_HEIGHT) + # Clip width to available space, never overlapping this Item's title + content_width = item_rect.width - (ITEM_PADDING * 2) + title_width = measure_text_cached(self._font, self.title, ITEM_TEXT_FONT_SIZE).x + right_width = min(content_width - title_width, right_width) + right_x = item_rect.x + item_rect.width - right_width right_y = item_rect.y return rl.Rectangle(right_x, right_y, right_width, ITEM_BASE_HEIGHT)