pyui: implement styled label and text box (#34813)

implement styled label
pull/34720/merge
Dean Lee 2 months ago committed by GitHub
parent fa79b29cba
commit 2d2efb3f58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      system/ui/lib/application.py
  2. 1
      system/ui/lib/button.py
  3. 48
      system/ui/lib/label.py
  4. 12
      system/ui/reset.py
  5. 2
      system/ui/text.py

@ -15,6 +15,7 @@ DEBUG_FPS = os.getenv("DEBUG_FPS") == '1'
STRICT_MODE = os.getenv("STRICT_MODE") == '1' STRICT_MODE = os.getenv("STRICT_MODE") == '1'
DEFAULT_TEXT_SIZE = 60 DEFAULT_TEXT_SIZE = 60
DEFAULT_TEXT_COLOR = rl.Color(200, 200, 200, 255)
FONT_DIR = os.path.join(BASEDIR, "selfdrive/assets/fonts") 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.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.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.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.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))) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BASE_COLOR_NORMAL, rl.color_to_int(rl.Color(50, 50, 50, 255)))

@ -54,6 +54,7 @@ def gui_button(
if button_style != ButtonStyle.TRANSPARENT: if button_style != ButtonStyle.TRANSPARENT:
rl.draw_rectangle_rounded(rect, roundness, 20, bg_color) rl.draw_rectangle_rounded(rect, roundness, 20, bg_color)
else: else:
rl.draw_rectangle_rounded(rect, roundness, 20, rl.BLACK)
rl.draw_rectangle_rounded_lines_ex(rect, roundness, 20, 2, rl.WHITE) rl.draw_rectangle_rounded_lines_ex(rect, roundness, 20, 2, rl.WHITE)
font = gui_app.font(font_weight) font = gui_app.font(font_weight)

@ -1,11 +1,55 @@
import pyray as rl 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 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 = [ 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_SIZE, font_size),
(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_LINE_SPACING, 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) (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_WRAP_MODE, rl.GuiTextWrapMode.TEXT_WRAP_WORD)
] ]

@ -7,7 +7,7 @@ from enum import IntEnum
from openpilot.system.ui.lib.application import gui_app, FontWeight 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.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" NVME = "/dev/nvme0n1"
USERDATA = "/dev/disk/by-partlabel/userdata" USERDATA = "/dev/disk/by-partlabel/userdata"
@ -51,13 +51,11 @@ class Reset:
threading.Timer(0.1, self.do_reset).start() threading.Timer(0.1, self.do_reset).start()
def render(self, rect: rl.Rectangle): 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, 100)
label_rect = rl.Rectangle(rect.x + 140, rect.y, rect.width - 280, rect.height) gui_label(label_rect, "System Reset", 100, font_weight=FontWeight.BOLD)
gui_label(label_rect, "System Reset", 90)
rl.gui_set_font(gui_app.font(FontWeight.NORMAL))
label_rect.y += 150 text_rect = rl.Rectangle(rect.x + 140, rect.y + 140, rect.width - 280, rect.height - 90 - 100)
gui_label(label_rect, self.get_body_text(), 80) gui_text_box(text_rect, self.get_body_text(), 90)
button_height = 160 button_height = 160
button_spacing = 50 button_spacing = 50

@ -39,7 +39,7 @@ def main():
text_content = sys.argv[1] if len(sys.argv) > 1 else DEMO_TEXT 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) 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) content_rect = rl.Rectangle(0, 0, textarea_rect.width - 20, len(wrapped_lines) * LINE_HEIGHT)
scroll_panel = GuiScrollPanel(show_vertical_scroll_bar=True) scroll_panel = GuiScrollPanel(show_vertical_scroll_bar=True)

Loading…
Cancel
Save