diff --git a/selfdrive/ui/mici/layouts/onboarding.py b/selfdrive/ui/mici/layouts/onboarding.py index b7fafd894a..7b619f31ec 100644 --- a/selfdrive/ui/mici/layouts/onboarding.py +++ b/selfdrive/ui/mici/layouts/onboarding.py @@ -8,14 +8,13 @@ from openpilot.common.filter_simple import FirstOrderFilter from openpilot.system.hardware import HARDWARE from openpilot.system.ui.lib.application import FontWeight, gui_app from openpilot.system.ui.widgets import Widget -from openpilot.system.ui.widgets.nav_widget import NavWidget from openpilot.system.ui.widgets.button import SmallButton, SmallCircleIconButton from openpilot.system.ui.widgets.label import UnifiedLabel from openpilot.system.ui.widgets.slider import SmallSlider from openpilot.system.ui.mici_setup import TermsHeader, TermsPage as SetupTermsPage from openpilot.selfdrive.ui.ui_state import ui_state, device from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer -from openpilot.selfdrive.ui.mici.onroad.driver_camera_dialog import DriverCameraDialog +from openpilot.selfdrive.ui.mici.onroad.driver_camera_dialog import BaseDriverCameraDialog from openpilot.system.ui.widgets.label import gui_label from openpilot.system.ui.lib.multilang import tr from openpilot.system.version import terms_version, training_version @@ -27,9 +26,9 @@ class OnboardingState(IntEnum): DECLINE = 2 -class DriverCameraSetupDialog(DriverCameraDialog): +class DriverCameraSetupDialog(BaseDriverCameraDialog): def __init__(self): - super().__init__(no_escape=True) + super().__init__() self.driver_state_renderer = DriverStateRenderer(inset=True) self.driver_state_renderer.set_rect(rl.Rectangle(0, 0, 120, 120)) self.driver_state_renderer.load_icons() @@ -438,11 +437,9 @@ class TermsPage(SetupTermsPage): )) -class OnboardingWindow(NavWidget): +class OnboardingWindow(Widget): def __init__(self): super().__init__() - self.set_back_enabled(False) - self._accepted_terms: bool = ui_state.params.get("HasAcceptedTerms") == terms_version self._training_done: bool = ui_state.params.get("CompletedTrainingVersion") == training_version @@ -486,6 +483,7 @@ class OnboardingWindow(NavWidget): self.close() def _render(self, _): + rl.draw_rectangle_rec(self._rect, rl.BLACK) if self._state == OnboardingState.TERMS: self._terms.render(self._rect) elif self._state == OnboardingState.ONBOARDING: diff --git a/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/selfdrive/ui/mici/onroad/driver_camera_dialog.py index dfa8beeb77..e8321b099c 100644 --- a/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -7,6 +7,7 @@ from openpilot.selfdrive.ui.ui_state import ui_state, device from openpilot.selfdrive.selfdrived.events import EVENTS, ET from openpilot.system.ui.lib.application import gui_app, FontWeight from openpilot.system.ui.lib.multilang import tr +from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.nav_widget import NavWidget from openpilot.system.ui.widgets.label import gui_label @@ -24,18 +25,15 @@ class DriverCameraView(CameraView): return base -class DriverCameraDialog(NavWidget): - def __init__(self, no_escape=False): +class BaseDriverCameraDialog(Widget): + # Not a NavWidget so training guide can use this without back navigation + def __init__(self): super().__init__() self._camera_view = DriverCameraView("camerad", VisionStreamType.VISION_STREAM_DRIVER) self.driver_state_renderer = DriverStateRenderer(lines=True) self.driver_state_renderer.set_rect(rl.Rectangle(0, 0, 200, 200)) self.driver_state_renderer.load_icons() self._pm: messaging.PubMaster | None = None - if not no_escape: - # TODO: this can grow unbounded, should be given some thought - device.add_interactive_timeout_callback(gui_app.pop_widget) - self.set_back_enabled(not no_escape) # Load eye icons self._eye_fill_texture = None @@ -230,6 +228,13 @@ class DriverCameraDialog(NavWidget): rl.draw_texture_v(self._glasses_texture, glasses_pos, rl.Color(70, 80, 161, int(255 * glasses_prob))) +class DriverCameraDialog(NavWidget, BaseDriverCameraDialog): + def __init__(self): + super().__init__() + # TODO: this can grow unbounded, should be given some thought + device.add_interactive_timeout_callback(gui_app.pop_widget) + + if __name__ == "__main__": gui_app.init_window("Driver Camera View (mici)") diff --git a/system/ui/widgets/nav_widget.py b/system/ui/widgets/nav_widget.py index 55eea04fe1..d7d3942157 100644 --- a/system/ui/widgets/nav_widget.py +++ b/system/ui/widgets/nav_widget.py @@ -2,7 +2,6 @@ from __future__ import annotations import abc import pyray as rl -from collections.abc import Callable from openpilot.system.ui.widgets import Widget from openpilot.common.filter_simple import BounceFilter, FirstOrderFilter from openpilot.system.ui.lib.application import gui_app, MousePos, MouseEvent @@ -60,28 +59,14 @@ class NavWidget(Widget, abc.ABC): self._playing_dismiss_animation = False # released and animating away self._y_pos_filter = BounceFilter(0.0, 0.1, 1 / gui_app.target_fps, bounce=1) - self._back_enabled: bool | Callable[[], bool] = True - self._nav_bar = NavBar() self._nav_bar_show_time = 0.0 self._nav_bar_y_filter = FirstOrderFilter(0.0, 0.1, 1 / gui_app.target_fps) - @property - def back_enabled(self) -> bool: - return self._back_enabled() if callable(self._back_enabled) else self._back_enabled - - def set_back_enabled(self, enabled: bool | Callable[[], bool]) -> None: - self._back_enabled = enabled - def _handle_mouse_event(self, mouse_event: MouseEvent) -> None: # FIXME: disabling this widget on new push_widget still causes this widget to track mouse events without mouse down super()._handle_mouse_event(mouse_event) - if not self.back_enabled: - self._drag_start_pos = None - self._dragging_down = False - return - if mouse_event.left_pressed: # user is able to swipe away if starting near top of screen, or anywhere if scroller is at top self._y_pos_filter.update_alpha(0.04) @@ -172,21 +157,20 @@ class NavWidget(Widget, abc.ABC): def render(self, rect: rl.Rectangle | None = None) -> bool | int | None: ret = super().render(rect) - if self.back_enabled: - bar_x = self._rect.x + (self._rect.width - self._nav_bar.rect.width) / 2 - nav_bar_delayed = rl.get_time() - self._nav_bar_show_time < 0.4 - # User dragging or dismissing, nav bar follows NavWidget - if self._drag_start_pos is not None or self._playing_dismiss_animation: - self._nav_bar_y_filter.x = NAV_BAR_MARGIN + self._y_pos_filter.x - # Waiting to show - elif nav_bar_delayed: - self._nav_bar_y_filter.x = -NAV_BAR_MARGIN - NAV_BAR_HEIGHT - # Animate back to top - else: - self._nav_bar_y_filter.update(NAV_BAR_MARGIN) + bar_x = self._rect.x + (self._rect.width - self._nav_bar.rect.width) / 2 + nav_bar_delayed = rl.get_time() - self._nav_bar_show_time < 0.4 + # User dragging or dismissing, nav bar follows NavWidget + if self._drag_start_pos is not None or self._playing_dismiss_animation: + self._nav_bar_y_filter.x = NAV_BAR_MARGIN + self._y_pos_filter.x + # Waiting to show + elif nav_bar_delayed: + self._nav_bar_y_filter.x = -NAV_BAR_MARGIN - NAV_BAR_HEIGHT + # Animate back to top + else: + self._nav_bar_y_filter.update(NAV_BAR_MARGIN) - self._nav_bar.set_position(bar_x, round(self._nav_bar_y_filter.x)) - self._nav_bar.render() + self._nav_bar.set_position(bar_x, round(self._nav_bar_y_filter.x)) + self._nav_bar.render() return ret