f8e13417f2
date: 2026-08-15T14:20:10 master commit: d48cfa730bf21593b684efeaf3fd8940695e1dea
119 lines
3.4 KiB
Python
119 lines
3.4 KiB
Python
"""
|
|
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 os
|
|
import time
|
|
|
|
import pyray as rl
|
|
|
|
from openpilot.common.hardware import HARDWARE
|
|
from openpilot.common.params import Params
|
|
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, params: Params | None = None):
|
|
super().__init__()
|
|
self.set_rect(rl.Rectangle(0, 0, gui_app.width, gui_app.height))
|
|
self._params = params or Params()
|
|
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._screensaver_timeout = 300
|
|
self._hit_last_frame = False
|
|
|
|
@property
|
|
def is_active(self) -> bool:
|
|
return self._start_time is not None and not self._dismiss
|
|
|
|
@property
|
|
def was_dismissed(self) -> bool:
|
|
return self._dismiss
|
|
|
|
def initialize(self):
|
|
self._screensaver_timeout = self._params.get("ScreenSaverTimeout", return_default=True)
|
|
if self._start_time is None:
|
|
self._start_time = time.monotonic()
|
|
self._dismiss = False
|
|
|
|
def hide_event(self):
|
|
super().hide_event()
|
|
self._dismiss = False
|
|
self._start_time = None
|
|
|
|
def _handle_mouse_release(self, mouse_pos):
|
|
self._dismiss = True
|
|
self._start_time = None
|
|
gui_app.pop_widget()
|
|
return super()._handle_mouse_release(mouse_pos)
|
|
|
|
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._dismiss = True
|
|
self._start_time = None
|
|
|
|
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
|
|
|
|
hit = hit_x or hit_y
|
|
if hit and not self._hit_last_frame:
|
|
while self._hue_dist((new_hue := rl.get_random_value(0, 360)), self._hue) < 120:
|
|
pass
|
|
self._hue = new_hue
|
|
self.color = rl.color_from_hsv(self._hue, 1, 1)
|
|
self._hit_last_frame = hit
|
|
|
|
@staticmethod
|
|
def _hue_dist(a, b):
|
|
d = abs(a - b)
|
|
return min(d, 360 - d)
|
|
|
|
def _render(self, rect: rl.Rectangle):
|
|
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
|