Compare commits

...

91 Commits

Author SHA1 Message Date
nayan
acb4bb848b solve for lint 2026-04-12 23:06:56 -04:00
nayan
0cd913d7ac better 2026-04-12 22:57:41 -04:00
nayan
7fd1fea3b0 lint 2026-04-12 22:39:29 -04:00
nayan
e79c3243b2 fix 2026-04-12 19:24:27 -04:00
nayan
a936c311d7 Merge remote-tracking branch 'origin/master' into screensaver
# Conflicts:
#	selfdrive/ui/sunnypilot/layouts/settings/display.py
2026-04-12 19:21:05 -04:00
nayan
8e53fe176d better 2026-02-21 23:18:47 -05:00
nayan
22a12aec35 Merge remote-tracking branch 'origin/master' into screensaver
# Conflicts:
#	common/params_keys.h
#	selfdrive/ui/sunnypilot/layouts/settings/display.py
#	selfdrive/ui/sunnypilot/ui_state.py
#	selfdrive/ui/ui_state.py
2026-02-21 22:59:38 -05:00
nayan
426c2abd61 use ui_state param 2026-01-04 14:37:07 -05:00
Nayan
1a84559cec Merge branch 'master' into screensaver 2026-01-04 14:16:28 -05:00
nayan
65b61fd965 handle default 2026-01-03 14:01:28 -05:00
nayan
a01449822f Merge branch 'rl-display-panel' into screensaver 2026-01-03 13:34:08 -05:00
nayan
f52db76444 inline everything again 2026-01-03 13:31:56 -05:00
Nayan
b61f095ef2 Merge branch 'master' into rl-display-panel 2026-01-03 13:29:18 -05:00
DevTekVE
59e5fd7fe6 Merge branch 'master' into screensaver 2026-01-03 16:35:10 +01:00
Nayan
607811b6ad Merge branch 'master' into screensaver 2025-12-08 15:52:52 -05:00
nayan
2414fe287d fix 2025-12-08 15:13:26 -05:00
nayan
f7a4dbc47f changes 2025-12-07 12:53:18 -05:00
nayan
fd0a5f806c ugh 2025-12-05 14:23:25 -05:00
nayan
de62240e97 refresh controls 2025-12-05 13:41:35 -05:00
nayan
adba29da1b Merge remote-tracking branch 'origin/master' into rl-display-panel 2025-12-05 13:03:16 -05:00
nayan
6d6a91c318 really @devtekve? REALLY?? 2025-12-04 17:38:16 -05:00
nayan
7259687578 it wasn't me 2025-12-04 17:31:34 -05:00
nayan
83a07e4bfa we doing this now @devtekve? FINE!! 2025-12-04 15:44:04 -05:00
nayan
cb65777186 not doing this 2025-12-04 15:36:12 -05:00
Nayan
282b867fcb Merge branch 'master' into screensaver 2025-12-04 15:34:36 -05:00
nayan
3fd3c31966 add toggle 2025-12-04 15:33:45 -05:00
nayan
f3c3581472 Merge branch 'rl-display-panel' into screensaver 2025-12-04 15:08:28 -05:00
nayan
465daf323c add param, timeout 2025-12-04 15:03:31 -05:00
nayan
3fe8e155b6 better 2025-12-03 23:15:11 -05:00
nayan
c0bffa2a8c oops 2025-12-03 22:57:14 -05:00
nayan
c9edcaa1a6 why? because! 2025-12-03 22:48:17 -05:00
DevTekVE
76101207cb Removed hide for now 2025-11-30 12:51:16 +01:00
DevTekVE
62b01d3799 Merge branch 'master' into rl-display-panel
# Conflicts:
#	selfdrive/ui/layouts/main.py
#	selfdrive/ui/layouts/settings/toggles.py
#	selfdrive/ui/sunnypilot/layouts/settings/cruise.py
#	selfdrive/ui/sunnypilot/layouts/settings/device.py
#	selfdrive/ui/sunnypilot/layouts/settings/display.py
#	selfdrive/ui/sunnypilot/layouts/settings/models.py
#	selfdrive/ui/sunnypilot/layouts/settings/navigation.py
#	selfdrive/ui/sunnypilot/layouts/settings/osm.py
#	selfdrive/ui/sunnypilot/layouts/settings/settings.py
#	selfdrive/ui/sunnypilot/layouts/settings/steering.py
#	selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py
#	selfdrive/ui/sunnypilot/layouts/settings/trips.py
#	selfdrive/ui/sunnypilot/layouts/settings/vehicle.py
#	selfdrive/ui/sunnypilot/layouts/settings/visuals.py
#	selfdrive/ui/sunnypilot/ui_state.py
#	selfdrive/ui/tests/test_ui/raylib_screenshots.py
#	system/ui/sunnypilot/lib/application.py
#	system/ui/sunnypilot/lib/styles.py
#	system/ui/sunnypilot/widgets/list_view.py
#	system/ui/sunnypilot/widgets/option_control.py
#	system/ui/sunnypilot/widgets/toggle.py
2025-11-30 12:50:39 +01:00
nayan
a3be1edde7 optimizations 2025-11-22 23:48:06 -05:00
nayan
7869542683 Merge branch 'py-ui-state-sp' into rl-display-panel 2025-11-21 18:16:47 -05:00
nayan
981aab0500 Merge branch 'rl-sp-panels' into rl-display-panel 2025-11-21 18:16:43 -05:00
nayan
9c82592906 Merge branch 'rl-sp-toggles' into rl-display-panel 2025-11-21 18:16:40 -05:00
nayan
5d3f95d420 use gui_app.sunnypilot_ui() 2025-11-21 18:08:19 -05:00
nayan
f8d19fe9dd Merge branch 'rl-sp-toggles' into rl-sp-panels 2025-11-21 18:07:19 -05:00
nayan
9d711350c2 Merge remote-tracking branch 'origin/ui-gui-app-ext' into rl-sp-panels 2025-11-21 18:07:03 -05:00
nayan
45c853c87a Merge remote-tracking branch 'origin/ui-gui-app-ext' into py-ui-state-sp 2025-11-21 17:57:35 -05:00
nayan
e8ab9d812d use gui_app.sunnypilot_ui() 2025-11-21 17:57:06 -05:00
nayan
ed775185f2 use gui_app.sunnypilot_ui() 2025-11-21 17:49:27 -05:00
nayan
7bbbc6588e Merge remote-tracking branch 'origin/ui-gui-app-ext' into rl-sp-toggles 2025-11-21 17:42:23 -05:00
nayan
e68c65d15d Merge remote-tracking branch 'origin/master' into rl-sp-toggles 2025-11-21 17:40:10 -05:00
Jason Wen
0db8722221 Merge branch 'master' into ui-gui-app-ext 2025-11-21 17:24:14 -05:00
Jason Wen
a33497ed19 add to readme 2025-11-21 16:42:59 -05:00
Jason Wen
91f2bf3459 ui: GuiApplicationExt 2025-11-21 16:23:01 -05:00
Jason Wen
7fad2fc189 Merge branch 'master' into rl-sp-toggles 2025-11-21 15:55:34 -05:00
nayan
e74252bdf5 Merge remote-tracking branch 'origin/master' into py-ui-state-sp 2025-11-21 15:37:33 -05:00
nayan
6b795ab513 Merge branch 'rl-sp-panels' into rl-display-panel
# Conflicts:
#	selfdrive/ui/sunnypilot/layouts/settings/display.py
2025-11-21 15:30:40 -05:00
nayan
3b1b4ef90f Merge remote-tracking branch 'origin/master' into rl-display-panel 2025-11-21 15:30:13 -05:00
nayan
48d33e98e7 scroller -> scroller_tici 2025-11-21 15:27:51 -05:00
nayan
2717d97350 scroller -> scroller_tici 2025-11-21 15:20:31 -05:00
nayan
64232397ed Merge remote-tracking branch 'origin/master' into rl-sp-panels 2025-11-21 15:16:50 -05:00
Jason Wen
0613442ac9 Merge branch 'master' into rl-sp-toggles 2025-11-21 15:00:14 -05:00
nayan
93ab6ee06b lint 2025-11-20 23:49:57 -05:00
nayan
4baa170cfa hide all controls 2025-11-20 23:46:16 -05:00
nayan
2be95225b1 add all controls 2025-11-20 23:41:15 -05:00
nayan
f8e8c59dd5 option control value fix 2025-11-20 23:34:24 -05:00
nayan
dd9d4bedf4 init 2025-11-20 22:58:55 -05:00
nayan
ada449989b Merge branch 'rl-sp-optioncontrol' into rl-display-panel 2025-11-20 22:43:51 -05:00
nayan
68c7f69439 AAARGGGGGG..... 2025-11-20 22:18:04 -05:00
nayan
1db71aff57 I. SAID. SIMPLIFY. 2025-11-20 22:15:43 -05:00
nayan
942ccb90dd simplify 2025-11-20 22:08:06 -05:00
nayan
e6f5aae246 remove padding from line separator.
like, WHY? 😩😩
2025-11-20 18:05:12 -05:00
nayan
7032e4a972 add show_description method 2025-11-20 18:00:44 -05:00
nayan
ffa78eabaa Revert "add ui_update callback"
This reverts commit 4da32cc009.
2025-11-20 17:58:19 -05:00
nayan
5b03369a8f listitem -> listitemsp 2025-11-20 17:56:26 -05:00
nayan
1e0564b484 this 2025-11-20 08:05:20 -05:00
nayan
eb94abaa14 better padding 2025-11-19 23:44:05 -05:00
nayan
4da32cc009 add ui_update callback 2025-11-19 23:03:56 -05:00
nayan
4820265268 better 2025-11-18 19:09:46 -05:00
nayan
01aa6c4204 param to control stock vs sp ui 2025-11-18 18:51:52 -05:00
nayan
21beea51ec introducing ui_state_sp for py 2025-11-18 16:26:48 -05:00
nayan
98c479830c Need this 2025-11-16 14:00:37 -05:00
nayan
5369b6880f Option Control 2025-11-16 13:58:14 -05:00
nayan
a9e57f0a76 add ui previews 2025-11-16 12:47:37 -05:00
nayan
712a358c94 Merge branch 'rl-sp-toggles' into rl-sp-panels 2025-11-16 11:23:31 -05:00
nayan
423a7d2ed0 fix ui preview 2025-11-16 11:15:28 -05:00
nayan
e4e10d4b87 fix callback 2025-11-16 11:15:22 -05:00
nayan
632e9d13b2 Merge branch 'rl-sp-toggles' into rl-sp-panels 2025-11-16 09:55:25 -05:00
nayan
362e9ce04b sp raylib preview 2025-11-16 09:53:28 -05:00
nayan
51d0666c85 more patience, grasshopper 2025-11-16 09:33:35 -05:00
nayan
deda1329a2 patience, grasshopper 2025-11-16 09:33:35 -05:00
nayan
4110749cb0 Panels. With Icons. And Scroller. 2025-11-16 09:33:35 -05:00
nayan
3946e643f6 optimizations 2025-11-16 09:29:58 -05:00
nayan
0c37a38596 Lint 2025-11-16 09:29:58 -05:00
nayan
9c5acf61c0 SP Toggles 2025-11-16 09:29:58 -05:00
nayan
121b304fe0 init styles 2025-11-16 09:29:58 -05:00
nayan
47d848293b param to control stock vs sp ui 2025-11-16 09:29:58 -05:00
6 changed files with 160 additions and 7 deletions

