Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions selfdrive/assets/icons_mici/alerts_bell.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions selfdrive/assets/icons_mici/alerts_pill.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 40 additions & 3 deletions selfdrive/ui/mici/layouts/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.widgets.layouts import HBoxLayout
from openpilot.system.ui.widgets.icon_widget import IconWidget
from openpilot.system.ui.widgets.label import UnifiedLabel
from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos
from openpilot.system.ui.widgets.label import UnifiedLabel, gui_label
from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos, DEFAULT_TEXT_COLOR
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.version import RELEASE_BRANCHES

Expand All @@ -28,6 +28,34 @@
}


class AlertsPill(Widget):
def __init__(self):
super().__init__()
self.set_rect(rl.Rectangle(0, 0, 104, 52))

self._pill_bg_txt = gui_app.texture("icons_mici/alerts_pill.png", 104, 52)
self._bell_txt = gui_app.texture("icons_mici/alerts_bell.png", 28, 30)
self._alert_count_callback: Callable[[], int] | None = None

def set_alert_count_callback(self, callback: Callable[[], int] | None):
self._alert_count_callback = callback

def _render(self, _):
alert_count = self._alert_count_callback() if self._alert_count_callback else 0
if alert_count > 0:
pill_w, pill_h = self._pill_bg_txt.width, self._pill_bg_txt.height
rl.draw_texture_ex(self._pill_bg_txt, rl.Vector2(self.rect.x, self.rect.y), 0.0, 1.0, rl.WHITE)

bell_x = self.rect.x + 20
bell_y = self.rect.y + (pill_h - self._bell_txt.height) / 2
rl.draw_texture_ex(self._bell_txt, rl.Vector2(bell_x, bell_y), 0.0, 1.0, DEFAULT_TEXT_COLOR)

count_rect = rl.Rectangle(self.rect.x, self.rect.y, pill_w - 20, pill_h)
gui_label(count_rect, str(alert_count), font_size=36,
alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT,
alignment_vertical=rl.GuiTextAlignmentVertical.TEXT_ALIGN_MIDDLE)


class NetworkIcon(Widget):
def __init__(self):
super().__init__()
Expand Down Expand Up @@ -84,6 +112,7 @@ class MiciHomeLayout(Widget):
def __init__(self):
super().__init__()
self._on_settings_click: Callable | None = None
self._alert_count_callback: Callable[[], int] | None = None

self._last_refresh = 0
self._mouse_down_t: None | float = None
Expand All @@ -96,6 +125,8 @@ def __init__(self):
self._experimental_icon = IconWidget("icons_mici/experimental_mode.png", (48, 48))
self._mic_icon = IconWidget("icons_mici/microphone.png", (32, 46))

self._alerts_pill = AlertsPill()

self._status_bar_layout = HBoxLayout([
IconWidget("icons_mici/settings.png", (48, 48), opacity=0.9),
NetworkIcon(),
Expand Down Expand Up @@ -141,8 +172,9 @@ def _update_state(self):
self._last_refresh = rl.get_time()
self._update_params()

def set_callbacks(self, on_settings: Callable | None = None):
def set_callbacks(self, on_settings: Callable | None = None, alert_count_callback: Callable[[], int] | None = None):
self._on_settings_click = on_settings
self._alerts_pill.set_alert_count_callback(alert_count_callback)

def _handle_mouse_release(self, mouse_pos: MousePos):
if not self._did_long_press:
Expand Down Expand Up @@ -203,3 +235,8 @@ def _render(self, _):

footer_rect = rl.Rectangle(self.rect.x + HOME_PADDING, self.rect.y + self.rect.height - 48, self.rect.width - HOME_PADDING, 48)
self._status_bar_layout.render(footer_rect)

# TODO: add alignment to hboxlayout and add to there
self._alerts_pill.set_position(self.rect.x + self.rect.width - self._alerts_pill.rect.width - HOME_PADDING,
self.rect.y + self.rect.height - self._alerts_pill.rect.height)
self._alerts_pill.render()
10 changes: 9 additions & 1 deletion selfdrive/ui/mici/layouts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,22 @@ def __init__(self):
gui_app.push_widget(self._onboarding_window)

def _setup_callbacks(self):
self._home_layout.set_callbacks(on_settings=lambda: gui_app.push_widget(self._settings_layout))
self._home_layout.set_callbacks(
on_settings=lambda: gui_app.push_widget(self._settings_layout),
alert_count_callback=self._alerts_layout.active_alerts,
)
self._onroad_layout.set_click_callback(lambda: self._scroll_to(self._home_layout))
device.add_interactive_timeout_callback(self._on_interactive_timeout)

def _scroll_to(self, layout: Widget):
layout_x = int(layout.rect.x)
self._scroller.scroll_to(layout_x, smooth=True)

def _update_state(self):
super()._update_state()
# TODO: Hack to run alert updates while not in view. Add a nav stack tick?
self._alerts_layout._update_state()
Comment on lines +72 to +75
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it not updating state? how does it normally work? oh it's out of view. this will double run it when in view. and make sure to call super() _update state

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can make alerts a singleton in the future

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double run is gated by REFRESH_INTERVAL (5s) but still a hack, yes.


def _render(self, _):
if not self._setup:
if self._alerts_layout.active_alerts() > 0:
Expand Down
Loading