always offroad ui

This commit is contained in:
nayan
2026-02-13 18:09:50 -05:00
parent b62014eb12
commit ead6ccebae
10 changed files with 154 additions and 2 deletions

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e459241d896824f5e8207d568847acab3dedd41caae7af59d4c17e043663b0c9
size 4035

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:27a0fca872d4586f578d246890b83674cdb7ecb03f58b2b0379b4b64a5816053
size 3908

View File

@@ -13,7 +13,7 @@ from openpilot.system.ui.lib.application import gui_app
if gui_app.sunnypilot_ui():
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

View File

@@ -14,6 +14,9 @@ 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
if gui_app.sunnypilot_ui():
from openpilot.selfdrive.ui.sunnypilot.mici.layouts.settings_layouts.device import DeviceLayoutMiciSP as DeviceLayoutMici
class PanelType(IntEnum):
TOGGLES = 0

View File

@@ -0,0 +1,52 @@
import time
from cereal import log
import pyray as rl
from collections.abc import Callable
from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.widgets.label import gui_label, MiciLabel, UnifiedLabel
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_TEXT_COLOR, MousePos
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.text import wrap_text
from openpilot.system.version import training_version, RELEASE_BRANCHES
class MiciHomeLayoutSP(MiciHomeLayout):
def __init__(self):
super().__init__()
def _render_bottom_status_bar(self):
super()._render_bottom_status_bar()
ITEM_SPACING = 18
Y_CENTER = 28
if ui_state.always_offroad:
text = "always offroad"
font_size = 28
padding_x = 10
padding_y = 10
font = gui_app.font(FontWeight.BOLD)
# Measure text size
text_width = measure_text_cached(font, text, font_size).x
text_height = font_size
pos_x = self._rect.x + self.rect.width - ITEM_SPACING - text_width - 5
# Calculate rectangle dimensions
rect_width = text_width + padding_x * 2
rect_height = text_height + padding_y * 2
# Draw rounded rectangle background (red)
bg_rect = rl.Rectangle(pos_x, self._rect.y + self.rect.height - rect_height / 2 - Y_CENTER, rect_width,
rect_height)
rl.draw_rectangle_rounded(bg_rect, 0.5, 10, rl.Color(245, 56, 56, 175))
# Draw white text centered on the rectangle
text_x = pos_x + padding_x
text_y = self._rect.y + self.rect.height - rect_height / 2 - Y_CENTER + padding_y
rl.draw_text_ex(font, text, rl.Vector2(int(text_x), int(text_y)), font_size, 0, rl.WHITE)

View File

@@ -7,9 +7,12 @@ See the LICENSE.md file in the root directory for more details.
from enum import IntEnum
from openpilot.selfdrive.ui.mici.layouts.settings import settings as OP
from openpilot.selfdrive.ui.mici.widgets.button import BigButton
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigCircleButton
from openpilot.selfdrive.ui.mici.widgets.dialog import BigConfirmationDialogV2
from openpilot.selfdrive.ui.sunnypilot.mici.layouts.sunnylink import SunnylinkLayoutMici
from openpilot.selfdrive.ui.sunnypilot.mici.layouts.models import ModelsLayoutMici
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.application import gui_app
ICON_SIZE = 70
@@ -38,10 +41,30 @@ class SettingsLayoutSP(OP.SettingsLayout):
OP.PanelType.MODELS: OP.PanelInfo("models", ModelsLayoutMici(back_callback=lambda: self._set_current_panel(None))),
})
self.disable_always_offroad_btn = BigCircleButton("../../sunnypilot/selfdrive/assets/icons_mici/disable_offroad.png",
red=False, icon_size=(120, 120))
self.disable_always_offroad_btn.set_click_callback(self._disable_always_offroad)
items = self._scroller._items.copy()
items.insert(0, self.disable_always_offroad_btn)
items.insert(1, sunnylink_btn)
items.insert(2, models_btn)
self._scroller._items.clear()
for item in items:
self._scroller.add_widget(item)
def _update_state(self):
super()._update_state()
# Show "disable always offroad" button only when in always offroad mode
self.disable_always_offroad_btn.set_visible(ui_state.always_offroad)
def _disable_always_offroad(self):
def _do_disable():
ui_state.params.put_bool("OffroadMode", False)
self.disable_always_offroad_btn.set_visible(False)
dlg = BigConfirmationDialogV2(f"slide to exit always offroad", "icons_mici/settings/device/lkas.png",
red=True, confirm_callback=_do_disable)
gui_app.set_modal_overlay(dlg)

View File

@@ -0,0 +1,60 @@
from collections.abc import Callable
from openpilot.selfdrive.ui.mici.layouts.settings.device import DeviceLayoutMici
from openpilot.selfdrive.ui.mici.widgets.button import BigCircleButton
from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigConfirmationDialogV2
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.multilang import tr
class DeviceLayoutMiciSP(DeviceLayoutMici):
def __init__(self, back_callback: Callable):
super().__init__(back_callback)
self._enable_offroad = BigCircleButton("../../sunnypilot/selfdrive/assets/icons_mici/always_offroad.png",
red=True, icon_size=(120, 120))
self._enable_offroad.set_click_callback(self._handle_always_offroad)
self._disable_offroad = BigCircleButton("../../sunnypilot/selfdrive/assets/icons_mici/disable_offroad.png",
red=False, icon_size=(120, 120))
self._disable_offroad.set_click_callback(self._handle_always_offroad)
items = self._scroller._items.copy()
items.insert(len(self._scroller._items) - 2, self._enable_offroad)
items.insert(len(self._scroller._items) - 2, self._disable_offroad)
self._scroller._items.clear()
for item in items:
self._scroller.add_widget(item)
def _handle_always_offroad(self):
if ui_state.engaged:
gui_app.set_modal_overlay(BigDialog(tr("disengage"),tr("\nto enable always offroad")))
return
def _enable_always_offroad():
if not ui_state.engaged:
ui_state.params.put_bool("OffroadMode", True)
ui_state.always_offroad = True
def _disable_always_offroad():
ui_state.params.put_bool("OffroadMode", False)
ui_state.always_offroad = False
if ui_state.params.get_bool("OffroadMode"):
dlg = BigConfirmationDialogV2(f"slide to exit always offroad", "icons_mici/settings/device/lkas.png",
red=True, confirm_callback=_disable_always_offroad)
else:
dlg = BigConfirmationDialogV2(tr("slide to enable always offroad"), "icons_mici/settings/device/lkas.png",
red=True, confirm_callback=_enable_always_offroad)
gui_app.set_modal_overlay(dlg)
def _update_state(self):
super()._update_state()
# Handle Always Offroad buttons
always_offroad = ui_state.always_offroad
self._enable_offroad.set_visible(not always_offroad)
self._disable_offroad.set_visible(always_offroad)

View File

@@ -143,6 +143,8 @@ class UIStateSP:
self.true_v_ego_ui = self.params.get_bool("TrueVEgoUI")
self.turn_signals = self.params.get_bool("ShowTurnSignals")
self.boot_offroad_mode = self.params.get("DeviceBootMode", return_default=True)
self.always_offroad = self.params.get_bool("OffroadMode")
class DeviceSP:

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e459241d896824f5e8207d568847acab3dedd41caae7af59d4c17e043663b0c9
size 4035

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:27a0fca872d4586f578d246890b83674cdb7ecb03f58b2b0379b4b64a5816053
size 3908