mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-08-05 08:16:06 +08:00
raylib: base widget class (#35484)
* use some widgets * consistent name draw -> render * more * rest
This commit is contained in:
@@ -6,7 +6,7 @@ from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.ui.widgets.offroad_alerts import UpdateAlert, OffroadAlert
|
||||
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
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_TEXT_COLOR, Widget
|
||||
|
||||
HEADER_HEIGHT = 80
|
||||
HEAD_BUTTON_FONT_SIZE = 40
|
||||
@@ -24,7 +24,7 @@ class HomeLayoutState(IntEnum):
|
||||
ALERTS = 2
|
||||
|
||||
|
||||
class HomeLayout:
|
||||
class HomeLayout(Widget):
|
||||
def __init__(self):
|
||||
self.params = Params()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from openpilot.selfdrive.ui.layouts.home import HomeLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.settings import SettingsLayout
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
|
||||
|
||||
class MainState(IntEnum):
|
||||
@@ -13,7 +14,7 @@ class MainState(IntEnum):
|
||||
ONROAD = 2
|
||||
|
||||
|
||||
class MainLayout:
|
||||
class MainLayout(Widget):
|
||||
def __init__(self):
|
||||
self._sidebar = Sidebar()
|
||||
self._sidebar_visible = True
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import pyray as rl
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
from openpilot.system.ui.lib.wifi_manager import WifiManagerWrapper
|
||||
from openpilot.system.ui.widgets.network import WifiManagerUI
|
||||
|
||||
|
||||
class NetworkLayout:
|
||||
class NetworkLayout(Widget):
|
||||
def __init__(self):
|
||||
self.wifi_manager = WifiManagerWrapper()
|
||||
self.wifi_ui = WifiManagerUI(self.wifi_manager)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
from openpilot.system.ui.lib.list_view import ListView, toggle_item
|
||||
from openpilot.common.params import Params
|
||||
|
||||
@@ -11,7 +12,7 @@ DESCRIPTIONS = {
|
||||
}
|
||||
|
||||
|
||||
class DeveloperLayout:
|
||||
class DeveloperLayout(Widget):
|
||||
def __init__(self):
|
||||
self._params = Params()
|
||||
items = [
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
from openpilot.system.ui.lib.list_view import ListView, text_item, button_item
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.hardware import TICI
|
||||
@@ -14,7 +15,7 @@ DESCRIPTIONS = {
|
||||
}
|
||||
|
||||
|
||||
class DeviceLayout:
|
||||
class DeviceLayout(Widget):
|
||||
def __init__(self):
|
||||
params = Params()
|
||||
dongle_id = params.get("DongleId", encoding="utf-8") or "N/A"
|
||||
|
||||
@@ -7,7 +7,7 @@ from openpilot.selfdrive.ui.layouts.settings.developer import DeveloperLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.device import DeviceLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.software import SoftwareLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.toggles import TogglesLayout
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
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.layouts.network import NetworkLayout
|
||||
@@ -48,7 +48,7 @@ class PanelInfo:
|
||||
button_rect: rl.Rectangle
|
||||
|
||||
|
||||
class SettingsLayout:
|
||||
class SettingsLayout(Widget):
|
||||
def __init__(self):
|
||||
self._params = Params()
|
||||
self._current_panel = PanelType.DEVICE
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
from openpilot.system.ui.lib.list_view import ListView, button_item, text_item
|
||||
|
||||
|
||||
class SoftwareLayout:
|
||||
class SoftwareLayout(Widget):
|
||||
def __init__(self):
|
||||
items = [
|
||||
text_item("Current Version", ""),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
from openpilot.system.ui.lib.list_view import ListView, toggle_item
|
||||
from openpilot.common.params import Params
|
||||
|
||||
@@ -18,7 +19,7 @@ DESCRIPTIONS = {
|
||||
}
|
||||
|
||||
|
||||
class TogglesLayout:
|
||||
class TogglesLayout(Widget):
|
||||
def __init__(self):
|
||||
self._params = Params()
|
||||
items = [
|
||||
|
||||
@@ -4,7 +4,7 @@ from dataclasses import dataclass
|
||||
from collections.abc import Callable
|
||||
from cereal import log
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
|
||||
SIDEBAR_WIDTH = 300
|
||||
@@ -60,7 +60,7 @@ class MetricData:
|
||||
self.color = color
|
||||
|
||||
|
||||
class Sidebar:
|
||||
class Sidebar(Widget):
|
||||
def __init__(self):
|
||||
self._net_type = NETWORK_TYPES.get(NetworkType.none)
|
||||
self._net_strength = 0
|
||||
|
||||
@@ -3,7 +3,7 @@ import pyray as rl
|
||||
from dataclasses import dataclass
|
||||
from cereal import messaging, log
|
||||
from openpilot.system.hardware import TICI
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_FPS
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_FPS, Widget
|
||||
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
|
||||
@@ -59,7 +59,7 @@ ALERT_CRITICAL_REBOOT = Alert(
|
||||
)
|
||||
|
||||
|
||||
class AlertRenderer:
|
||||
class AlertRenderer(Widget):
|
||||
def __init__(self):
|
||||
self.font_regular: rl.Font = gui_app.font(FontWeight.NORMAL)
|
||||
self.font_bold: rl.Font = gui_app.font(FontWeight.BOLD)
|
||||
@@ -91,8 +91,8 @@ class AlertRenderer:
|
||||
# Return current alert
|
||||
return Alert(text1=ss.alertText1, text2=ss.alertText2, size=ss.alertSize, status=ss.alertStatus)
|
||||
|
||||
def draw(self, rect: rl.Rectangle, sm: messaging.SubMaster) -> None:
|
||||
alert = self.get_alert(sm)
|
||||
def render(self, rect: rl.Rectangle) -> None:
|
||||
alert = self.get_alert(ui_state.sm)
|
||||
if not alert:
|
||||
return
|
||||
|
||||
|
||||
@@ -78,10 +78,10 @@ class AugmentedRoadView(CameraView):
|
||||
super().render(rect)
|
||||
|
||||
# Draw all UI overlays
|
||||
self.model_renderer.draw(self._content_rect, ui_state.sm)
|
||||
self._hud_renderer.draw(self._content_rect, ui_state.sm)
|
||||
self.alert_renderer.draw(self._content_rect, ui_state.sm)
|
||||
self.driver_state_renderer.draw(self._content_rect, ui_state.sm)
|
||||
self.model_renderer.render(self._content_rect)
|
||||
self._hud_renderer.render(self._content_rect)
|
||||
self.alert_renderer.render(self._content_rect)
|
||||
self.driver_state_renderer.render(self._content_rect, ui_state.sm)
|
||||
|
||||
# Custom UI extension point - add custom overlays here
|
||||
# Use self._content_rect for positioning within camera bounds
|
||||
|
||||
@@ -4,7 +4,7 @@ import pyray as rl
|
||||
from openpilot.system.hardware import TICI
|
||||
from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.lib.application import gui_app, Widget
|
||||
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
|
||||
@@ -55,7 +55,7 @@ else:
|
||||
"""
|
||||
|
||||
|
||||
class CameraView:
|
||||
class CameraView(Widget):
|
||||
def __init__(self, name: str, stream_type: VisionStreamType):
|
||||
self._name = name
|
||||
# Primary stream
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import numpy as np
|
||||
import pyray as rl
|
||||
from cereal import messaging
|
||||
from msgq.visionipc import VisionStreamType
|
||||
from openpilot.selfdrive.ui.onroad.cameraview import CameraView
|
||||
from openpilot.selfdrive.ui.onroad.driver_state import DriverStateRenderer
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.label import gui_label
|
||||
|
||||
@@ -13,7 +13,7 @@ class DriverCameraView(CameraView):
|
||||
super().__init__("camerad", stream_type)
|
||||
self.driver_state_renderer = DriverStateRenderer()
|
||||
|
||||
def render(self, rect, sm):
|
||||
def render(self, rect):
|
||||
super().render(rect)
|
||||
|
||||
if not self.frame:
|
||||
@@ -26,8 +26,8 @@ class DriverCameraView(CameraView):
|
||||
)
|
||||
return
|
||||
|
||||
self._draw_face_detection(rect, sm)
|
||||
self.driver_state_renderer.draw(rect, sm)
|
||||
self._draw_face_detection(rect, ui_state.sm)
|
||||
self.driver_state_renderer.draw(rect, ui_state.sm)
|
||||
|
||||
def _draw_face_detection(self, rect: rl.Rectangle, sm) -> None:
|
||||
driver_state = sm["driverStateV2"]
|
||||
@@ -83,12 +83,11 @@ class DriverCameraView(CameraView):
|
||||
|
||||
if __name__ == "__main__":
|
||||
gui_app.init_window("Driver Camera View")
|
||||
sm = messaging.SubMaster(["selfdriveState", "driverStateV2", "driverMonitoringState"])
|
||||
|
||||
driver_camera_view = DriverCameraView(VisionStreamType.VISION_STREAM_DRIVER)
|
||||
try:
|
||||
for _ in gui_app.render():
|
||||
sm.update()
|
||||
driver_camera_view.render(rl.Rectangle(0, 0, gui_app.width, gui_app.height), sm)
|
||||
ui_state.update()
|
||||
driver_camera_view.render(rl.Rectangle(0, 0, gui_app.width, gui_app.height))
|
||||
finally:
|
||||
driver_camera_view.close()
|
||||
|
||||
@@ -2,7 +2,7 @@ import numpy as np
|
||||
import pyray as rl
|
||||
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
|
||||
from openpilot.system.ui.lib.application import gui_app, Widget
|
||||
|
||||
# Default 3D coordinates for face keypoints as a NumPy array
|
||||
DEFAULT_FACE_KPTS_3D = np.array([
|
||||
@@ -41,7 +41,7 @@ class ArcData:
|
||||
thickness: float
|
||||
|
||||
|
||||
class DriverStateRenderer:
|
||||
class DriverStateRenderer(Widget):
|
||||
def __init__(self):
|
||||
# Initial state with NumPy arrays
|
||||
self.face_kpts_draw = DEFAULT_FACE_KPTS_3D.copy()
|
||||
@@ -74,11 +74,11 @@ class DriverStateRenderer:
|
||||
self.engaged_color = rl.Color(26, 242, 66, 255)
|
||||
self.disengaged_color = rl.Color(139, 139, 139, 255)
|
||||
|
||||
def draw(self, rect, sm):
|
||||
if not self._is_visible(sm):
|
||||
def render(self, rect):
|
||||
if not self._is_visible(ui_state.sm):
|
||||
return
|
||||
|
||||
self._update_state(sm, rect)
|
||||
self._update_state(ui_state.sm, rect)
|
||||
if not self.state_updated:
|
||||
return
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import pyray as rl
|
||||
from dataclasses import dataclass
|
||||
from cereal.messaging import SubMaster
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
|
||||
@@ -54,7 +54,7 @@ FONT_SIZES = FontSizes()
|
||||
COLORS = Colors()
|
||||
|
||||
|
||||
class HudRenderer:
|
||||
class HudRenderer(Widget):
|
||||
def __init__(self):
|
||||
"""Initialize the HUD renderer."""
|
||||
self.is_cruise_set: bool = False
|
||||
@@ -94,9 +94,9 @@ class HudRenderer:
|
||||
speed_conversion = CV.MS_TO_KPH if ui_state.is_metric else CV.MS_TO_MPH
|
||||
self.speed = max(0.0, v_ego * speed_conversion)
|
||||
|
||||
def draw(self, rect: rl.Rectangle, sm: SubMaster) -> None:
|
||||
def render(self, rect: rl.Rectangle) -> None:
|
||||
"""Render HUD elements to the screen."""
|
||||
self._update_state(sm)
|
||||
self._update_state(ui_state.sm)
|
||||
rl.draw_rectangle_gradient_v(
|
||||
int(rect.x),
|
||||
int(rect.y),
|
||||
|
||||
@@ -5,7 +5,7 @@ from cereal import messaging, car
|
||||
from dataclasses import dataclass, field
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.application import DEFAULT_FPS
|
||||
from openpilot.system.ui.lib.application import DEFAULT_FPS, Widget
|
||||
from openpilot.system.ui.lib.shader_polygon import draw_polygon
|
||||
from openpilot.selfdrive.locationd.calibrationd import HEIGHT_INIT
|
||||
|
||||
@@ -43,7 +43,7 @@ class LeadVehicle:
|
||||
fill_alpha: int = 0
|
||||
|
||||
|
||||
class ModelRenderer:
|
||||
class ModelRenderer(Widget):
|
||||
def __init__(self):
|
||||
self._longitudinal_control = False
|
||||
self._experimental_mode = False
|
||||
@@ -86,7 +86,9 @@ class ModelRenderer:
|
||||
self._car_space_transform = transform.astype(np.float32)
|
||||
self._transform_dirty = True
|
||||
|
||||
def draw(self, rect: rl.Rectangle, sm: messaging.SubMaster):
|
||||
def render(self, rect: rl.Rectangle):
|
||||
sm = ui_state.sm
|
||||
|
||||
# Check if data is up-to-date
|
||||
if (sm.recv_frame["liveCalibration"] < ui_state.started_frame or
|
||||
sm.recv_frame["modelV2"] < ui_state.started_frame):
|
||||
|
||||
@@ -8,7 +8,7 @@ from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
|
||||
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
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
|
||||
|
||||
class AlertColors:
|
||||
@@ -41,7 +41,7 @@ class AlertData:
|
||||
visible: bool = False
|
||||
|
||||
|
||||
class AbstractAlert(ABC):
|
||||
class AbstractAlert(Widget, ABC):
|
||||
def __init__(self, has_reboot_btn: bool = False):
|
||||
self.params = Params()
|
||||
self.has_reboot_btn = has_reboot_btn
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import abc
|
||||
import atexit
|
||||
import os
|
||||
import time
|
||||
@@ -26,6 +27,12 @@ ASSETS_DIR = files("openpilot.selfdrive").joinpath("assets")
|
||||
FONT_DIR = ASSETS_DIR.joinpath("fonts")
|
||||
|
||||
|
||||
class Widget(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def render(self, rect: rl.Rectangle) -> bool | None:
|
||||
"""Render the widget within the given rectangle."""
|
||||
|
||||
|
||||
class FontWeight(IntEnum):
|
||||
THIN = 0
|
||||
EXTRA_LIGHT = 1
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import pyray as rl
|
||||
import time
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.lib.application import gui_app, Widget
|
||||
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
|
||||
|
||||
|
||||
class InputBox:
|
||||
class InputBox(Widget):
|
||||
def __init__(self, max_text_size=255, password_mode=False):
|
||||
self._max_text_size = max_text_size
|
||||
self._input_text = ""
|
||||
|
||||
@@ -4,12 +4,11 @@ from dataclasses import dataclass
|
||||
from collections.abc import Callable
|
||||
from abc import ABC, abstractmethod
|
||||
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.lib.wrap_text import wrap_text
|
||||
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
|
||||
from openpilot.system.ui.lib.toggle import Toggle, WIDTH as TOGGLE_WIDTH, HEIGHT as TOGGLE_HEIGHT
|
||||
|
||||
LINE_PADDING = 40
|
||||
LINE_COLOR = rl.GRAY
|
||||
@@ -31,15 +30,11 @@ BUTTON_FONT_WEIGHT = FontWeight.MEDIUM
|
||||
|
||||
|
||||
# Abstract base class for right-side items
|
||||
class RightItem(ABC):
|
||||
class RightItem(Widget, ABC):
|
||||
def __init__(self, width: int = 100):
|
||||
self.width = width
|
||||
self.enabled = True
|
||||
|
||||
@abstractmethod
|
||||
def draw(self, rect: rl.Rectangle) -> bool:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_width(self) -> int:
|
||||
pass
|
||||
@@ -52,7 +47,7 @@ class ToggleRightItem(RightItem):
|
||||
self.state = initial_state
|
||||
self.enabled = True
|
||||
|
||||
def draw(self, rect: rl.Rectangle) -> bool:
|
||||
def render(self, rect: rl.Rectangle) -> bool:
|
||||
if self.toggle.render(rl.Rectangle(rect.x, rect.y + (rect.height - TOGGLE_HEIGHT) / 2, self.width, TOGGLE_HEIGHT)):
|
||||
self.state = not self.state
|
||||
return True
|
||||
@@ -78,7 +73,7 @@ class ButtonRightItem(RightItem):
|
||||
self.text = text
|
||||
self.enabled = True
|
||||
|
||||
def draw(self, rect: rl.Rectangle) -> bool:
|
||||
def render(self, rect: rl.Rectangle) -> bool:
|
||||
return (
|
||||
gui_button(
|
||||
rl.Rectangle(rect.x, rect.y + (rect.height - BUTTON_HEIGHT) / 2, BUTTON_WIDTH, BUTTON_HEIGHT),
|
||||
@@ -108,7 +103,7 @@ class TextRightItem(RightItem):
|
||||
text_width = measure_text_cached(font, text, font_size).x
|
||||
super().__init__(int(text_width + 20))
|
||||
|
||||
def draw(self, rect: rl.Rectangle) -> bool:
|
||||
def render(self, rect: rl.Rectangle) -> bool:
|
||||
font = gui_app.font(FontWeight.NORMAL)
|
||||
text_size = measure_text_cached(font, self.text, self.font_size)
|
||||
|
||||
@@ -269,7 +264,7 @@ class ListView:
|
||||
right_rect = item.get_right_item_rect(rect)
|
||||
# Adjust for scroll offset
|
||||
right_rect.y = right_rect.y
|
||||
if item.right_item.draw(right_rect):
|
||||
if item.right_item.render(right_rect):
|
||||
# Right item was clicked/activated
|
||||
if item.callback:
|
||||
item.callback()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import pyray as rl
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
|
||||
ON_COLOR = rl.Color(51, 171, 76, 255)
|
||||
OFF_COLOR = rl.Color(0x39, 0x39, 0x39, 255)
|
||||
@@ -11,7 +12,7 @@ BG_HEIGHT = 60
|
||||
ANIMATION_SPEED = 8.0
|
||||
|
||||
|
||||
class Toggle:
|
||||
class Toggle(Widget):
|
||||
def __init__(self, initial_state=False):
|
||||
self._state = initial_state
|
||||
self._enabled = True
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ import threading
|
||||
from enum import IntEnum
|
||||
|
||||
from openpilot.system.hardware import PC
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
from openpilot.system.ui.lib.button import gui_button, ButtonStyle
|
||||
from openpilot.system.ui.lib.label import gui_label, gui_text_box
|
||||
|
||||
@@ -27,7 +27,7 @@ class ResetState(IntEnum):
|
||||
FAILED = 3
|
||||
|
||||
|
||||
class Reset:
|
||||
class Reset(Widget):
|
||||
def __init__(self, mode):
|
||||
self.mode = mode
|
||||
self.reset_state = ResetState.NONE
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import pyray as rl
|
||||
|
||||
from cereal import log
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
from openpilot.system.ui.lib.button import gui_button, ButtonStyle
|
||||
from openpilot.system.ui.lib.label import gui_label, gui_text_box
|
||||
from openpilot.system.ui.widgets.network import WifiManagerUI, WifiManagerWrapper
|
||||
@@ -39,7 +39,7 @@ class SetupState(IntEnum):
|
||||
DOWNLOAD_FAILED = 6
|
||||
|
||||
|
||||
class Setup:
|
||||
class Setup(Widget):
|
||||
def __init__(self):
|
||||
self.state = SetupState.GETTING_STARTED
|
||||
self.network_check_thread = None
|
||||
|
||||
@@ -3,7 +3,7 @@ import pyray as rl
|
||||
import select
|
||||
import sys
|
||||
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.lib.application import gui_app, Widget
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.text import wrap_text
|
||||
|
||||
@@ -22,7 +22,7 @@ def clamp(value, min_value, max_value):
|
||||
return max(min(value, max_value), min_value)
|
||||
|
||||
|
||||
class Spinner:
|
||||
class Spinner(Widget):
|
||||
def __init__(self):
|
||||
self._comma_texture = gui_app.texture("images/spinner_comma.png", TEXTURE_SIZE, TEXTURE_SIZE)
|
||||
self._spinner_texture = gui_app.texture("images/spinner_track.png", TEXTURE_SIZE, TEXTURE_SIZE, alpha_premultiply=True)
|
||||
@@ -38,7 +38,7 @@ class Spinner:
|
||||
self._progress = None
|
||||
self._wrapped_lines = wrap_text(text, FONT_SIZE, gui_app.width - MARGIN_H)
|
||||
|
||||
def render(self):
|
||||
def render(self, _: rl.Rectangle):
|
||||
if self._wrapped_lines:
|
||||
# Calculate total height required for spinner and text
|
||||
spacing = 50
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@ from openpilot.system.hardware import HARDWARE, PC
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.lib.button import gui_button, ButtonStyle
|
||||
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.lib.application import gui_app, Widget
|
||||
|
||||
MARGIN = 50
|
||||
SPACING = 40
|
||||
@@ -46,7 +46,7 @@ def wrap_text(text, font_size, max_width):
|
||||
return lines
|
||||
|
||||
|
||||
class TextWindow:
|
||||
class TextWindow(Widget):
|
||||
def __init__(self, text: str):
|
||||
self._textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2)
|
||||
self._wrapped_lines = wrap_text(text, FONT_SIZE, self._textarea_rect.width - 20)
|
||||
@@ -54,7 +54,7 @@ class TextWindow:
|
||||
self._scroll_panel = GuiScrollPanel(show_vertical_scroll_bar=True)
|
||||
self._scroll_panel._offset.y = -max(self._content_rect.height - self._textarea_rect.height, 0)
|
||||
|
||||
def render(self):
|
||||
def render(self, _: rl.Rectangle = None):
|
||||
scroll = self._scroll_panel.handle_scroll(self._textarea_rect, self._content_rect)
|
||||
rl.begin_scissor_mode(int(self._textarea_rect.x), int(self._textarea_rect.y), int(self._textarea_rect.width), int(self._textarea_rect.height))
|
||||
for i, line in enumerate(self._wrapped_lines):
|
||||
|
||||
@@ -6,7 +6,7 @@ import pyray as rl
|
||||
from enum import IntEnum
|
||||
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
from openpilot.system.ui.lib.button import gui_button, ButtonStyle
|
||||
from openpilot.system.ui.lib.label import gui_text_box, gui_label
|
||||
from openpilot.system.ui.lib.wifi_manager import WifiManagerWrapper
|
||||
@@ -30,7 +30,7 @@ class Screen(IntEnum):
|
||||
PROGRESS = 2
|
||||
|
||||
|
||||
class Updater:
|
||||
class Updater(Widget):
|
||||
def __init__(self, updater_path, manifest_path):
|
||||
self.updater = updater_path
|
||||
self.manifest = manifest_path
|
||||
@@ -137,7 +137,7 @@ class Updater:
|
||||
HARDWARE.reboot()
|
||||
return
|
||||
|
||||
def render(self):
|
||||
def render(self, _: rl.Rectangle = None):
|
||||
if self.current_screen == Screen.PROMPT:
|
||||
self.render_prompt_screen()
|
||||
elif self.current_screen == Screen.WIFI:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import time
|
||||
from typing import Literal
|
||||
import pyray as rl
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, Widget
|
||||
from openpilot.system.ui.lib.button import ButtonStyle, gui_button
|
||||
from openpilot.system.ui.lib.inputbox import InputBox
|
||||
from openpilot.system.ui.lib.label import gui_label
|
||||
@@ -52,7 +52,7 @@ KEYBOARD_LAYOUTS = {
|
||||
}
|
||||
|
||||
|
||||
class Keyboard:
|
||||
class Keyboard(Widget):
|
||||
def __init__(self, max_text_size: int = 255, min_text_size: int = 0, password_mode: bool = False, show_password_toggle: bool = False):
|
||||
self._layout_name: Literal["lowercase", "uppercase", "numbers", "specials"] = "lowercase"
|
||||
self._caps_lock = False
|
||||
|
||||
@@ -3,7 +3,7 @@ from threading import Lock
|
||||
from typing import Literal
|
||||
|
||||
import pyray as rl
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.lib.application import gui_app, Widget
|
||||
from openpilot.system.ui.lib.button import ButtonStyle, gui_button
|
||||
from openpilot.system.ui.lib.label import gui_label
|
||||
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
|
||||
@@ -57,7 +57,7 @@ class StateForgetting:
|
||||
UIState = StateIdle | StateConnecting | StateNeedsAuth | StateShowForgetConfirm | StateForgetting
|
||||
|
||||
|
||||
class WifiManagerUI:
|
||||
class WifiManagerUI(Widget):
|
||||
def __init__(self, wifi_manager: WifiManagerWrapper):
|
||||
self.state: UIState = StateIdle()
|
||||
self.btn_width: int = 200
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import pyray as rl
|
||||
|
||||
from openpilot.system.ui.lib.application import Widget
|
||||
from openpilot.system.ui.lib.button import gui_button, ButtonStyle, TextAlignment
|
||||
from openpilot.system.ui.lib.label import gui_label
|
||||
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
|
||||
|
||||
|
||||
class MultiOptionDialog:
|
||||
class MultiOptionDialog(Widget):
|
||||
def __init__(self, title, options, current=""):
|
||||
self._title = title
|
||||
self._options = options
|
||||
|
||||
Reference in New Issue
Block a user