From 6909aa95ff037183ec5e26f3e73bb6572634810b Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 5 Aug 2026 22:53:04 -0400 Subject: [PATCH] ui: use sunnypilot and sunnylink branding fonts (#1895) * ui: use sunnypilot and sunnylink branding fonts * split --- openpilot/selfdrive/ui/layouts/main.py | 1 + openpilot/selfdrive/ui/mici/layouts/main.py | 1 + .../selfdrive/ui/sunnypilot/layouts/home.py | 68 +++++++++++++++++++ .../ui/sunnypilot/layouts/onboarding.py | 2 +- .../ui/sunnypilot/mici/layouts/home.py | 15 ++++ 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 openpilot/selfdrive/ui/sunnypilot/layouts/home.py create mode 100644 openpilot/selfdrive/ui/sunnypilot/mici/layouts/home.py diff --git a/openpilot/selfdrive/ui/layouts/main.py b/openpilot/selfdrive/ui/layouts/main.py index 2b8bac22c2..69536912ce 100644 --- a/openpilot/selfdrive/ui/layouts/main.py +++ b/openpilot/selfdrive/ui/layouts/main.py @@ -13,6 +13,7 @@ from openpilot.selfdrive.ui.body.layouts.onroad import BodyLayout if gui_app.sunnypilot_ui(): from openpilot.selfdrive.ui.sunnypilot.layouts.settings.settings import SettingsLayoutSP as SettingsLayout + from openpilot.selfdrive.ui.sunnypilot.layouts.home import HomeLayoutSP as HomeLayout class MainState(IntEnum): diff --git a/openpilot/selfdrive/ui/mici/layouts/main.py b/openpilot/selfdrive/ui/mici/layouts/main.py index 6356a2bc9d..0ddd2decd1 100644 --- a/openpilot/selfdrive/ui/mici/layouts/main.py +++ b/openpilot/selfdrive/ui/mici/layouts/main.py @@ -13,6 +13,7 @@ from openpilot.system.ui.lib.application import gui_app if gui_app.sunnypilot_ui(): from openpilot.selfdrive.ui.sunnypilot.mici.layouts.settings import SettingsLayoutSP as SettingsLayout + from openpilot.selfdrive.ui.sunnypilot.mici.layouts.home import MiciHomeLayoutSP as MiciHomeLayout ONROAD_DELAY = 2.5 # seconds diff --git a/openpilot/selfdrive/ui/sunnypilot/layouts/home.py b/openpilot/selfdrive/ui/sunnypilot/layouts/home.py new file mode 100644 index 0000000000..a8c0790d3f --- /dev/null +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/home.py @@ -0,0 +1,68 @@ +""" +Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + +This file is part of sunnypilot and is licensed under the MIT License. +See the LICENSE.md file in the root directory for more details. +""" +import pyray as rl +from openpilot.selfdrive.ui.layouts.home import HomeLayout, HomeLayoutState, HEAD_BUTTON_FONT_SIZE, SPACING +from openpilot.system.ui.lib.application import gui_app, FontWeight +from openpilot.system.ui.lib.text_measure import measure_text_cached +from openpilot.system.ui.lib.multilang import tr, trn +from openpilot.system.ui.widgets.label import gui_label + +BRAND_FONT_SIZE = 48 +BRAND_DESC_SPACING = 12 + + +class HomeLayoutSP(HomeLayout): + def _render_header(self): + font = gui_app.font(FontWeight.MEDIUM) + + version_text_width = self.header_rect.width + + if self.update_available: + version_text_width -= self.update_notif_rect.width + + highlight_color = rl.Color(75, 95, 255, 255) if self.current_state == HomeLayoutState.UPDATE else rl.Color(54, 77, 239, 255) + rl.draw_rectangle_rounded(self.update_notif_rect, 0.3, 10, highlight_color) + + text = tr("UPDATE") + text_size = measure_text_cached(font, text, HEAD_BUTTON_FONT_SIZE) + text_x = self.update_notif_rect.x + (self.update_notif_rect.width - text_size.x) // 2 + text_y = self.update_notif_rect.y + (self.update_notif_rect.height - text_size.y) // 2 + rl.draw_text_ex(font, text, rl.Vector2(int(text_x), int(text_y)), HEAD_BUTTON_FONT_SIZE, 0, rl.WHITE) + + if self.alert_count > 0: + version_text_width -= self.alert_notif_rect.width + + highlight_color = rl.Color(255, 70, 70, 255) if self.current_state == HomeLayoutState.ALERTS else rl.Color(226, 44, 44, 255) + rl.draw_rectangle_rounded(self.alert_notif_rect, 0.3, 10, highlight_color) + + alert_text = trn("{} ALERT", "{} ALERTS", self.alert_count).format(self.alert_count) + text_size = measure_text_cached(font, alert_text, HEAD_BUTTON_FONT_SIZE) + text_x = self.alert_notif_rect.x + (self.alert_notif_rect.width - text_size.x) // 2 + text_y = self.alert_notif_rect.y + (self.alert_notif_rect.height - text_size.y) // 2 + rl.draw_text_ex(font, alert_text, rl.Vector2(int(text_x), int(text_y)), HEAD_BUTTON_FONT_SIZE, 0, rl.WHITE) + + if self.update_available or self.alert_count > 0: + version_text_width -= SPACING * 1.5 + + version_right = self.header_rect.x + self.header_rect.width + version_left = version_right - version_text_width + + brand = "sunnypilot" + description = self.params.get("UpdaterCurrentDescription") or "" + + desc_width = 0 + if description: + desc_size = measure_text_cached(gui_app.font(FontWeight.NORMAL), description, BRAND_FONT_SIZE) + desc_width = desc_size.x + desc_rect = rl.Rectangle(version_right - desc_width, self.header_rect.y, desc_width, self.header_rect.height) + gui_label(desc_rect, description, BRAND_FONT_SIZE, rl.WHITE, alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT) + + brand_size = measure_text_cached(gui_app.font(FontWeight.AUDIOWIDE), brand, BRAND_FONT_SIZE) + spacing = BRAND_DESC_SPACING if description else 0 + brand_x = version_right - desc_width - spacing - brand_size.x + brand_rect = rl.Rectangle(max(version_left, brand_x), self.header_rect.y, brand_size.x, self.header_rect.height) + gui_label(brand_rect, brand, BRAND_FONT_SIZE, rl.WHITE, font_weight=FontWeight.AUDIOWIDE) diff --git a/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py b/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py index a86677a7b1..ee4b479afe 100644 --- a/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py @@ -20,7 +20,7 @@ class SunnylinkConsentPage(Widget): self._done_callback = done_callback self._step = 0 - self._title = self._child(Label(tr("sunnylink"), font_size=90, font_weight=FontWeight.BOLD, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT)) + self._title = self._child(Label(tr("sunnylink"), font_size=90, font_weight=FontWeight.AUDIOWIDE, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT)) self._content = [ { diff --git a/openpilot/selfdrive/ui/sunnypilot/mici/layouts/home.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/home.py new file mode 100644 index 0000000000..d29e579c52 --- /dev/null +++ b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/home.py @@ -0,0 +1,15 @@ +""" +Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + +This file is part of sunnypilot and is licensed under the MIT License. +See the LICENSE.md file in the root directory for more details. +""" +from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout +from openpilot.system.ui.lib.application import FontWeight +from openpilot.system.ui.widgets.label import UnifiedLabel + + +class MiciHomeLayoutSP(MiciHomeLayout): + def __init__(self): + super().__init__() + self._openpilot_label = UnifiedLabel("sunnypilot", font_size=88, font_weight=FontWeight.AUDIOWIDE, max_width=480, wrap_text=False)