diff --git a/system/ui/lib/application.py b/system/ui/lib/application.py index 22c6ed71f2..c7b7a36e5d 100644 --- a/system/ui/lib/application.py +++ b/system/ui/lib/application.py @@ -15,6 +15,7 @@ DEBUG_FPS = os.getenv("DEBUG_FPS") == '1' STRICT_MODE = os.getenv("STRICT_MODE") == '1' DEFAULT_TEXT_SIZE = 60 +DEFAULT_TEXT_COLOR = rl.Color(200, 200, 200, 255) FONT_DIR = os.path.join(BASEDIR, "selfdrive/assets/fonts") @@ -118,7 +119,7 @@ class GuiApplication: rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BORDER_WIDTH, 0) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_SIZE, DEFAULT_TEXT_SIZE) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.BLACK)) - rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_COLOR_NORMAL, rl.color_to_int(rl.Color(200, 200, 200, 255))) + rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_COLOR_NORMAL, rl.color_to_int(DEFAULT_TEXT_COLOR)) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.Color(30, 30, 30, 255))) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BASE_COLOR_NORMAL, rl.color_to_int(rl.Color(50, 50, 50, 255))) diff --git a/system/ui/lib/button.py b/system/ui/lib/button.py index 9bcf3f7e01..034189275f 100644 --- a/system/ui/lib/button.py +++ b/system/ui/lib/button.py @@ -54,6 +54,7 @@ def gui_button( if button_style != ButtonStyle.TRANSPARENT: rl.draw_rectangle_rounded(rect, roundness, 20, bg_color) else: + rl.draw_rectangle_rounded(rect, roundness, 20, rl.BLACK) rl.draw_rectangle_rounded_lines_ex(rect, roundness, 20, 2, rl.WHITE) font = gui_app.font(font_weight) diff --git a/system/ui/lib/label.py b/system/ui/lib/label.py index 37b66582f9..ccfd89a2ec 100644 --- a/system/ui/lib/label.py +++ b/system/ui/lib/label.py @@ -1,11 +1,55 @@ import pyray as rl +from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_TEXT_SIZE, DEFAULT_TEXT_COLOR from openpilot.system.ui.lib.utils import GuiStyleContext -def gui_label(rect, text, font_size): + +def gui_label( + rect: rl.Rectangle, + text: str, + font_size: int = DEFAULT_TEXT_SIZE, + color: rl.Color = DEFAULT_TEXT_COLOR, + font_weight: FontWeight = FontWeight.NORMAL, + alignment: int = rl.GuiTextAlignment.TEXT_ALIGN_LEFT, + alignment_vertical: int = rl.GuiTextAlignmentVertical.TEXT_ALIGN_MIDDLE +): + # Set font based on the provided weight + font = gui_app.font(font_weight) + + # Measure text size + text_size = rl.measure_text_ex(font, text, font_size, 0) + + # Calculate horizontal position based on alignment + text_x = rect.x + { + rl.GuiTextAlignment.TEXT_ALIGN_LEFT: 0, + rl.GuiTextAlignment.TEXT_ALIGN_CENTER: (rect.width - text_size.x) / 2, + rl.GuiTextAlignment.TEXT_ALIGN_RIGHT: rect.width - text_size.x, + }.get(alignment, 0) + + # Calculate vertical position based on alignment + text_y = rect.y + { + rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP: 0, + rl.GuiTextAlignmentVertical.TEXT_ALIGN_MIDDLE: (rect.height - text_size.y) / 2, + rl.GuiTextAlignmentVertical.TEXT_ALIGN_BOTTOM: rect.height - text_size.y, + }.get(alignment_vertical, 0) + + # Draw the text in the specified rectangle + rl.draw_text_ex(font, text, rl.Vector2(text_x, text_y), font_size, 0, color) + + +def gui_text_box( + rect: rl.Rectangle, + text: str, + font_size: int = DEFAULT_TEXT_SIZE, + color: rl.Color = DEFAULT_TEXT_COLOR, + alignment: int = rl.GuiTextAlignment.TEXT_ALIGN_LEFT, + alignment_vertical: int = rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP +): styles = [ + (rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_COLOR_NORMAL, rl.color_to_int(color)), (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_SIZE, font_size), (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_LINE_SPACING, font_size), - (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_ALIGNMENT_VERTICAL, rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP), + (rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_ALIGNMENT, alignment), + (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_ALIGNMENT_VERTICAL, alignment_vertical), (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_WRAP_MODE, rl.GuiTextWrapMode.TEXT_WRAP_WORD) ] diff --git a/system/ui/reset.py b/system/ui/reset.py index a5a8a84b04..80a1c10ea8 100755 --- a/system/ui/reset.py +++ b/system/ui/reset.py @@ -7,7 +7,7 @@ from enum import IntEnum from openpilot.system.ui.lib.application import gui_app, FontWeight from openpilot.system.ui.lib.button import gui_button, ButtonStyle -from openpilot.system.ui.lib.label import gui_label +from openpilot.system.ui.lib.label import gui_label, gui_text_box NVME = "/dev/nvme0n1" USERDATA = "/dev/disk/by-partlabel/userdata" @@ -51,13 +51,11 @@ class Reset: threading.Timer(0.1, self.do_reset).start() def render(self, rect: rl.Rectangle): - rl.gui_set_font(gui_app.font(FontWeight.BOLD)) - label_rect = rl.Rectangle(rect.x + 140, rect.y, rect.width - 280, rect.height) - gui_label(label_rect, "System Reset", 90) - rl.gui_set_font(gui_app.font(FontWeight.NORMAL)) + label_rect = rl.Rectangle(rect.x + 140, rect.y, rect.width - 280, 100) + gui_label(label_rect, "System Reset", 100, font_weight=FontWeight.BOLD) - label_rect.y += 150 - gui_label(label_rect, self.get_body_text(), 80) + text_rect = rl.Rectangle(rect.x + 140, rect.y + 140, rect.width - 280, rect.height - 90 - 100) + gui_text_box(text_rect, self.get_body_text(), 90) button_height = 160 button_spacing = 50 diff --git a/system/ui/text.py b/system/ui/text.py index 77a0d267e4..33299605d6 100755 --- a/system/ui/text.py +++ b/system/ui/text.py @@ -39,7 +39,7 @@ def main(): text_content = sys.argv[1] if len(sys.argv) > 1 else DEMO_TEXT - textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2 - BUTTON_SIZE.y - SPACING) + textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2) wrapped_lines = wrap_text(text_content, FONT_SIZE, textarea_rect.width - 20) content_rect = rl.Rectangle(0, 0, textarea_rect.width - 20, len(wrapped_lines) * LINE_HEIGHT) scroll_panel = GuiScrollPanel(show_vertical_scroll_bar=True)