Files
StarPilot/selfdrive/ui/mici/layouts/settings/settings.py
T

149 lines
5.5 KiB
Python

import pyray as rl
from dataclasses import dataclass
from enum import IntEnum
from collections.abc import Callable
from openpilot.common.params import Params
from openpilot.system.ui.widgets.scroller import Scroller
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigMultiToggle
from openpilot.selfdrive.ui.mici.layouts.settings.toggles import TogglesLayoutMici
from openpilot.selfdrive.ui.mici.layouts.settings.network import NetworkLayoutMici
from openpilot.selfdrive.ui.mici.layouts.settings.device import DeviceLayoutMici, PairBigButton, GalaxyBigButton
from openpilot.selfdrive.ui.mici.layouts.settings.developer import DeveloperLayoutMici
from openpilot.selfdrive.ui.mici.layouts.settings.firehose import FirehoseLayout
from openpilot.system.ui.lib.application import gui_app, FontWeight
from openpilot.system.ui.widgets import Widget, NavWidget
class PanelType(IntEnum):
TOGGLES = 0
NETWORK = 1
DEVICE = 2
DEVELOPER = 3
USER_MANUAL = 4
FIREHOSE = 5
@dataclass
class PanelInfo:
name: str
instance: Widget
class ForceDriveStateBigButton(BigMultiToggle):
def __init__(self):
super().__init__("force drive state", ["offroad", "onroad", "off"])
self._params = Params()
self.refresh()
def _handle_mouse_release(self, mouse_pos):
super()._handle_mouse_release(mouse_pos)
self._apply_mode(self.value)
def _apply_mode(self, mode: str):
if mode == "offroad":
self._params.put_bool("ForceOffroad", True)
self._params.put_bool("ForceOnroad", False)
elif mode == "onroad":
self._params.put_bool("ForceOffroad", False)
self._params.put_bool("ForceOnroad", True)
else:
self._params.put_bool("ForceOffroad", False)
self._params.put_bool("ForceOnroad", False)
def refresh(self):
if self._params.get_bool("ForceOffroad"):
self.set_value("offroad")
elif self._params.get_bool("ForceOnroad"):
self.set_value("onroad")
else:
self.set_value("off")
class SettingsLayout(NavWidget):
def __init__(self):
super().__init__()
self._params = Params()
self._current_panel = None # PanelType.DEVICE
toggles_btn = BigButton("toggles", "", "icons_mici/settings/toggles_icon.png")
toggles_btn.set_click_callback(lambda: self._set_current_panel(PanelType.TOGGLES))
network_btn = BigButton("network", "", "icons_mici/settings/network/wifi_strength_full.png")
network_btn.set_click_callback(lambda: self._set_current_panel(PanelType.NETWORK))
device_btn = BigButton("device", "", "icons_mici/settings/device_icon.png")
device_btn.set_click_callback(lambda: self._set_current_panel(PanelType.DEVICE))
developer_btn = BigButton("developer", "", "icons_mici/settings/developer_icon.png")
developer_btn.set_click_callback(lambda: self._set_current_panel(PanelType.DEVELOPER))
firehose_btn = BigButton("firehose", "", "icons_mici/settings/comma_icon.png")
firehose_btn.set_click_callback(lambda: self._set_current_panel(PanelType.FIREHOSE))
self._force_drive_state_btn = ForceDriveStateBigButton()
self._scroller = Scroller([
toggles_btn,
network_btn,
self._force_drive_state_btn,
device_btn,
PairBigButton(),
GalaxyBigButton(),
#BigDialogButton("manual", "", "icons_mici/settings/manual_icon.png", "Check out the mici user\nmanual at comma.ai/setup"),
firehose_btn,
developer_btn,
], snap_items=False, scroll_indicator=True, edge_shadows=True)
# Set up back navigation
self.set_back_callback(self.close_settings)
self.set_back_enabled(lambda: self._current_panel is None)
self._panels = {
PanelType.TOGGLES: PanelInfo("Toggles", TogglesLayoutMici(back_callback=lambda: self._set_current_panel(None))),
PanelType.NETWORK: PanelInfo("Network", NetworkLayoutMici(back_callback=lambda: self._set_current_panel(None))),
PanelType.DEVICE: PanelInfo("Device", DeviceLayoutMici(back_callback=lambda: self._set_current_panel(None))),
PanelType.DEVELOPER: PanelInfo("Developer", DeveloperLayoutMici(back_callback=lambda: self._set_current_panel(None))),
PanelType.FIREHOSE: PanelInfo("Firehose", FirehoseLayout(back_callback=lambda: self._set_current_panel(None))),
}
self._font_medium = gui_app.font(FontWeight.MEDIUM)
# Callbacks
self._close_callback: Callable | None = None
def show_event(self):
super().show_event()
self._force_drive_state_btn.refresh()
self._set_current_panel(None)
self._scroller.show_event()
if self._current_panel is not None:
self._panels[self._current_panel].instance.show_event()
def hide_event(self):
super().hide_event()
if self._current_panel is not None:
self._panels[self._current_panel].instance.hide_event()
def set_callbacks(self, on_close: Callable):
self._close_callback = on_close
def _render(self, rect: rl.Rectangle):
if self._current_panel is not None:
self._draw_current_panel()
else:
self._scroller.render(rect)
def _draw_current_panel(self):
panel = self._panels[self._current_panel]
panel.instance.render(self._rect)
def _set_current_panel(self, panel_type: PanelType | None):
if panel_type != self._current_panel:
if self._current_panel is not None:
self._panels[self._current_panel].instance.hide_event()
self._current_panel = panel_type
if self._current_panel is not None:
self._panels[self._current_panel].instance.show_event()
def close_settings(self):
if self._close_callback:
self._close_callback()