View File

@@ -179,6 +179,8 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"QuietMode", {PERSISTENT | BACKUP, BOOL, "0"}},
{"RainbowMode", {PERSISTENT | BACKUP, BOOL, "0"}},
{"RocketFuel", {PERSISTENT | BACKUP, BOOL, "0"}},
{"ScreenSaverEnabled", {PERSISTENT | BACKUP, BOOL, "0"}},
{"ScreenSaverTimeout", {PERSISTENT | BACKUP, INT, "300"}},
{"ShowAdvancedControls", {PERSISTENT | BACKUP, BOOL, "0"}},
{"ShowTurnSignals", {PERSISTENT | BACKUP, BOOL, "0"}},
{"StandstillTimer", {PERSISTENT | BACKUP, BOOL, "0"}},

View File

@@ -11,7 +11,7 @@ from openpilot.system.ui.sunnypilot.widgets.option_control import OptionControlS
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.widgets.scroller_tici import Scroller
from openpilot.system.ui.sunnypilot.widgets.list_view import option_item_sp, ToggleActionSP
from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp, option_item_sp, ToggleActionSP
from openpilot.sunnypilot.system.params_migration import ONROAD_BRIGHTNESS_TIMER_VALUES
@@ -64,10 +64,27 @@ class DisplayLayout(Widget):
f"{value} s" if value < 60 else f"{int(value/60)} m"),
inline=True
)
self._screensaver_toggle = toggle_item_sp(
param="ScreenSaverEnabled",
title=lambda: tr("Enable sunnypilot Screen Saver"),
description=lambda: tr("Enable screen saver when the device is offroad & idle. " +
"The screen saver will kick off after the interactivity timeout expires, and will stay on for the duration configured below."),
)
self._screensaver_timeout = option_item_sp(
param="ScreenSaverTimeout",
title=lambda: tr("Screen Saver Timeout"),
description=lambda: tr("Configure how long the screen saver should stay on after the interactivity timeout expires."),
min_value=60,
max_value=600,
value_change_step=60,
label_callback=lambda value: f"{int(value/60)} m"
)
items = [
self._onroad_brightness,
self._onroad_brightness_timer,
self._interactivity_timeout,
self._screensaver_toggle,
self._screensaver_timeout,
]
return items
@@ -100,6 +117,8 @@ class DisplayLayout(Widget):
brightness_val = self._params.get("OnroadScreenOffBrightness", return_default=True)
self._onroad_brightness_timer.action_item.set_enabled(brightness_val not in (OnroadBrightness.AUTO, OnroadBrightness.AUTO_DARK))
self._screensaver_timeout.set_visible(self._screensaver_toggle.action_item.get_state())
def _render(self, rect):
self._scroller.render(rect)

