mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-20 15:54:13 +08:00
33d5cfc393
date: 2025-12-18T23:23:16 master commit: 3cdee7b54718ee14bd85befd6c5bad3d699c5479
150 lines
5.1 KiB
Python
150 lines
5.1 KiB
Python
import pyray as rl
|
|
from enum import IntEnum
|
|
import cereal.messaging as messaging
|
|
from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout
|
|
from openpilot.selfdrive.ui.mici.layouts.settings.settings import SettingsLayout
|
|
from openpilot.selfdrive.ui.mici.layouts.offroad_alerts import MiciOffroadAlerts
|
|
from openpilot.selfdrive.ui.mici.onroad.augmented_road_view import AugmentedRoadView
|
|
from openpilot.selfdrive.ui.ui_state import device, ui_state
|
|
from openpilot.selfdrive.ui.mici.layouts.onboarding import OnboardingWindow
|
|
from openpilot.system.ui.widgets import Widget
|
|
from openpilot.system.ui.widgets.scroller import Scroller
|
|
from openpilot.system.ui.lib.application import gui_app
|
|
|
|
|
|
ONROAD_DELAY = 2.5 # seconds
|
|
|
|
|
|
class MainState(IntEnum):
|
|
MAIN = 0
|
|
SETTINGS = 1
|
|
|
|
|
|
class MiciMainLayout(Widget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self._pm = messaging.PubMaster(['bookmarkButton'])
|
|
|
|
self._current_mode: MainState | None = None
|
|
self._prev_onroad = False
|
|
self._prev_standstill = False
|
|
self._onroad_time_delay: float | None = None
|
|
self._setup = False
|
|
|
|
# Initialize widgets
|
|
self._home_layout = MiciHomeLayout()
|
|
self._alerts_layout = MiciOffroadAlerts()
|
|
self._settings_layout = SettingsLayout()
|
|
self._onroad_layout = AugmentedRoadView(bookmark_callback=self._on_bookmark_clicked)
|
|
|
|
# Initialize widget rects
|
|
for widget in (self._home_layout, self._settings_layout, self._alerts_layout, self._onroad_layout):
|
|
# TODO: set parent rect and use it if never passed rect from render (like in Scroller)
|
|
widget.set_rect(rl.Rectangle(0, 0, gui_app.width, gui_app.height))
|
|
|
|
self._scroller = Scroller([
|
|
self._alerts_layout,
|
|
self._home_layout,
|
|
self._onroad_layout,
|
|
], spacing=0, pad_start=0, pad_end=0)
|
|
self._scroller.set_reset_scroll_at_show(False)
|
|
|
|
# Disable scrolling when onroad is interacting with bookmark
|
|
self._scroller.set_scrolling_enabled(lambda: not self._onroad_layout.is_swiping_left())
|
|
|
|
self._layouts = {
|
|
MainState.MAIN: self._scroller,
|
|
MainState.SETTINGS: self._settings_layout,
|
|
}
|
|
|
|
# Set callbacks
|
|
self._setup_callbacks()
|
|
|
|
# Start onboarding if terms or training not completed
|
|
self._onboarding_window = OnboardingWindow()
|
|
if not self._onboarding_window.completed:
|
|
gui_app.set_modal_overlay(self._onboarding_window)
|
|
|
|
def _setup_callbacks(self):
|
|
self._home_layout.set_callbacks(on_settings=self._on_settings_clicked)
|
|
self._settings_layout.set_callbacks(on_close=self._on_settings_closed)
|
|
self._onroad_layout.set_click_callback(lambda: self._scroll_to(self._home_layout))
|
|
device.add_interactive_timeout_callback(self._set_mode_for_started)
|
|
|
|
def _scroll_to(self, layout: Widget):
|
|
layout_x = int(layout.rect.x)
|
|
self._scroller.scroll_to(layout_x, smooth=True)
|
|
|
|
def _render(self, _):
|
|
# Initial show event
|
|
if self._current_mode is None:
|
|
self._set_mode(MainState.MAIN)
|
|
|
|
if not self._setup:
|
|
if self._alerts_layout.active_alerts() > 0:
|
|
self._scroller.scroll_to(self._alerts_layout.rect.x)
|
|
else:
|
|
self._scroller.scroll_to(self._rect.width)
|
|
self._setup = True
|
|
|
|
# Render
|
|
if self._current_mode == MainState.MAIN:
|
|
self._scroller.render(self._rect)
|
|
|
|
elif self._current_mode == MainState.SETTINGS:
|
|
self._settings_layout.render(self._rect)
|
|
|
|
self._handle_transitions()
|
|
|
|
def _set_mode(self, mode: MainState):
|
|
if mode != self._current_mode:
|
|
if self._current_mode is not None:
|
|
self._layouts[self._current_mode].hide_event()
|
|
self._layouts[mode].show_event()
|
|
self._current_mode = mode
|
|
|
|
def _handle_transitions(self):
|
|
if ui_state.started != self._prev_onroad:
|
|
self._prev_onroad = ui_state.started
|
|
|
|
if ui_state.started:
|
|
self._onroad_time_delay = rl.get_time()
|
|
else:
|
|
self._set_mode_for_started(True)
|
|
|
|
# delay so we show home for a bit after starting
|
|
if self._onroad_time_delay is not None and rl.get_time() - self._onroad_time_delay >= ONROAD_DELAY:
|
|
self._set_mode_for_started(True)
|
|
self._onroad_time_delay = None
|
|
|
|
CS = ui_state.sm["carState"]
|
|
if not CS.standstill and self._prev_standstill:
|
|
self._set_mode(MainState.MAIN)
|
|
self._scroll_to(self._onroad_layout)
|
|
self._prev_standstill = CS.standstill
|
|
|
|
def _set_mode_for_started(self, onroad_transition: bool = False):
|
|
if ui_state.started:
|
|
CS = ui_state.sm["carState"]
|
|
# Only go onroad if car starts or is not at a standstill
|
|
if not CS.standstill or onroad_transition:
|
|
self._set_mode(MainState.MAIN)
|
|
self._scroll_to(self._onroad_layout)
|
|
else:
|
|
# Stay in settings if car turns off while in settings
|
|
if not onroad_transition or self._current_mode != MainState.SETTINGS:
|
|
self._set_mode(MainState.MAIN)
|
|
self._scroll_to(self._home_layout)
|
|
|
|
def _on_settings_clicked(self):
|
|
self._set_mode(MainState.SETTINGS)
|
|
|
|
def _on_settings_closed(self):
|
|
self._set_mode(MainState.MAIN)
|
|
|
|
def _on_bookmark_clicked(self):
|
|
user_bookmark = messaging.new_message('bookmarkButton')
|
|
user_bookmark.valid = True
|
|
self._pm.send('bookmarkButton', user_bookmark)
|