raylib: fix when we show offroad alerts and styles (#36240)

* fix how we show alerts

* test this too

* match border radius

* simplifty

* keep

* back

* fix alert spacing

* fix alert text padding

* cmt

* cmt
pull/36243/head
Shane Smiskol 1 day ago committed by GitHub
parent 21fd3d0320
commit 75e52427d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 21
      selfdrive/ui/layouts/home.py
  2. 1
      selfdrive/ui/tests/test_ui/raylib_screenshots.py
  3. 33
      selfdrive/ui/widgets/offroad_alerts.py

@ -41,6 +41,8 @@ class HomeLayout(Widget):
self.update_available = False self.update_available = False
self.alert_count = 0 self.alert_count = 0
self._prev_update_available = False
self._prev_alerts_present = False
self.header_rect = rl.Rectangle(0, 0, 0, 0) self.header_rect = rl.Rectangle(0, 0, 0, 0)
self.content_rect = rl.Rectangle(0, 0, 0, 0) self.content_rect = rl.Rectangle(0, 0, 0, 0)
@ -185,20 +187,23 @@ class HomeLayout(Widget):
def _refresh(self): def _refresh(self):
# TODO: implement _update_state with a timer # TODO: implement _update_state with a timer
self.update_available = self.update_alert.refresh() update_available = self.update_alert.refresh()
self.alert_count = self.offroad_alert.refresh() alert_count = self.offroad_alert.refresh()
self._update_state_priority(self.update_available, self.alert_count > 0) alerts_present = alert_count > 0
def _update_state_priority(self, update_available: bool, alerts_present: bool):
current_state = self.current_state
# Show panels on transition from no alert/update to any alerts/update
if not update_available and not alerts_present: if not update_available and not alerts_present:
self.current_state = HomeLayoutState.HOME self.current_state = HomeLayoutState.HOME
elif update_available and (current_state == HomeLayoutState.HOME or (not alerts_present and current_state == HomeLayoutState.ALERTS)): elif update_available and ((not self._prev_update_available) or (not alerts_present and self.current_state == HomeLayoutState.ALERTS)):
self.current_state = HomeLayoutState.UPDATE self.current_state = HomeLayoutState.UPDATE
elif alerts_present and (current_state == HomeLayoutState.HOME or (not update_available and current_state == HomeLayoutState.UPDATE)): elif alerts_present and ((not self._prev_alerts_present) or (not update_available and self.current_state == HomeLayoutState.UPDATE)):
self.current_state = HomeLayoutState.ALERTS self.current_state = HomeLayoutState.ALERTS
self.update_available = update_available
self.alert_count = alert_count
self._prev_update_available = update_available
self._prev_alerts_present = alerts_present
def _get_version_text(self) -> str: def _get_version_text(self) -> str:
brand = "openpilot" brand = "openpilot"
description = self.params.get("UpdaterCurrentDescription") description = self.params.get("UpdaterCurrentDescription")

@ -70,6 +70,7 @@ def setup_pair_device(click, pm: PubMaster):
def setup_offroad_alert(click, pm: PubMaster): def setup_offroad_alert(click, pm: PubMaster):
set_offroad_alert("Offroad_TemperatureTooHigh", True, extra_text='99C') set_offroad_alert("Offroad_TemperatureTooHigh", True, extra_text='99C')
set_offroad_alert("Offroad_ExcessiveActuation", True, extra_text='longitudinal')
for alert in OFFROAD_ALERTS: for alert in OFFROAD_ALERTS:
set_offroad_alert(alert, True) set_offroad_alert(alert, True)

@ -29,9 +29,10 @@ class AlertConstants:
MARGIN = 50 MARGIN = 50
SPACING = 30 SPACING = 30
FONT_SIZE = 48 FONT_SIZE = 48
BORDER_RADIUS = 30 BORDER_RADIUS = 30 * 2 # matches Qt's 30px
ALERT_HEIGHT = 120 ALERT_HEIGHT = 120
ALERT_SPACING = 20 ALERT_SPACING = 10
ALERT_INSET = 60
@dataclass @dataclass
@ -88,7 +89,7 @@ class AbstractAlert(Widget, ABC):
HARDWARE.reboot() HARDWARE.reboot()
def _render(self, rect: rl.Rectangle): def _render(self, rect: rl.Rectangle):
rl.draw_rectangle_rounded(rect, AlertConstants.BORDER_RADIUS / rect.width, 10, AlertColors.BACKGROUND) rl.draw_rectangle_rounded(rect, AlertConstants.BORDER_RADIUS / rect.height, 10, AlertColors.BACKGROUND)
footer_height = AlertConstants.BUTTON_SIZE[1] + AlertConstants.SPACING footer_height = AlertConstants.BUTTON_SIZE[1] + AlertConstants.SPACING
content_height = rect.height - 2 * AlertConstants.MARGIN - footer_height content_height = rect.height - 2 * AlertConstants.MARGIN - footer_height
@ -138,7 +139,8 @@ class AbstractAlert(Widget, ABC):
self.dismiss_btn_rect.x = rect.x + AlertConstants.MARGIN self.dismiss_btn_rect.x = rect.x + AlertConstants.MARGIN
self.dismiss_btn_rect.y = footer_y self.dismiss_btn_rect.y = footer_y
rl.draw_rectangle_rounded(self.dismiss_btn_rect, 0.3, 10, AlertColors.BUTTON) roundness = AlertConstants.BORDER_RADIUS / self.dismiss_btn_rect.height
rl.draw_rectangle_rounded(self.dismiss_btn_rect, roundness, 10, AlertColors.BUTTON)
text = "Close" text = "Close"
text_width = measure_text_cached(font, text, AlertConstants.FONT_SIZE).x text_width = measure_text_cached(font, text, AlertConstants.FONT_SIZE).x
@ -151,7 +153,8 @@ class AbstractAlert(Widget, ABC):
if self.snooze_visible: if self.snooze_visible:
self.snooze_btn_rect.x = rect.x + rect.width - AlertConstants.MARGIN - AlertConstants.SNOOZE_BUTTON_SIZE[0] self.snooze_btn_rect.x = rect.x + rect.width - AlertConstants.MARGIN - AlertConstants.SNOOZE_BUTTON_SIZE[0]
self.snooze_btn_rect.y = footer_y self.snooze_btn_rect.y = footer_y
rl.draw_rectangle_rounded(self.snooze_btn_rect, 0.3, 10, AlertColors.SNOOZE_BG) roundness = AlertConstants.BORDER_RADIUS / self.snooze_btn_rect.height
rl.draw_rectangle_rounded(self.snooze_btn_rect, roundness, 10, AlertColors.SNOOZE_BG)
text = "Snooze Update" text = "Snooze Update"
text_width = measure_text_cached(font, text, AlertConstants.FONT_SIZE).x text_width = measure_text_cached(font, text, AlertConstants.FONT_SIZE).x
@ -162,7 +165,8 @@ class AbstractAlert(Widget, ABC):
elif self.has_reboot_btn: elif self.has_reboot_btn:
self.reboot_btn_rect.x = rect.x + rect.width - AlertConstants.MARGIN - AlertConstants.REBOOT_BUTTON_SIZE[0] self.reboot_btn_rect.x = rect.x + rect.width - AlertConstants.MARGIN - AlertConstants.REBOOT_BUTTON_SIZE[0]
self.reboot_btn_rect.y = footer_y self.reboot_btn_rect.y = footer_y
rl.draw_rectangle_rounded(self.reboot_btn_rect, 0.3, 10, AlertColors.BUTTON) roundness = AlertConstants.BORDER_RADIUS / self.reboot_btn_rect.height
rl.draw_rectangle_rounded(self.reboot_btn_rect, roundness, 10, AlertColors.BUTTON)
text = "Reboot and Update" text = "Reboot and Update"
text_width = measure_text_cached(font, text, AlertConstants.FONT_SIZE).x text_width = measure_text_cached(font, text, AlertConstants.FONT_SIZE).x
@ -215,11 +219,11 @@ class OffroadAlert(AbstractAlert):
if not alert_data.visible: if not alert_data.visible:
continue continue
text_width = int(self.content_rect.width - 90) text_width = int(self.content_rect.width - (AlertConstants.ALERT_INSET * 2))
wrapped_lines = wrap_text(font, alert_data.text, AlertConstants.FONT_SIZE, text_width) wrapped_lines = wrap_text(font, alert_data.text, AlertConstants.FONT_SIZE, text_width)
line_count = len(wrapped_lines) line_count = len(wrapped_lines)
text_height = line_count * (AlertConstants.FONT_SIZE + 5) text_height = line_count * (AlertConstants.FONT_SIZE + 5)
alert_item_height = max(text_height + 40, AlertConstants.ALERT_HEIGHT) alert_item_height = max(text_height + (AlertConstants.ALERT_INSET * 2), AlertConstants.ALERT_HEIGHT)
total_height += alert_item_height + AlertConstants.ALERT_SPACING total_height += alert_item_height + AlertConstants.ALERT_SPACING
if total_height > 20: if total_height > 20:
@ -235,7 +239,7 @@ class OffroadAlert(AbstractAlert):
self.sorted_alerts.append(alert_data) self.sorted_alerts.append(alert_data)
def _render_content(self, content_rect: rl.Rectangle): def _render_content(self, content_rect: rl.Rectangle):
y_offset = 20 y_offset = AlertConstants.ALERT_SPACING
font = gui_app.font(FontWeight.NORMAL) font = gui_app.font(FontWeight.NORMAL)
for alert_data in self.sorted_alerts: for alert_data in self.sorted_alerts:
@ -243,11 +247,11 @@ class OffroadAlert(AbstractAlert):
continue continue
bg_color = AlertColors.HIGH_SEVERITY if alert_data.severity > 0 else AlertColors.LOW_SEVERITY bg_color = AlertColors.HIGH_SEVERITY if alert_data.severity > 0 else AlertColors.LOW_SEVERITY
text_width = int(content_rect.width - 90) text_width = int(content_rect.width - (AlertConstants.ALERT_INSET * 2))
wrapped_lines = wrap_text(font, alert_data.text, AlertConstants.FONT_SIZE, text_width) wrapped_lines = wrap_text(font, alert_data.text, AlertConstants.FONT_SIZE, text_width)
line_count = len(wrapped_lines) line_count = len(wrapped_lines)
text_height = line_count * (AlertConstants.FONT_SIZE + 5) text_height = line_count * (AlertConstants.FONT_SIZE + 5)
alert_item_height = max(text_height + 40, AlertConstants.ALERT_HEIGHT) alert_item_height = max(text_height + (AlertConstants.ALERT_INSET * 2), AlertConstants.ALERT_HEIGHT)
alert_rect = rl.Rectangle( alert_rect = rl.Rectangle(
content_rect.x + 10, content_rect.x + 10,
@ -256,10 +260,11 @@ class OffroadAlert(AbstractAlert):
alert_item_height, alert_item_height,
) )
rl.draw_rectangle_rounded(alert_rect, 0.2, 10, bg_color) roundness = AlertConstants.BORDER_RADIUS / min(alert_rect.height, alert_rect.width)
rl.draw_rectangle_rounded(alert_rect, roundness, 10, bg_color)
text_x = alert_rect.x + 30 text_x = alert_rect.x + AlertConstants.ALERT_INSET
text_y = alert_rect.y + 20 text_y = alert_rect.y + AlertConstants.ALERT_INSET
for i, line in enumerate(wrapped_lines): for i, line in enumerate(wrapped_lines):
rl.draw_text_ex( rl.draw_text_ex(

Loading…
Cancel
Save