View File

@@ -11,6 +11,7 @@ from openpilot.common.params import Params
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.display import OnroadBrightness
from openpilot.sunnypilot.sunnylink.sunnylink_state import SunnylinkState
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.sunnypilot.widgets.screen_saver import ScreenSaverSP
OpenpilotState = log.SelfdriveState.OpenpilotState
MADSState = custom.ModularAssistiveDrivingSystem.ModularAssistiveDrivingSystemState
@@ -34,6 +35,8 @@ class UIStateSP:
]
self.sunnylink_state = SunnylinkState()
self.screensaver = ScreenSaverSP()
self.update_params()
self.onroad_brightness_timer: int = 0
@@ -146,14 +149,27 @@ 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.screensaver_enabled = self.params.get_bool("ScreenSaverEnabled")
class DeviceSP:
@staticmethod
def _set_awake(on: bool, _ui_state):
def _set_awake(_device, on: bool, _ui_state):
if _ui_state.boot_offroad_mode == 1 and not on:
_ui_state.params.put_bool("OffroadMode", True)
if not on and _ui_state.screensaver_enabled:
if _ui_state.screensaver.was_dismissed:
_ui_state.screensaver.deinit()
gui_app.pop_widget()
return True
else:
_ui_state.screensaver.initialize(dismiss_callback=lambda: _device._set_awake(False))
gui_app.push_widget(_ui_state.screensaver)
return False
return True
@staticmethod
def set_onroad_brightness(_ui_state, awake: bool, cur_brightness: float) -> float:
if not awake or not _ui_state.started:

