format raylib (#35483)

* format raylib

* not really sure what this is
pull/35487/head
Shane Smiskol 5 days ago committed by GitHub
parent 541bd4d4d9
commit 29830440b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      selfdrive/ui/layouts/home.py
  2. 2
      selfdrive/ui/layouts/settings/developer.py
  3. 1
      selfdrive/ui/layouts/settings/software.py
  4. 2
      selfdrive/ui/layouts/settings/toggles.py
  5. 6
      selfdrive/ui/layouts/sidebar.py
  6. 4
      selfdrive/ui/onroad/alert_renderer.py
  7. 7
      selfdrive/ui/onroad/augmented_road_view.py
  8. 49
      selfdrive/ui/onroad/cameraview.py
  9. 35
      selfdrive/ui/onroad/driver_state.py
  10. 13
      selfdrive/ui/onroad/model_renderer.py
  11. 3
      selfdrive/ui/ui.py
  12. 1
      selfdrive/ui/ui_state.py
  13. 1
      selfdrive/ui/widgets/offroad_alerts.py
  14. 4
      system/ui/lib/application.py
  15. 1
      system/ui/lib/button.py
  16. 2
      system/ui/lib/egl.py
  17. 11
      system/ui/lib/inputbox.py
  18. 1
      system/ui/lib/label.py
  19. 1
      system/ui/lib/list_view.py
  20. 2
      system/ui/lib/shader_polygon.py
  21. 6
      system/ui/lib/wifi_manager.py
  22. 1
      system/ui/lib/wrap_text.py
  23. 2
      system/ui/reset.py
  24. 1
      system/ui/spinner.py
  25. 2
      system/ui/text.py
  26. 5
      system/ui/updater.py
  27. 4
      system/ui/widgets/keyboard.py
  28. 20
      system/ui/widgets/network.py

@ -8,7 +8,6 @@ from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.label import gui_label
from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_TEXT_COLOR
HEADER_HEIGHT = 80
HEAD_BUTTON_FONT_SIZE = 40
CONTENT_MARGIN = 40

@ -1,4 +1,4 @@
from openpilot.system.ui.lib.list_view import ListView, toggle_item
from openpilot.system.ui.lib.list_view import ListView, toggle_item
from openpilot.common.params import Params
# Description constants

@ -1,5 +1,6 @@
from openpilot.system.ui.lib.list_view import ListView, button_item, text_item
class SoftwareLayout:
def __init__(self):
items = [

@ -10,7 +10,7 @@ DESCRIPTIONS = {
"DisengageOnAccelerator": "When enabled, pressing the accelerator pedal will disengage openpilot.",
"IsLdwEnabled": (
"Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line " +
"without a turn signal activated while driving over 31 mph (50 km/h)."
"without a turn signal activated while driving over 31 mph (50 km/h)."
),
"AlwaysOnDM": "Enable driver monitoring even when openpilot is not engaged.",
'RecordFront': "Upload data from the driver facing camera and help improve the driver monitoring algorithm.",

@ -18,6 +18,7 @@ HOME_BTN = rl.Rectangle(60, 860, 180, 180)
ThermalStatus = log.DeviceState.ThermalStatus
NetworkType = log.DeviceState.NetworkType
# Color scheme
class Colors:
SIDEBAR_BG = rl.Color(57, 57, 57, 255)
@ -35,6 +36,7 @@ class Colors:
BUTTON_NORMAL = rl.Color(255, 255, 255, 255)
BUTTON_PRESSED = rl.Color(255, 255, 255, 166)
NETWORK_TYPES = {
NetworkType.none: "Offline",
NetworkType.wifi: "WiFi",
@ -57,6 +59,7 @@ class MetricData:
self.value = value
self.color = color
class Sidebar:
def __init__(self):
self._net_type = NETWORK_TYPES.get(NetworkType.none)
@ -72,7 +75,7 @@ class Sidebar:
self._font_regular = gui_app.font(FontWeight.NORMAL)
self._font_bold = gui_app.font(FontWeight.SEMI_BOLD)
# Callbacks
# Callbacks
self._on_settings_click: Callable | None = None
self._on_flag_click: Callable | None = None
@ -150,7 +153,6 @@ class Sidebar:
mouse_pos = rl.get_mouse_position()
mouse_down = rl.is_mouse_button_down(rl.MouseButton.MOUSE_BUTTON_LEFT)
# Settings button
settings_down = mouse_down and rl.check_collision_point_rec(mouse_pos, SETTINGS_BTN)
tint = Colors.BUTTON_PRESSED if settings_down else Colors.BUTTON_NORMAL

@ -8,7 +8,6 @@ from openpilot.system.ui.lib.label import gui_text_box
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.selfdrive.ui.ui_state import ui_state
ALERT_MARGIN = 40
ALERT_PADDING = 60
ALERT_LINE_SPACING = 45
@ -21,7 +20,6 @@ ALERT_FONT_BIG = 88
SELFDRIVE_STATE_TIMEOUT = 5 # Seconds
SELFDRIVE_UNRESPONSIVE_TIMEOUT = 10 # Seconds
# Constants
ALERT_COLORS = {
log.SelfdriveState.AlertStatus.normal: rl.Color(0, 0, 0, 235), # Black
@ -114,7 +112,7 @@ class AlertRenderer:
return rect
height = (ALERT_FONT_MEDIUM + 2 * ALERT_PADDING if size == log.SelfdriveState.AlertSize.small else
ALERT_FONT_BIG + ALERT_LINE_SPACING + ALERT_FONT_SMALL + 2 * ALERT_PADDING)
ALERT_FONT_BIG + ALERT_LINE_SPACING + ALERT_FONT_SMALL + 2 * ALERT_PADDING)
return rl.Rectangle(
rect.x + ALERT_MARGIN,

@ -13,7 +13,6 @@ from openpilot.system.ui.lib.application import gui_app
from openpilot.common.transformations.camera import DEVICE_CAMERAS, DeviceCameraConfig, view_frame_from_device_frame
from openpilot.common.transformations.orientation import rot_from_euler
OpState = log.SelfdriveState.OpenpilotState
CALIBRATED = log.LiveCalibrationData.Status.calibrated
ROAD_CAM = VisionStreamType.VISION_STREAM_ROAD
@ -170,9 +169,9 @@ class AugmentedRoadView(CameraView):
])
video_transform = np.array([
[zoom, 0.0, (w / 2 + x - x_offset) - (cx * zoom)],
[0.0, zoom, (h / 2 + y - y_offset) - (cy * zoom)],
[0.0, 0.0, 1.0]
[zoom, 0.0, (w / 2 + x - x_offset) - (cx * zoom)],
[0.0, zoom, (h / 2 + y - y_offset) - (cy * zoom)],
[0.0, 0.0, 1.0]
])
self.model_renderer.set_transform(video_transform @ calib_transform)

@ -7,7 +7,6 @@ from openpilot.common.swaglog import cloudlog
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.egl import init_egl, create_egl_image, destroy_egl_image, bind_egl_image_to_texture, EGLImage
CONNECTION_RETRY_INTERVAL = 0.2 # seconds between connection attempts
VERTEX_SHADER = """
@ -55,6 +54,7 @@ else:
}
"""
class CameraView:
def __init__(self, name: str, stream_type: VisionStreamType):
self._name = name
@ -68,7 +68,6 @@ class CameraView:
self._target_stream_type: VisionStreamType | None = None
self._switching: bool = False
self._texture_needs_update = True
self.last_connection_attempt: float = 0.0
self.shader = rl.load_shader_from_memory(VERTEX_SHADER, FRAME_FRAGMENT_SHADER)
@ -82,7 +81,7 @@ class CameraView:
self.egl_images: dict[int, EGLImage] = {}
self.egl_texture: rl.Texture | None = None
self._placeholder_color : rl.Color | None = None
self._placeholder_color: rl.Color | None = None
# Initialize EGL for zero-copy rendering on TICI
if TICI:
@ -145,9 +144,9 @@ class CameraView:
zy = min(widget_aspect_ratio / frame_aspect_ratio, 1.0)
return np.array([
[zx, 0.0, 0.0],
[0.0, zy, 0.0],
[0.0, 0.0, 1.0]
[zx, 0.0, 0.0],
[0.0, zy, 0.0],
[0.0, 0.0, 1.0]
])
def render(self, rect: rl.Rectangle):
@ -230,7 +229,7 @@ class CameraView:
# Update textures with new frame data
if self._texture_needs_update:
y_data = self.frame.data[: self.frame.uv_offset]
uv_data = self.frame.data[self.frame.uv_offset :]
uv_data = self.frame.data[self.frame.uv_offset:]
rl.update_texture(self.texture_y, rl.ffi.cast("void *", y_data.ctypes.data))
rl.update_texture(self.texture_uv, rl.ffi.cast("void *", uv_data.ctypes.data))
@ -265,7 +264,7 @@ class CameraView:
def _handle_switch(self) -> None:
"""Check if target stream is ready and switch immediately."""
if not self._target_client or not self._switching:
return
return
# Try to connect target if needed
if not self._target_client.is_connected():
@ -277,28 +276,28 @@ class CameraView:
# Check if target has frames ready
target_frame = self._target_client.recv(timeout_ms=0)
if target_frame:
self.frame = target_frame # Update current frame to target frame
self.frame = target_frame # Update current frame to target frame
self._complete_switch()
def _complete_switch(self) -> None:
"""Instantly switch to target stream."""
cloudlog.debug(f"Switching to {self._target_stream_type}")
# Clean up current resources
if self.client:
del self.client
# Switch to target
self.client = self._target_client
self._stream_type = self._target_stream_type
self._texture_needs_update = True
"""Instantly switch to target stream."""
cloudlog.debug(f"Switching to {self._target_stream_type}")
# Clean up current resources
if self.client:
del self.client
# Switch to target
self.client = self._target_client
self._stream_type = self._target_stream_type
self._texture_needs_update = True
# Reset state
self._target_client = None
self._target_stream_type = None
self._switching = False
# Reset state
self._target_client = None
self._target_stream_type = None
self._switching = False
# Initialize textures for new stream
self._initialize_textures()
# Initialize textures for new stream
self._initialize_textures()
def _initialize_textures(self):
self._clear_textures()

@ -4,18 +4,17 @@ from dataclasses import dataclass
from openpilot.selfdrive.ui.ui_state import ui_state, UI_BORDER_SIZE
from openpilot.system.ui.lib.application import gui_app
# Default 3D coordinates for face keypoints as a NumPy array
DEFAULT_FACE_KPTS_3D = np.array([
[-5.98, -51.20, 8.00], [-17.64, -49.14, 8.00], [-23.81, -46.40, 8.00], [-29.98, -40.91, 8.00],
[-32.04, -37.49, 8.00], [-34.10, -32.00, 8.00], [-36.16, -21.03, 8.00], [-36.16, 6.40, 8.00],
[-35.47, 10.51, 8.00], [-32.73, 19.43, 8.00], [-29.30, 26.29, 8.00], [-24.50, 33.83, 8.00],
[-19.01, 41.37, 8.00], [-14.21, 46.17, 8.00], [-12.16, 47.54, 8.00], [-4.61, 49.60, 8.00],
[4.99, 49.60, 8.00], [12.53, 47.54, 8.00], [14.59, 46.17, 8.00], [19.39, 41.37, 8.00],
[24.87, 33.83, 8.00], [29.67, 26.29, 8.00], [33.10, 19.43, 8.00], [35.84, 10.51, 8.00],
[36.53, 6.40, 8.00], [36.53, -21.03, 8.00], [34.47, -32.00, 8.00], [32.42, -37.49, 8.00],
[30.36, -40.91, 8.00], [24.19, -46.40, 8.00], [18.02, -49.14, 8.00], [6.36, -51.20, 8.00],
[-5.98, -51.20, 8.00],
[-5.98, -51.20, 8.00], [-17.64, -49.14, 8.00], [-23.81, -46.40, 8.00], [-29.98, -40.91, 8.00],
[-32.04, -37.49, 8.00], [-34.10, -32.00, 8.00], [-36.16, -21.03, 8.00], [-36.16, 6.40, 8.00],
[-35.47, 10.51, 8.00], [-32.73, 19.43, 8.00], [-29.30, 26.29, 8.00], [-24.50, 33.83, 8.00],
[-19.01, 41.37, 8.00], [-14.21, 46.17, 8.00], [-12.16, 47.54, 8.00], [-4.61, 49.60, 8.00],
[4.99, 49.60, 8.00], [12.53, 47.54, 8.00], [14.59, 46.17, 8.00], [19.39, 41.37, 8.00],
[24.87, 33.83, 8.00], [29.67, 26.29, 8.00], [33.10, 19.43, 8.00], [35.84, 10.51, 8.00],
[36.53, 6.40, 8.00], [36.53, -21.03, 8.00], [34.47, -32.00, 8.00], [32.42, -37.49, 8.00],
[30.36, -40.91, 8.00], [24.19, -46.40, 8.00], [18.02, -49.14, 8.00], [6.36, -51.20, 8.00],
[-5.98, -51.20, 8.00],
], dtype=np.float32)
# UI constants
@ -31,6 +30,7 @@ SCALES_NEG = np.array([0.7, 0.4, 0.4], dtype=np.float32)
ARC_POINT_COUNT = 37 # Number of points in the arc
ARC_ANGLES = np.linspace(0.0, np.pi, ARC_POINT_COUNT, dtype=np.float32)
@dataclass
class ArcData:
"""Data structure for arc rendering parameters."""
@ -40,6 +40,7 @@ class ArcData:
height: float
thickness: float
class DriverStateRenderer:
def __init__(self):
# Initial state with NumPy arrays
@ -113,9 +114,9 @@ class DriverStateRenderer:
def _update_state(self, sm, rect):
"""Update the driver monitoring state based on model data"""
if not sm.updated["driverMonitoringState"]:
if self.state_updated and (rect.x != self.last_rect.x or rect.y != self.last_rect.y or \
rect.width != self.last_rect.width or rect.height != self.last_rect.height):
if not sm.updated["driverMonitoringState"]:
if self.state_updated and (rect.x != self.last_rect.x or rect.y != self.last_rect.y or
rect.width != self.last_rect.width or rect.height != self.last_rect.height):
self._pre_calculate_drawing_elements(rect)
return
@ -189,15 +190,15 @@ class DriverStateRenderer:
# Horizontal arc
h_width = abs(delta_x)
self.h_arc_data = self._calculate_arc_data(
delta_x, h_width, self.position_x, self.position_y - ARC_LENGTH / 2,
self.driver_pose_sins[1], self.driver_pose_diff[1], is_horizontal=True
delta_x, h_width, self.position_x, self.position_y - ARC_LENGTH / 2,
self.driver_pose_sins[1], self.driver_pose_diff[1], is_horizontal=True
)
# Vertical arc
v_height = abs(delta_y)
self.v_arc_data = self._calculate_arc_data(
delta_y, v_height, self.position_x - ARC_LENGTH / 2, self.position_y,
self.driver_pose_sins[0], self.driver_pose_diff[0], is_horizontal=False
delta_y, v_height, self.position_x - ARC_LENGTH / 2, self.position_y,
self.driver_pose_sins[0], self.driver_pose_diff[0], is_horizontal=False
)
def _calculate_arc_data(

@ -9,7 +9,6 @@ from openpilot.system.ui.lib.application import DEFAULT_FPS
from openpilot.system.ui.lib.shader_polygon import draw_polygon
from openpilot.selfdrive.locationd.calibrationd import HEIGHT_INIT
CLIP_MARGIN = 500
MIN_DRAW_DISTANCE = 10.0
MAX_DRAW_DISTANCE = 100.0
@ -36,6 +35,7 @@ class ModelPoints:
raw_points: np.ndarray = field(default_factory=lambda: np.empty((0, 3), dtype=np.float32))
projected_points: np.ndarray = field(default_factory=lambda: np.empty((0, 2), dtype=np.float32))
@dataclass
class LeadVehicle:
glow: list[float] = field(default_factory=list)
@ -127,7 +127,6 @@ class ModelRenderer:
self._update_leads(radar_state, path_x_array)
self._transform_dirty = False
# Draw elements
self._draw_lane_lines()
self._draw_path(sm)
@ -256,7 +255,7 @@ class ModelRenderer:
glow = [(x + (sz * 1.35) + g_xo, y + sz + g_yo), (x, y - g_yo), (x - (sz * 1.35) - g_xo, y + sz + g_yo)]
chevron = [(x + (sz * 1.25), y + sz), (x, y), (x - (sz * 1.25), y + sz)]
return LeadVehicle(glow=glow,chevron=chevron, fill_alpha=int(fill_alpha))
return LeadVehicle(glow=glow, chevron=chevron, fill_alpha=int(fill_alpha))
def _draw_lane_lines(self):
"""Draw lane lines and road edges"""
@ -417,10 +416,10 @@ class ModelRenderer:
def _hsla_to_color(h, s, l, a):
rgb = colorsys.hls_to_rgb(h, l, s)
return rl.Color(
int(rgb[0] * 255),
int(rgb[1] * 255),
int(rgb[2] * 255),
int(a * 255)
int(rgb[0] * 255),
int(rgb[1] * 255),
int(rgb[2] * 255),
int(a * 255)
)
@staticmethod

@ -6,14 +6,13 @@ from openpilot.selfdrive.ui.layouts.main import MainLayout
from openpilot.selfdrive.ui.ui_state import ui_state
def main():
gui_app.init_window("UI")
main_layout = MainLayout()
for _ in gui_app.render():
ui_state.update()
#TODO handle brigntness and awake state here
# TODO handle brigntness and awake state here
main_layout.render(rl.Rectangle(0, 0, gui_app.width, gui_app.height))

@ -3,7 +3,6 @@ from enum import Enum
from cereal import messaging, log
from openpilot.common.params import Params, UnknownKeyName
UI_BORDER_SIZE = 30

@ -10,6 +10,7 @@ from openpilot.system.ui.lib.wrap_text import wrap_text
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.application import gui_app, FontWeight
class AlertColors:
HIGH_SEVERITY = rl.Color(226, 44, 44, 255)
LOW_SEVERITY = rl.Color(41, 41, 41, 255)

@ -43,6 +43,7 @@ class ModalOverlay:
overlay: object = None
callback: Callable | None = None
class GuiApplication:
def __init__(self, width: int, height: int):
self._fonts: dict[FontWeight, rl.Font] = {}
@ -59,7 +60,6 @@ class GuiApplication:
self._trace_log_callback = None
self._modal_overlay = ModalOverlay()
def request_close(self):
self._window_close_requested = True
@ -167,7 +167,7 @@ class GuiApplication:
elif callable(self._modal_overlay.overlay):
result = self._modal_overlay.overlay()
else:
assert(0)
raise Exception
if result >= 0 and self._modal_overlay.callback is not None:
# Execute callback with the result and clear the overlay

@ -25,7 +25,6 @@ BUTTON_DISABLED_TEXT_COLOR = rl.Color(228, 228, 228, 51)
ACTION_BUTTON_FONT_SIZE = 48
ACTION_BUTTON_TEXT_COLOR = rl.Color(0, 0, 0, 255)
BUTTON_BACKGROUND_COLORS = {
ButtonStyle.NORMAL: rl.Color(51, 51, 51, 255),
ButtonStyle.PRIMARY: rl.Color(70, 91, 234, 255),

@ -4,7 +4,6 @@ from dataclasses import dataclass
from typing import Any
from openpilot.common.swaglog import cloudlog
# EGL constants
EGL_LINUX_DMA_BUF_EXT = 0x3270
EGL_WIDTH = 0x3057
@ -23,6 +22,7 @@ GL_TEXTURE_EXTERNAL_OES = 0x8D65
# DRM Format for NV12
DRM_FORMAT_NV12 = 842094158
@dataclass
class EGLImage:
"""Container for EGL image and associated resources"""

@ -3,7 +3,6 @@ import time
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.text_measure import measure_text_cached
PASSWORD_MASK_CHAR = ""
PASSWORD_MASK_DELAY = 1.5 # Seconds to show character before masking
@ -23,7 +22,7 @@ class InputBox:
self._text_offset = 0
self._visible_width = 0
self._last_char_time = 0 # Track when last character was added
self._masked_length = 0 # How many characters are currently masked
self._masked_length = 0 # How many characters are currently masked
@property
def text(self):
@ -76,7 +75,7 @@ class InputBox:
def add_char_at_cursor(self, char):
"""Add a character at the current cursor position."""
if len(self._input_text) < self._max_text_size:
self._input_text = self._input_text[: self._cursor_position] + char + self._input_text[self._cursor_position :]
self._input_text = self._input_text[: self._cursor_position] + char + self._input_text[self._cursor_position:]
self.set_cursor_position(self._cursor_position + 1)
if self._password_mode:
@ -88,7 +87,7 @@ class InputBox:
def delete_char_before_cursor(self):
"""Delete the character before the cursor position (backspace)."""
if self._cursor_position > 0:
self._input_text = self._input_text[: self._cursor_position - 1] + self._input_text[self._cursor_position :]
self._input_text = self._input_text[: self._cursor_position - 1] + self._input_text[self._cursor_position:]
self.set_cursor_position(self._cursor_position - 1)
return True
return False
@ -96,7 +95,7 @@ class InputBox:
def delete_char_at_cursor(self):
"""Delete the character at the cursor position (delete)."""
if self._cursor_position < len(self._input_text):
self._input_text = self._input_text[: self._cursor_position] + self._input_text[self._cursor_position + 1 :]
self._input_text = self._input_text[: self._cursor_position] + self._input_text[self._cursor_position + 1:]
self.set_cursor_position(self._cursor_position)
return True
return False
@ -164,7 +163,7 @@ class InputBox:
if recent_edit and self._input_text:
last_pos = max(0, self._cursor_position - 1)
if last_pos < len(self._input_text):
return masked_text[:last_pos] + self._input_text[last_pos] + masked_text[last_pos + 1 :]
return masked_text[:last_pos] + self._input_text[last_pos] + masked_text[last_pos + 1:]
return masked_text

@ -76,4 +76,3 @@ def gui_text_box(
if font_weight != FontWeight.NORMAL:
rl.gui_set_font(gui_app.font(FontWeight.NORMAL))

@ -11,7 +11,6 @@ from openpilot.system.ui.lib.button import gui_button
from openpilot.system.ui.lib.toggle import Toggle
from openpilot.system.ui.lib.toggle import WIDTH as TOGGLE_WIDTH, HEIGHT as TOGGLE_HEIGHT
LINE_PADDING = 40
LINE_COLOR = rl.GRAY
ITEM_PADDING = 20

@ -124,7 +124,6 @@ void main() {
}
"""
UNIFORM_INT = rl.ShaderUniformDataType.SHADER_UNIFORM_INT
UNIFORM_FLOAT = rl.ShaderUniformDataType.SHADER_UNIFORM_FLOAT
UNIFORM_VEC2 = rl.ShaderUniformDataType.SHADER_UNIFORM_VEC2
@ -244,6 +243,7 @@ def _configure_shader_color(state, color, gradient, clipped_rect, original_rect)
state.fill_color_ptr[0:4] = [color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a / 255.0]
rl.set_shader_value(state.shader, state.locations['fillColor'], state.fill_color_ptr, UNIFORM_VEC4)
def draw_polygon(origin_rect: rl.Rectangle, points: np.ndarray, color=None, gradient=None):
"""
Draw a complex polygon using shader-based even-odd fill rule

@ -13,6 +13,7 @@ from dbus_next.aio import MessageBus
from dbus_next import BusType, Variant, Message
from dbus_next.errors import DBusError
from dbus_next.constants import MessageType
try:
from openpilot.common.params import Params
except ImportError:
@ -38,6 +39,7 @@ NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8
TETHERING_IP_ADDRESS = "192.168.43.1"
DEFAULT_TETHERING_PASSWORD = "12345678"
# NetworkManager device states
class NMDeviceState(IntEnum):
DISCONNECTED = 30
@ -46,6 +48,7 @@ class NMDeviceState(IntEnum):
IP_CONFIG = 70
ACTIVATED = 100
class SecurityType(IntEnum):
OPEN = 0
WPA = 1
@ -53,6 +56,7 @@ class SecurityType(IntEnum):
WPA3 = 3
UNSUPPORTED = 4
@dataclass
class NetworkInfo:
ssid: str
@ -227,7 +231,7 @@ class WifiManager:
except Exception as e:
self._current_connection_ssid = None
cloudlog.error(f"Error connecting to network: {e}")
# Notify UI of failure
# Notify UI of failure
if self.callbacks.connection_failed:
self.callbacks.connection_failed(ssid, str(e))

@ -1,6 +1,7 @@
import pyray as rl
from openpilot.system.ui.lib.text_measure import measure_text_cached
def _break_long_word(font: rl.Font, word: str, font_size: int, max_width: int) -> list[str]:
if not word:
return []

@ -76,7 +76,7 @@ class Reset:
if self.reset_state != ResetState.FAILED:
if gui_button(rl.Rectangle(rect.x + button_width + 50, button_top, button_width, button_height),
"Confirm", button_style=ButtonStyle.PRIMARY):
"Confirm", button_style=ButtonStyle.PRIMARY):
self.confirm()
return True

@ -101,5 +101,6 @@ def main():
spinner.render()
if __name__ == "__main__":
main()

@ -17,6 +17,7 @@ BUTTON_SIZE = rl.Vector2(310, 160)
DEMO_TEXT = """This is a sample text that will be wrapped and scrolled if necessary.
The text is long enough to demonstrate scrolling and word wrapping.""" * 30
def wrap_text(text, font_size, max_width):
lines = []
font = gui_app.font()
@ -72,6 +73,7 @@ class TextWindow:
HARDWARE.reboot()
return ret
if __name__ == "__main__":
text = sys.argv[1] if len(sys.argv) > 1 else DEMO_TEXT
gui_app.init_window("Text Viewer")

@ -12,7 +12,6 @@ from openpilot.system.ui.lib.label import gui_text_box, gui_label
from openpilot.system.ui.lib.wifi_manager import WifiManagerWrapper
from openpilot.system.ui.widgets.network import WifiManagerUI
# Constants
MARGIN = 50
BUTTON_HEIGHT = 160
@ -60,7 +59,7 @@ class Updater:
# TODO: just import it and run in a thread without a subprocess
cmd = [self.updater, "--swap", self.manifest]
self.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, bufsize=1, universal_newlines=True)
text=True, bufsize=1, universal_newlines=True)
for line in self.process.stdout:
parts = line.strip().split(":")
@ -85,7 +84,7 @@ class Updater:
# Description
desc_text = ("An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. " +
"The download size is approximately 1GB.")
"The download size is approximately 1GB.")
desc_rect = rl.Rectangle(MARGIN + 50, 250 + TITLE_FONT_SIZE + 75, gui_app.width - MARGIN * 2 - 100, BODY_FONT_SIZE * 3)
gui_text_box(desc_rect, desc_text, BODY_FONT_SIZE)

@ -69,7 +69,7 @@ class Keyboard:
# Backspace key repeat tracking
self._backspace_pressed: bool = False
self._backspace_press_time: float = 0.0
self._backspace_last_repeat:float = 0.0
self._backspace_last_repeat: float = 0.0
self._eye_open_texture = gui_app.texture("icons/eye_open.png", 81, 54)
self._eye_closed_texture = gui_app.texture("icons/eye_closed.png", 81, 54)
@ -91,7 +91,7 @@ class Keyboard:
self._input_box.clear()
self._backspace_pressed = False
def set_title(self, title: str, sub_title: str=""):
def set_title(self, title: str, sub_title: str = ""):
self._title = title
self._sub_title = sub_title

@ -24,30 +24,36 @@ STRENGTH_ICONS = [
"icons/wifi_strength_full.png",
]
@dataclass
class StateIdle:
action: Literal["idle"] = "idle"
@dataclass
class StateConnecting:
network: NetworkInfo
action: Literal["connecting"] = "connecting"
@dataclass
class StateNeedsAuth:
network: NetworkInfo
action: Literal["needs_auth"] = "needs_auth"
@dataclass
class StateShowForgetConfirm:
network: NetworkInfo
action: Literal["show_forget_confirm"] = "show_forget_confirm"
@dataclass
class StateForgetting:
network: NetworkInfo
action: Literal["forgetting"] = "forgetting"
UIState = StateIdle | StateConnecting | StateNeedsAuth | StateShowForgetConfirm | StateForgetting
@ -64,11 +70,11 @@ class WifiManagerUI:
self.wifi_manager.set_callbacks(
WifiManagerCallbacks(
need_auth = self._on_need_auth,
activated = self._on_activated,
forgotten = self._on_forgotten,
networks_updated = self._on_network_updated,
connection_failed = self._on_connection_failed
need_auth=self._on_need_auth,
activated=self._on_activated,
forgotten=self._on_forgotten,
networks_updated=self._on_network_updated,
connection_failed=self._on_connection_failed
)
)
self.wifi_manager.start()
@ -148,7 +154,8 @@ class WifiManagerUI:
else:
# If the network is saved, show the "Forget" button
if network.is_saved:
forget_btn_rect = rl.Rectangle(security_icon_rect.x - self.btn_width - spacing,
forget_btn_rect = rl.Rectangle(
security_icon_rect.x - self.btn_width - spacing,
rect.y + (ITEM_HEIGHT - 80) / 2,
self.btn_width,
80,
@ -225,7 +232,6 @@ class WifiManagerUI:
self.state = StateIdle()
def main():
gui_app.init_window("Wi-Fi Manager")
wifi_manager = WifiManagerWrapper()

Loading…
Cancel
Save