mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-07 00:05:44 +08:00
Compare commits
2 Commits
egpu-support
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 099143ad9d | |||
| 6909aa95ff |
@@ -13,6 +13,7 @@ from openpilot.selfdrive.ui.body.layouts.onroad import BodyLayout
|
|||||||
|
|
||||||
if gui_app.sunnypilot_ui():
|
if gui_app.sunnypilot_ui():
|
||||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.settings import SettingsLayoutSP as SettingsLayout
|
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.settings import SettingsLayoutSP as SettingsLayout
|
||||||
|
from openpilot.selfdrive.ui.sunnypilot.layouts.home import HomeLayoutSP as HomeLayout
|
||||||
|
|
||||||
|
|
||||||
class MainState(IntEnum):
|
class MainState(IntEnum):
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from openpilot.system.ui.lib.application import gui_app
|
|||||||
|
|
||||||
if gui_app.sunnypilot_ui():
|
if gui_app.sunnypilot_ui():
|
||||||
from openpilot.selfdrive.ui.sunnypilot.mici.layouts.settings import SettingsLayoutSP as SettingsLayout
|
from openpilot.selfdrive.ui.sunnypilot.mici.layouts.settings import SettingsLayoutSP as SettingsLayout
|
||||||
|
from openpilot.selfdrive.ui.sunnypilot.mici.layouts.home import MiciHomeLayoutSP as MiciHomeLayout
|
||||||
|
|
||||||
ONROAD_DELAY = 2.5 # seconds
|
ONROAD_DELAY = 2.5 # seconds
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
"""
|
||||||
|
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||||
|
|
||||||
|
This file is part of sunnypilot and is licensed under the MIT License.
|
||||||
|
See the LICENSE.md file in the root directory for more details.
|
||||||
|
"""
|
||||||
|
import pyray as rl
|
||||||
|
from openpilot.selfdrive.ui.layouts.home import HomeLayout, HomeLayoutState, HEAD_BUTTON_FONT_SIZE, SPACING
|
||||||
|
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||||
|
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||||
|
from openpilot.system.ui.lib.multilang import tr, trn
|
||||||
|
from openpilot.system.ui.widgets.label import gui_label
|
||||||
|
|
||||||
|
BRAND_FONT_SIZE = 48
|
||||||
|
BRAND_DESC_SPACING = 12
|
||||||
|
|
||||||
|
|
||||||
|
class HomeLayoutSP(HomeLayout):
|
||||||
|
def _render_header(self):
|
||||||
|
font = gui_app.font(FontWeight.MEDIUM)
|
||||||
|
|
||||||
|
version_text_width = self.header_rect.width
|
||||||
|
|
||||||
|
if self.update_available:
|
||||||
|
version_text_width -= self.update_notif_rect.width
|
||||||
|
|
||||||
|
highlight_color = rl.Color(75, 95, 255, 255) if self.current_state == HomeLayoutState.UPDATE else rl.Color(54, 77, 239, 255)
|
||||||
|
rl.draw_rectangle_rounded(self.update_notif_rect, 0.3, 10, highlight_color)
|
||||||
|
|
||||||
|
text = tr("UPDATE")
|
||||||
|
text_size = measure_text_cached(font, text, HEAD_BUTTON_FONT_SIZE)
|
||||||
|
text_x = self.update_notif_rect.x + (self.update_notif_rect.width - text_size.x) // 2
|
||||||
|
text_y = self.update_notif_rect.y + (self.update_notif_rect.height - text_size.y) // 2
|
||||||
|
rl.draw_text_ex(font, text, rl.Vector2(int(text_x), int(text_y)), HEAD_BUTTON_FONT_SIZE, 0, rl.WHITE)
|
||||||
|
|
||||||
|
if self.alert_count > 0:
|
||||||
|
version_text_width -= self.alert_notif_rect.width
|
||||||
|
|
||||||
|
highlight_color = rl.Color(255, 70, 70, 255) if self.current_state == HomeLayoutState.ALERTS else rl.Color(226, 44, 44, 255)
|
||||||
|
rl.draw_rectangle_rounded(self.alert_notif_rect, 0.3, 10, highlight_color)
|
||||||
|
|
||||||
|
alert_text = trn("{} ALERT", "{} ALERTS", self.alert_count).format(self.alert_count)
|
||||||
|
text_size = measure_text_cached(font, alert_text, HEAD_BUTTON_FONT_SIZE)
|
||||||
|
text_x = self.alert_notif_rect.x + (self.alert_notif_rect.width - text_size.x) // 2
|
||||||
|
text_y = self.alert_notif_rect.y + (self.alert_notif_rect.height - text_size.y) // 2
|
||||||
|
rl.draw_text_ex(font, alert_text, rl.Vector2(int(text_x), int(text_y)), HEAD_BUTTON_FONT_SIZE, 0, rl.WHITE)
|
||||||
|
|
||||||
|
if self.update_available or self.alert_count > 0:
|
||||||
|
version_text_width -= SPACING * 1.5
|
||||||
|
|
||||||
|
version_right = self.header_rect.x + self.header_rect.width
|
||||||
|
version_left = version_right - version_text_width
|
||||||
|
|
||||||
|
brand = "sunnypilot"
|
||||||
|
description = self.params.get("UpdaterCurrentDescription") or ""
|
||||||
|
|
||||||
|
desc_width = 0
|
||||||
|
if description:
|
||||||
|
desc_size = measure_text_cached(gui_app.font(FontWeight.NORMAL), description, BRAND_FONT_SIZE)
|
||||||
|
desc_width = desc_size.x
|
||||||
|
desc_rect = rl.Rectangle(version_right - desc_width, self.header_rect.y, desc_width, self.header_rect.height)
|
||||||
|
gui_label(desc_rect, description, BRAND_FONT_SIZE, rl.WHITE, alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT)
|
||||||
|
|
||||||
|
brand_size = measure_text_cached(gui_app.font(FontWeight.AUDIOWIDE), brand, BRAND_FONT_SIZE)
|
||||||
|
spacing = BRAND_DESC_SPACING if description else 0
|
||||||
|
brand_x = version_right - desc_width - spacing - brand_size.x
|
||||||
|
brand_rect = rl.Rectangle(max(version_left, brand_x), self.header_rect.y, brand_size.x, self.header_rect.height)
|
||||||
|
gui_label(brand_rect, brand, BRAND_FONT_SIZE, rl.WHITE, font_weight=FontWeight.AUDIOWIDE)
|
||||||
@@ -20,7 +20,7 @@ class SunnylinkConsentPage(Widget):
|
|||||||
self._done_callback = done_callback
|
self._done_callback = done_callback
|
||||||
self._step = 0
|
self._step = 0
|
||||||
|
|
||||||
self._title = self._child(Label(tr("sunnylink"), font_size=90, font_weight=FontWeight.BOLD, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT))
|
self._title = self._child(Label(tr("sunnylink"), font_size=90, font_weight=FontWeight.AUDIOWIDE, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT))
|
||||||
|
|
||||||
self._content = [
|
self._content = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
"""
|
||||||
|
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||||
|
|
||||||
|
This file is part of sunnypilot and is licensed under the MIT License.
|
||||||
|
See the LICENSE.md file in the root directory for more details.
|
||||||
|
"""
|
||||||
|
from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout
|
||||||
|
from openpilot.system.ui.lib.application import FontWeight
|
||||||
|
from openpilot.system.ui.widgets.label import UnifiedLabel
|
||||||
|
|
||||||
|
|
||||||
|
class MiciHomeLayoutSP(MiciHomeLayout):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self._openpilot_label = UnifiedLabel("sunnypilot", font_size=88, font_weight=FontWeight.AUDIOWIDE, max_width=480, wrap_text=False)
|
||||||
@@ -4,7 +4,6 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
|||||||
This file is part of sunnypilot and is licensed under the MIT License.
|
This file is part of sunnypilot and is licensed under the MIT License.
|
||||||
See the LICENSE.md file in the root directory for more details.
|
See the LICENSE.md file in the root directory for more details.
|
||||||
"""
|
"""
|
||||||
from collections.abc import Callable
|
|
||||||
import pyray as rl
|
import pyray as rl
|
||||||
|
|
||||||
from openpilot.cereal import custom
|
from openpilot.cereal import custom
|
||||||
@@ -48,10 +47,8 @@ class CurrentModelInfo(Widget):
|
|||||||
self.info_text.render()
|
self.info_text.render()
|
||||||
|
|
||||||
class ModelsLayoutMici(NavScroller):
|
class ModelsLayoutMici(NavScroller):
|
||||||
def __init__(self, back_callback: Callable):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.set_back_callback(back_callback)
|
|
||||||
self.original_back_callback = back_callback
|
|
||||||
self.focused_widget = None
|
self.focused_widget = None
|
||||||
|
|
||||||
self.current_model_info = CurrentModelInfo()
|
self.current_model_info = CurrentModelInfo()
|
||||||
@@ -85,12 +82,10 @@ class ModelsLayoutMici(NavScroller):
|
|||||||
|
|
||||||
return folders
|
return folders
|
||||||
|
|
||||||
def _show_selection_view(self, items, back_callback: Callable):
|
def _push_selection_view(self, items):
|
||||||
self._scroller._items = items
|
scroller = NavScroller()
|
||||||
for item in items:
|
scroller._scroller.add_widgets(items)
|
||||||
item.set_touch_valid_callback(lambda: self._scroller.scroll_panel.is_touch_valid() and self._scroller.enabled)
|
gui_app.push_widget(scroller)
|
||||||
self._scroller.scroll_panel.set_offset(0)
|
|
||||||
self.set_back_callback(back_callback)
|
|
||||||
|
|
||||||
def _show_folders(self):
|
def _show_folders(self):
|
||||||
self.focused_widget = self.select_model_btn
|
self.focused_widget = self.select_model_btn
|
||||||
@@ -112,15 +107,18 @@ class ModelsLayoutMici(NavScroller):
|
|||||||
folder_buttons.insert(0, btn)
|
folder_buttons.insert(0, btn)
|
||||||
else:
|
else:
|
||||||
folder_buttons.append(btn)
|
folder_buttons.append(btn)
|
||||||
self._show_selection_view(folder_buttons, self._reset_main_view)
|
self._push_selection_view(folder_buttons)
|
||||||
|
|
||||||
|
def _pop_to_main(self):
|
||||||
|
gui_app.pop_widgets_to(self)
|
||||||
|
|
||||||
def _select_model(self, bundle):
|
def _select_model(self, bundle):
|
||||||
ui_state.params.put("ModelManager_DownloadIndex", bundle.index)
|
ui_state.params.put("ModelManager_DownloadIndex", bundle.index)
|
||||||
self._reset_main_view()
|
self._pop_to_main()
|
||||||
|
|
||||||
def _select_default(self):
|
def _select_default(self):
|
||||||
ui_state.params.remove("ModelManager_ActiveBundle")
|
ui_state.params.remove("ModelManager_ActiveBundle")
|
||||||
self._reset_main_view()
|
self._pop_to_main()
|
||||||
|
|
||||||
def _select_folder(self, folder_name):
|
def _select_folder(self, folder_name):
|
||||||
favs = ui_state.params.get("ModelManager_Favs")
|
favs = ui_state.params.get("ModelManager_Favs")
|
||||||
@@ -135,13 +133,7 @@ class ModelsLayoutMici(NavScroller):
|
|||||||
btn = BigButton(txt)
|
btn = BigButton(txt)
|
||||||
btn.set_click_callback(lambda b=bundle: self._select_model(b))
|
btn.set_click_callback(lambda b=bundle: self._select_model(b))
|
||||||
btns.append(btn)
|
btns.append(btn)
|
||||||
self._show_selection_view(btns, self._show_folders)
|
self._push_selection_view(btns)
|
||||||
|
|
||||||
def _reset_main_view(self):
|
|
||||||
self._scroller._items = self.main_items # type: ignore[assignment] # ty: ignore[invalid-assignment]
|
|
||||||
self.set_back_callback(self.original_back_callback)
|
|
||||||
self._scroller.scroll_panel.set_offset(0)
|
|
||||||
self._scroller.scroll_to(0)
|
|
||||||
|
|
||||||
def hide_event(self):
|
def hide_event(self):
|
||||||
super().hide_event()
|
super().hide_event()
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ class SettingsLayoutSP(OP.SettingsLayout):
|
|||||||
BIG_ICON_SIZE)
|
BIG_ICON_SIZE)
|
||||||
self.icon_offroad_slider = gui_app.texture("icons_mici/settings/device/lkas.png", BIG_ICON_SIZE, BIG_ICON_SIZE)
|
self.icon_offroad_slider = gui_app.texture("icons_mici/settings/device/lkas.png", BIG_ICON_SIZE, BIG_ICON_SIZE)
|
||||||
|
|
||||||
sunnylink_panel = SunnylinkLayoutMici(back_callback=gui_app.pop_widget)
|
sunnylink_panel = SunnylinkLayoutMici()
|
||||||
sunnylink_btn = SettingsBigButton(tr("sunnylink"), "", gui_app.texture("icons_mici/settings/developer/ssh.png", 55, 55))
|
sunnylink_btn = SettingsBigButton(tr("sunnylink"), "", gui_app.texture("icons_mici/settings/developer/ssh.png", 55, 55))
|
||||||
sunnylink_btn.set_click_callback(lambda: gui_app.push_widget(sunnylink_panel))
|
sunnylink_btn.set_click_callback(lambda: gui_app.push_widget(sunnylink_panel))
|
||||||
|
|
||||||
models_panel = ModelsLayoutMici(back_callback=gui_app.pop_widget)
|
models_panel = ModelsLayoutMici()
|
||||||
models_btn = SettingsBigButton(tr("models"), "", gui_app.texture("../../sunnypilot/selfdrive/assets/offroad/icon_models.png", ICON_SIZE, ICON_SIZE))
|
models_btn = SettingsBigButton(tr("models"), "", gui_app.texture("../../sunnypilot/selfdrive/assets/offroad/icon_models.png", ICON_SIZE, ICON_SIZE))
|
||||||
models_btn.set_click_callback(lambda: gui_app.push_widget(models_panel))
|
models_btn.set_click_callback(lambda: gui_app.push_widget(models_panel))
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ See the LICENSE.md file in the root directory for more details.
|
|||||||
"""
|
"""
|
||||||
import pyray as rl
|
import pyray as rl
|
||||||
|
|
||||||
from collections.abc import Callable
|
|
||||||
|
|
||||||
from openpilot.cereal import custom
|
from openpilot.cereal import custom
|
||||||
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigToggle
|
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigToggle
|
||||||
@@ -54,9 +53,8 @@ class SunnylinkInfo(Widget):
|
|||||||
self.sponsor_text.render()
|
self.sponsor_text.render()
|
||||||
|
|
||||||
class SunnylinkLayoutMici(NavScroller):
|
class SunnylinkLayoutMici(NavScroller):
|
||||||
def __init__(self, back_callback: Callable):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.set_back_callback(back_callback)
|
|
||||||
self._restore_in_progress = False
|
self._restore_in_progress = False
|
||||||
self._backup_in_progress = False
|
self._backup_in_progress = False
|
||||||
self._sunnylink_enabled = ui_state.params.get("SunnylinkEnabled")
|
self._sunnylink_enabled = ui_state.params.get("SunnylinkEnabled")
|
||||||
|
|||||||
@@ -338,8 +338,11 @@ def build_mici_script(pm: PubMaster, main_layout, script: Script) -> None:
|
|||||||
|
|
||||||
settings_cases: Cases = [
|
settings_cases: Cases = [
|
||||||
lambda: scroll_through_cases(toggle_cases),
|
lambda: scroll_through_cases(toggle_cases),
|
||||||
|
None, # sunnylink (just open and close)
|
||||||
|
None, # models (just open and close)
|
||||||
lambda: scroll_through_cases(network_cases),
|
lambda: scroll_through_cases(network_cases),
|
||||||
lambda: scroll_through_cases(device_cases),
|
lambda: scroll_through_cases(device_cases),
|
||||||
|
lambda: script.wait(WAIT_SHORT), # software
|
||||||
lambda: script.wait(WAIT_SHORT), # pairing
|
lambda: script.wait(WAIT_SHORT), # pairing
|
||||||
lambda: run_actions(lambda: swipe_up(height * 3), lambda: swipe_down(height * 3)), # firehose (scroll down and back up)
|
lambda: run_actions(lambda: swipe_up(height * 3), lambda: swipe_down(height * 3)), # firehose (scroll down and back up)
|
||||||
lambda: scroll_through_cases(developer_cases),
|
lambda: scroll_through_cases(developer_cases),
|
||||||
|
|||||||
Reference in New Issue
Block a user