View File

@@ -299,11 +299,11 @@ class Device(DeviceSP):
def _set_awake(self, on: bool):
if on != self._awake:
DeviceSP._set_awake(on, ui_state)
self._awake = on
cloudlog.debug(f"setting display power {int(on)}")
HARDWARE.set_display_power(on)
gui_app.set_should_render(on)
if DeviceSP._set_awake(self, on, ui_state):
self._awake = on
cloudlog.debug(f"setting display power {int(on)}")
HARDWARE.set_display_power(on)
gui_app.set_should_render(on)
# Global instance

View File

@@ -1126,6 +1126,14 @@
"title": "Route Count",
"description": ""
},
"ScreenSaverEnabled": {
"title": "Enable Screen Saver",
"description": ""
},
"ScreenSaverTimeout": {
"title": "Screen Saver Timeout",
"description": ""
},
"SecOCKey": {
"title": "Sec Oc Key",
"description": ""

View File

@@ -0,0 +1,108 @@
import os
import time
from collections.abc import Callable
import pyray as rl
from openpilot.common.params import Params
from openpilot.system.hardware import HARDWARE
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.widgets import Widget
class ScreenSaverSP(Widget):
def __init__(self):
super().__init__()
self.set_rect(rl.Rectangle(0, 0, gui_app.width, gui_app.height))
self.screensaver_timeout = Params().get("ScreenSaverTimeout", return_default=True)
self._is_mici = HARDWARE.get_device_type() == 'mici' or (HARDWARE.get_device_type() == "pc" and os.getenv("BIG") != "1")
self.x = 0.0
self.y = 100.0
self.vx = 120.0 if self._is_mici else 300.0
self.vy = 70.0 if self._is_mici else 200.0
self._hue = 150
self.color = rl.color_from_hsv(self._hue, 1, 1)
self.text = "sunnypilot"
self.font_size = 50 if self._is_mici else 200
self._start_time = None
self._dismiss = False
self.dismiss_callback = None
@property
def was_dismissed(self) -> bool:
return self._dismiss
def initialize(self, dismiss_callback: Callable):
if self._start_time is None:
self._start_time = time.monotonic()
self.dismiss_callback = dismiss_callback
self._dismiss = False
def deinit(self):
self._dismiss = False
self._start_time = None
def _handle_mouse_press(self, mouse_pos):
self._reset()
return super()._handle_mouse_press(mouse_pos)
def _reset(self):
self._dismiss = True
self._start_time = None
def _update_state(self):
super()._update_state()
self.font = gui_app.font(FontWeight.AUDIOWIDE)
text_size = measure_text_cached(self.font, self.text, self.font_size, 0)
self.logo_width = text_size.x
self.logo_height = text_size.y
if self._start_time and time.monotonic() - self._start_time > self.screensaver_timeout:
self._reset()
dt = rl.get_frame_time()
self.x += self.vx * dt
self.y += self.vy * dt
hit_x = hit_y = False
if self.x + self.logo_width > self.rect.width:
self.vx *= -1
self.x = self.rect.width - self.logo_width
hit_x = True
elif self.x < 0:
self.vx *= -1
self.x = 0
hit_x = True
if self.y + self.logo_height > self.rect.height:
self.vy *= -1
self.y = self.rect.height - self.logo_height
hit_y = True
elif self.y < 0:
self.vy *= -1
self.y = 0
hit_y = True
def hue_dist(a, b):
d = abs(a - b)
return min(d, 360 - d)
if hit_x or hit_y:
while hue_dist((new_hue := rl.get_random_value(0, 360)), self._hue) < 90:
pass
self._hue = new_hue
self.color = rl.color_from_hsv(self._hue, 1, 1)
def _render(self, rect: rl.Rectangle):
if self._dismiss:
self.dismiss_callback()
return 0
self.set_rect(rect)
rl.clear_background(rl.BLACK)
rl.draw_text_ex(self.font, self.text, rl.Vector2(int(self.x), int(self.y)), self.font_size, 0, self.color)
return -1