You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.1 KiB
97 lines
3.1 KiB
import pyray as rl
|
|
from enum import IntEnum
|
|
from openpilot.selfdrive.ui.layouts.sidebar import Sidebar, SIDEBAR_WIDTH
|
|
from openpilot.selfdrive.ui.layouts.home import HomeLayout
|
|
from openpilot.selfdrive.ui.layouts.settings.settings import SettingsLayout
|
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
|
from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView
|
|
from openpilot.system.ui.lib.application import Widget
|
|
|
|
|
|
class MainState(IntEnum):
|
|
HOME = 0
|
|
SETTINGS = 1
|
|
ONROAD = 2
|
|
|
|
|
|
class MainLayout(Widget):
|
|
def __init__(self):
|
|
self._sidebar = Sidebar()
|
|
self._sidebar_visible = True
|
|
self._current_mode = MainState.HOME
|
|
self._prev_onroad = False
|
|
self._window_rect = None
|
|
self._current_callback: callable | None = None
|
|
|
|
# Initialize layouts
|
|
self._layouts = {MainState.HOME: HomeLayout(), MainState.SETTINGS: SettingsLayout(), MainState.ONROAD: AugmentedRoadView()}
|
|
|
|
self._sidebar_rect = rl.Rectangle(0, 0, 0, 0)
|
|
self._content_rect = rl.Rectangle(0, 0, 0, 0)
|
|
|
|
# Set callbacks
|
|
self._setup_callbacks()
|
|
|
|
def render(self, rect):
|
|
self._current_callback = None
|
|
|
|
self._update_layout_rects(rect)
|
|
self._handle_onroad_transition()
|
|
self._render_main_content()
|
|
self._handle_input()
|
|
|
|
if self._current_callback:
|
|
self._current_callback()
|
|
|
|
def _setup_callbacks(self):
|
|
self._sidebar.set_callbacks(
|
|
on_settings=lambda: setattr(self, '_current_callback', self._on_settings_clicked),
|
|
on_flag=lambda: setattr(self, '_current_callback', self._on_flag_clicked),
|
|
)
|
|
self._layouts[MainState.SETTINGS].set_callbacks(
|
|
on_close=lambda: setattr(self, '_current_callback', self._set_mode_for_state)
|
|
)
|
|
|
|
def _update_layout_rects(self, rect):
|
|
self._window_rect = rect
|
|
self._sidebar_rect = rl.Rectangle(rect.x, rect.y, SIDEBAR_WIDTH, rect.height)
|
|
|
|
x_offset = SIDEBAR_WIDTH if self._sidebar_visible else 0
|
|
self._content_rect = rl.Rectangle(rect.y + x_offset, rect.y, rect.width - x_offset, rect.height)
|
|
|
|
def _handle_onroad_transition(self):
|
|
if ui_state.started != self._prev_onroad:
|
|
self._prev_onroad = ui_state.started
|
|
|
|
self._set_mode_for_state()
|
|
|
|
def _set_mode_for_state(self):
|
|
if ui_state.started:
|
|
self._current_mode = MainState.ONROAD
|
|
self._sidebar_visible = False
|
|
else:
|
|
self._current_mode = MainState.HOME
|
|
self._sidebar_visible = True
|
|
|
|
def _on_settings_clicked(self):
|
|
self._current_mode = MainState.SETTINGS
|
|
self._sidebar_visible = False
|
|
|
|
def _on_flag_clicked(self):
|
|
pass
|
|
|
|
def _render_main_content(self):
|
|
# Render sidebar
|
|
if self._sidebar_visible:
|
|
self._sidebar.render(self._sidebar_rect)
|
|
|
|
content_rect = self._content_rect if self._sidebar_visible else self._window_rect
|
|
self._layouts[self._current_mode].render(content_rect)
|
|
|
|
def _handle_input(self):
|
|
if self._current_mode != MainState.ONROAD or not rl.is_mouse_button_pressed(rl.MouseButton.MOUSE_BUTTON_LEFT):
|
|
return
|
|
|
|
mouse_pos = rl.get_mouse_position()
|
|
if rl.check_collision_point_rec(mouse_pos, self._content_rect):
|
|
self._sidebar_visible = not self._sidebar_visible
|
|
|