match style

pull/36197/head
Shane Smiskol 4 days ago
parent afc7ff1b7a
commit 7f18c24850
  1. 3
      selfdrive/ui/layouts/main.py
  2. 7
      selfdrive/ui/layouts/settings/settings.py
  3. 4
      selfdrive/ui/layouts/sidebar.py
  4. 2
      selfdrive/ui/ui.cc
  5. 2
      selfdrive/ui/ui_state.py
  6. 25
      system/ui/lib/wifi_manager.py
  7. 20
      system/ui/widgets/button.py
  8. 113
      system/ui/widgets/network.py

@ -34,6 +34,9 @@ class MainLayout(Widget):
# Set callbacks
self._setup_callbacks()
self._on_settings_clicked()
def _render(self, _):
self._handle_onroad_transition()
self._render_main_content()

@ -11,7 +11,7 @@ from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.wifi_manager import WifiManager
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.widgets.network import WifiManagerUI
from openpilot.system.ui.widgets.network import WifiUi
# Settings close button
SETTINGS_CLOSE_TEXT = "×"
@ -51,7 +51,7 @@ class PanelInfo:
class SettingsLayout(Widget):
def __init__(self):
super().__init__()
self._current_panel = PanelType.DEVICE
self._current_panel = PanelType.NETWORK
# Panel configuration
wifi_manager = WifiManager()
@ -59,7 +59,7 @@ class SettingsLayout(Widget):
self._panels = {
PanelType.DEVICE: PanelInfo("Device", DeviceLayout()),
PanelType.NETWORK: PanelInfo("Network", WifiManagerUI(wifi_manager)),
PanelType.NETWORK: PanelInfo("Network", WifiUi(wifi_manager)),
PanelType.TOGGLES: PanelInfo("Toggles", TogglesLayout()),
PanelType.SOFTWARE: PanelInfo("Software", SoftwareLayout()),
PanelType.FIREHOSE: PanelInfo("Firehose", FirehoseLayout()),
@ -152,6 +152,7 @@ class SettingsLayout(Widget):
return False
def set_current_panel(self, panel_type: PanelType):
panel_type = PanelType.NETWORK
if panel_type != self._current_panel:
self._panels[self._current_panel].instance.hide_event()
self._current_panel = panel_type

@ -189,11 +189,11 @@ class Sidebar(Widget):
# Draw colored left edge (clipped rounded rectangle)
edge_rect = rl.Rectangle(metric_rect.x + 4, metric_rect.y + 4, 100, 118)
rl.begin_scissor_mode(int(metric_rect.x + 4), int(metric_rect.y), 18, int(metric_rect.height))
rl.draw_rectangle_rounded(edge_rect, 0.18, 10, metric.color)
rl.draw_rectangle_rounded(edge_rect, 0.3, 10, metric.color)
rl.end_scissor_mode()
# Draw border
rl.draw_rectangle_rounded_lines_ex(metric_rect, 0.15, 10, 2, Colors.METRIC_BORDER)
rl.draw_rectangle_rounded_lines_ex(metric_rect, 0.3, 10, 2, Colors.METRIC_BORDER)
# Draw label and value
labels = [metric.label, metric.value]

@ -145,7 +145,7 @@ void Device::setAwake(bool on) {
void Device::resetInteractiveTimeout(int timeout) {
if (timeout == -1) {
timeout = (ignition_on ? 10 : 30);
timeout = (ignition_on ? 10 : 300);
}
interactive_timeout = timeout * UI_FREQ;
}

@ -156,7 +156,7 @@ class Device:
def reset_interactive_timeout(self, timeout: int = -1) -> None:
if timeout == -1:
timeout = 10 if ui_state.ignition else 30
timeout = 10 if ui_state.ignition else 300
self._interaction_time = time.monotonic() + timeout
def add_interactive_timeout_callback(self, callback: Callable):

@ -132,6 +132,7 @@ class WifiManager:
# State
self._connecting_to_ssid: str = ""
self._ipv4_address: str = ""
self._last_network_update: float = 0.0
self._callback_queue: list[Callable] = []
@ -409,9 +410,33 @@ class WifiManager:
networks.sort(key=lambda n: (-n.is_connected, -n.strength, n.ssid.lower()))
self._networks = networks
self._update_ipv4_address()
if self._networks_updated is not None:
self._enqueue_callback(self._networks_updated, self._networks)
def _update_ipv4_address(self):
if self._wifi_device is None:
cloudlog.warning("No WiFi device found")
return
self._ipv4_address = ""
for conn_path in self._get_active_connections():
conn_addr = DBusAddress(conn_path, bus_name=NM, interface=NM_ACTIVE_CONNECTION_IFACE)
conn_type = self._router_main.send_and_get_reply(Properties(conn_addr).get('Type')).body[0][1]
if conn_type == '802-11-wireless':
ip4config_path = self._router_main.send_and_get_reply(Properties(conn_addr).get('Ip4Config')).body[0][1]
if ip4config_path != "/":
ip4config_addr = DBusAddress(ip4config_path, bus_name=NM, interface=NM_IP4_CONFIG_IFACE)
address_data = self._router_main.send_and_get_reply(Properties(ip4config_addr).get('AddressData')).body[0][1]
for entry in address_data:
if 'address' in entry:
self._ipv4_address = entry['address'][1]
return
def __del__(self):
self.stop()

@ -14,6 +14,7 @@ class ButtonStyle(IntEnum):
PRIMARY = 1 # For main actions
DANGER = 2 # For critical actions, like reboot or delete
TRANSPARENT = 3 # For buttons with transparent background and border
TRANSPARENT_WHITE = 3 # For buttons with transparent background and border
ACTION = 4
LIST_ACTION = 5 # For list items with action buttons
NO_EFFECT = 6
@ -23,8 +24,6 @@ class ButtonStyle(IntEnum):
ICON_PADDING = 15
DEFAULT_BUTTON_FONT_SIZE = 60
BUTTON_DISABLED_TEXT_COLOR = rl.Color(228, 228, 228, 51)
BUTTON_DISABLED_BACKGROUND_COLOR = rl.Color(51, 51, 51, 255)
ACTION_BUTTON_FONT_SIZE = 48
BUTTON_TEXT_COLOR = {
@ -32,6 +31,7 @@ BUTTON_TEXT_COLOR = {
ButtonStyle.PRIMARY: rl.Color(228, 228, 228, 255),
ButtonStyle.DANGER: rl.Color(228, 228, 228, 255),
ButtonStyle.TRANSPARENT: rl.BLACK,
ButtonStyle.TRANSPARENT_WHITE: rl.WHITE,
ButtonStyle.ACTION: rl.BLACK,
ButtonStyle.LIST_ACTION: rl.Color(228, 228, 228, 255),
ButtonStyle.NO_EFFECT: rl.Color(228, 228, 228, 255),
@ -39,11 +39,16 @@ BUTTON_TEXT_COLOR = {
ButtonStyle.FORGET_WIFI: rl.Color(51, 51, 51, 255),
}
BUTTON_DISABLED_TEXT_COLORS = {
ButtonStyle.TRANSPARENT_WHITE: rl.WHITE,
}
BUTTON_BACKGROUND_COLORS = {
ButtonStyle.NORMAL: rl.Color(51, 51, 51, 255),
ButtonStyle.PRIMARY: rl.Color(70, 91, 234, 255),
ButtonStyle.DANGER: rl.Color(255, 36, 36, 255),
ButtonStyle.TRANSPARENT: rl.BLACK,
ButtonStyle.TRANSPARENT_WHITE: rl.BLANK,
ButtonStyle.ACTION: rl.Color(189, 189, 189, 255),
ButtonStyle.LIST_ACTION: rl.Color(57, 57, 57, 255),
ButtonStyle.NO_EFFECT: rl.Color(51, 51, 51, 255),
@ -56,6 +61,7 @@ BUTTON_PRESSED_BACKGROUND_COLORS = {
ButtonStyle.PRIMARY: rl.Color(48, 73, 244, 255),
ButtonStyle.DANGER: rl.Color(255, 36, 36, 255),
ButtonStyle.TRANSPARENT: rl.BLACK,
ButtonStyle.TRANSPARENT_WHITE: rl.BLANK,
ButtonStyle.ACTION: rl.Color(130, 130, 130, 255),
ButtonStyle.LIST_ACTION: rl.Color(74, 74, 74, 74),
ButtonStyle.NO_EFFECT: rl.Color(51, 51, 51, 255),
@ -63,6 +69,10 @@ BUTTON_PRESSED_BACKGROUND_COLORS = {
ButtonStyle.FORGET_WIFI: rl.Color(130, 130, 130, 255),
}
BUTTON_DISABLED_BACKGROUND_COLORS = {
ButtonStyle.TRANSPARENT_WHITE: rl.BLANK,
}
_pressed_buttons: set[str] = set() # Track mouse press state globally
@ -156,7 +166,7 @@ def gui_button(
# Draw the button text if any
if text:
color = BUTTON_TEXT_COLOR[button_style] if is_enabled else BUTTON_DISABLED_TEXT_COLOR
color = BUTTON_TEXT_COLOR[button_style] if is_enabled else BUTTON_DISABLED_TEXT_COLORS.get(button_style, rl.Color(228, 228, 228, 51))
rl.draw_text_ex(font, text, text_pos, font_size, 0, color)
return result
@ -198,8 +208,8 @@ class Button(Widget):
else:
self._background_color = BUTTON_BACKGROUND_COLORS[self._button_style]
elif self._button_style != ButtonStyle.NO_EFFECT:
self._background_color = BUTTON_DISABLED_BACKGROUND_COLOR
self._label.set_text_color(BUTTON_DISABLED_TEXT_COLOR)
self._background_color = BUTTON_DISABLED_BACKGROUND_COLORS.get(self._button_style, rl.Color(51, 51, 51, 255))
self._label.set_text_color(BUTTON_DISABLED_TEXT_COLORS.get(self._button_style, rl.Color(228, 228, 228, 51)))
def _render(self, _):
roundness = self._border_radius / (min(self._rect.width, self._rect.height) / 2)

@ -11,6 +11,8 @@ from openpilot.system.ui.widgets.button import ButtonStyle, Button
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
from openpilot.system.ui.widgets.keyboard import Keyboard
from openpilot.system.ui.widgets.label import TextAlignment, gui_label
from openpilot.system.ui.widgets.scroller import Scroller
from openpilot.system.ui.widgets.list_view import text_item, button_item, dual_button_item, TextAction, ListItem
NM_DEVICE_STATE_NEED_AUTH = 60
MIN_PASSWORD_LENGTH = 8
@ -26,6 +28,11 @@ STRENGTH_ICONS = [
]
class PanelType(IntEnum):
WIFI = 0
ADVANCED = 1
class UIState(IntEnum):
IDLE = 0
CONNECTING = 1
@ -34,6 +41,109 @@ class UIState(IntEnum):
FORGETTING = 4
class NavButton(Widget):
def __init__(self, text: str):
super().__init__()
self._text = text
self.set_rect(rl.Rectangle(0, 0, 400, 100))
def set_text(self, text: str):
self._text = text
def _render(self, _):
color = rl.Color(74, 74, 74, 255) if self.is_pressed else rl.Color(57, 57, 57, 255)
rl.draw_rectangle_rounded(self._rect, 0.6, 10, color)
gui_label(self.rect, self._text, font_size=60, alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER)
class WifiUi(Widget):
def __init__(self, wifi_manager: WifiManager):
super().__init__()
self.wifi_manager = wifi_manager
self._current_panel: PanelType = PanelType.WIFI
self._wifi_panel = WifiManagerUI(wifi_manager)
self._advanced_panel = AdvancedNetworkSettings()
self._nav_button = NavButton("Advanced")
self._nav_button.set_click_callback(self._cycle_panel)
def show_event(self):
self._set_current_panel(PanelType.WIFI)
self._wifi_panel.show_event()
def hide_event(self):
self._wifi_panel.hide_event()
def _cycle_panel(self):
if self._current_panel == PanelType.WIFI:
self._set_current_panel(PanelType.ADVANCED)
else:
self._set_current_panel(PanelType.WIFI)
def _render(self, _):
# subtract button
content_rect = rl.Rectangle(self._rect.x, self._rect.y + self._nav_button.rect.height + 20,
self._rect.width, self._rect.height - self._nav_button.rect.height - 20)
if self._current_panel == PanelType.WIFI:
self._nav_button.set_text("Advanced")
self._nav_button.set_position(self._rect.x + self._rect.width - self._nav_button.rect.width, self._rect.y + 10)
self._wifi_panel.render(content_rect)
else:
self._nav_button.set_text("Back")
self._nav_button.set_position(self._rect.x, self._rect.y + 10)
self._advanced_panel.render(content_rect)
self._nav_button.render()
def _set_current_panel(self, panel: PanelType):
self._current_panel = panel
class AdvancedNetworkSettings(Widget):
def __init__(self):
super().__init__()
#
# self._params = Params()
# self._select_language_dialog: MultiOptionDialog | None = None
# self._driver_camera: DriverCameraDialog | None = None
# self._pair_device_dialog: PairingDialog | None = None
# self._fcc_dialog: HtmlRenderer | None = None
# items = self._initialize_items()
# action =
action = TextAction(text="", color=rl.Color(170, 170, 170, 255))
self._ip_address_btn = ListItem(title="IP Address", action_item=action)
# enable tethering, tethering password, ip address, wifi network metered, hidden network
items = [
self._ip_address_btn
]
self._scroller = Scroller(items, line_separator=True, spacing=0)
def _initialize_items(self):
items = [
text_item("Dongle ID", dongle_id),
# text_item("Serial", serial),
# button_item("Pair Device", "PAIR", DESCRIPTIONS['pair_device'], callback=self._pair_device),
# button_item("Driver Camera", "PREVIEW", DESCRIPTIONS['driver_camera'], callback=self._show_driver_camera, enabled=ui_state.is_offroad),
# button_item("Reset Calibration", "RESET", DESCRIPTIONS['reset_calibration'], callback=self._reset_calibration_prompt),
# regulatory_btn := button_item("Regulatory", "VIEW", callback=self._on_regulatory),
# button_item("Review Training Guide", "REVIEW", DESCRIPTIONS['review_guide'], self._on_review_training_guide),
# button_item("Change Language", "CHANGE", callback=self._show_language_selection, enabled=ui_state.is_offroad),
# dual_button_item("Reboot", "Power Off", left_callback=self._reboot_prompt, right_callback=self._power_off_prompt),
]
# regulatory_btn.set_visible(TICI)
return items
def _render(self, _):
self._scroller.render(self._rect)
# gui_label(rect, "Advanced Network Settings (Not Implemented)", font_size=50, alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER)
class WifiManagerUI(Widget):
def __init__(self, wifi_manager: WifiManager):
super().__init__()
@ -213,7 +323,7 @@ class WifiManagerUI(Widget):
self._networks = networks
for n in self._networks:
self._networks_buttons[n.ssid] = Button(n.ssid, partial(self._networks_buttons_callback, n), font_size=55, text_alignment=TextAlignment.LEFT,
button_style=ButtonStyle.NO_EFFECT)
button_style=ButtonStyle.TRANSPARENT_WHITE)
self._forget_networks_buttons[n.ssid] = Button("Forget", partial(self._forget_networks_buttons_callback, n), button_style=ButtonStyle.FORGET_WIFI,
font_size=45)
@ -237,6 +347,7 @@ class WifiManagerUI(Widget):
self.state = UIState.IDLE
def main():
gui_app.init_window("Wi-Fi Manager")
wifi_ui = WifiManagerUI(WifiManager())

Loading…
Cancel
Save