IQ.Pilot Release Commit @ 2f37564

This commit is contained in:
IQ.Lvbs CI [bot]
2026-07-27 01:30:19 -05:00
parent 6a4096e52e
commit 15c14e1369
236 changed files with 2475 additions and 990 deletions

View File

@@ -1,9 +1,9 @@
"""
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos
"""
from openpilot.system.ui.iqpilot.widgets.list_view import IQButtonAction
from openpilot.system.ui.iqwidgets.widgets.list_view import IQButtonAction
class NoElideButtonAction(IQButtonAction):
class WideButtonAction(IQButtonAction):
def get_width_hint(self):
return super().get_width_hint() + 1

View File

@@ -7,9 +7,9 @@ import time
from collections.abc import Callable
import pyray as rl
from openpilot.system.ui.iqpilot.lib.styles import ink, metrics
from openpilot.system.ui.iqwidgets.lib.styles import ink, metrics
from openpilot.system.ui.widgets.button import Button, ButtonStyle
from openpilot.system.ui.iqpilot.lib import canvas
from openpilot.system.ui.iqwidgets.lib import canvas
from openpilot.system.ui.widgets.scroller_tici import LineSeparator, LINE_COLOR, LINE_PADDING
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.widgets.toggle import Toggle
@@ -899,8 +899,8 @@ def progress_item(title):
from dataclasses import dataclass, field
from openpilot.common.params import Params
from openpilot.system.ui.iqpilot.lib.styles import ink
from openpilot.system.ui.iqpilot.widgets.helpers.glyphs import draw_star
from openpilot.system.ui.iqwidgets.lib.styles import ink
from openpilot.system.ui.iqwidgets.widgets.helpers.glyphs import draw_star
from openpilot.system.ui.lib.application import FontWeight, gui_app
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.multilang import tr
@@ -925,13 +925,13 @@ _FRAME_PAD = 50
@dataclass
class TreeNode:
class PickerItem:
ref: str
data: dict = field(default_factory=dict)
@dataclass
class TreeFolder:
class PickerGroup:
folder: str
nodes: list
@@ -999,7 +999,7 @@ class _TreeRow(Button):
return super()._handle_mouse_release(mouse_pos)
class TreeOptionDialog(MultiOptionDialog):
class PickerDialog(MultiOptionDialog):
"""Folder/leaf picker with search, favourites, and a pinned current selection."""
def __init__(self, title, folders, current_ref="", fav_param="", option_font_weight=FontWeight.MEDIUM, search_prompt=None,
@@ -1018,7 +1018,7 @@ class TreeOptionDialog(MultiOptionDialog):
self.on_exit = on_exit
self.display_func = display_func or (lambda node: node.data.get('display_name', node.ref))
self.search_funcs = search_funcs or [lambda node: node.data.get('display_name', ''), lambda node: node.data.get('short_name', '')]
self.search_title = search_title or tr("Enter search query")
self.search_title = search_title or tr("Type to search")
self.search_subtitle = search_subtitle
self._search_rect: rl.Rectangle | None = None
self._search_pressed = False

View File

@@ -26,7 +26,7 @@ from openpilot.system.hardware import HARDWARE, PC
from openpilot.system.ui.lib.multilang import multilang
from openpilot.common.realtime import Ratekeeper
from openpilot.system.ui.iqpilot.lib.application import IQAppHooks
from openpilot.system.ui.iqwidgets.lib.application import IQAppHooks
from openpilot.system.ui.lib.screen_recorder import ScreenRecorder
_DEFAULT_FPS = int(os.getenv("FPS", {'tizi': 20, 'tici': 20}.get(HARDWARE.get_device_type(), 60)))

View File

@@ -636,6 +636,7 @@ class WifiManager:
cloudlog.warning("No WiFi device found")
return
self._set_device_autoconnect(True)
self._connecting_to_ssid = ssid
self._router_main.send(new_method_call(self._nm, 'ActivateConnection', 'ooo',
(conn_path, self._wifi_device, "/")))
@@ -645,6 +646,37 @@ class WifiManager:
else:
threading.Thread(target=worker, daemon=True).start()
def disconnect_connection(self, ssid: str, block: bool = False):
def worker():
if self._router_main is None:
cloudlog.warning(f"WiFi not ready while disconnecting {ssid}")
return
if ssid not in self._get_connections():
return
# the profile stays saved and untouched; without clearing autoconnect on the device
# NetworkManager re-associates within seconds
self._set_device_autoconnect(False)
self._connecting_to_ssid = ""
self._deactivate_connection(ssid)
self._update_networks()
self._enqueue_callbacks(self._disconnected)
if block:
worker()
else:
threading.Thread(target=worker, daemon=True).start()
def _set_device_autoconnect(self, enabled: bool) -> None:
if self._router_main is None or self._wifi_device is None:
return
dev_addr = DBusAddress(self._wifi_device, bus_name=NM, interface=NM_DEVICE_IFACE)
reply = self._router_main.send_and_get_reply(Properties(dev_addr).set('Autoconnect', 'b', enabled))
if reply.header.message_type == MessageType.error:
cloudlog.warning(f'Failed to set device autoconnect={enabled}: {reply}')
def _deactivate_connection(self, ssid: str):
target_conn_path = self._get_connections().get(ssid, None)
if target_conn_path is None:

View File

@@ -17,10 +17,10 @@ from openpilot.system.ui.widgets.scroller_tici import Scroller
from openpilot.system.ui.widgets.list_view import ButtonAction, ListItem, MultipleButtonAction, ToggleAction, button_item, text_item
if gui_app.iqpilot_ui():
from openpilot.system.ui.iqpilot.widgets.list_view import button_item
from openpilot.system.ui.iqpilot.widgets.list_view import IQListItem as ListItem
from openpilot.system.ui.iqpilot.widgets.list_view import IQToggleAction as ToggleAction
from openpilot.system.ui.iqpilot.widgets.list_view import IQMultipleButtonAction as MultipleButtonAction
from openpilot.system.ui.iqwidgets.widgets.list_view import button_item
from openpilot.system.ui.iqwidgets.widgets.list_view import IQListItem as ListItem
from openpilot.system.ui.iqwidgets.widgets.list_view import IQToggleAction as ToggleAction
from openpilot.system.ui.iqwidgets.widgets.list_view import IQMultipleButtonAction as MultipleButtonAction
# These are only used for AdvancedNetworkSettings, standalone apps just need WifiManagerUI
try:
@@ -66,6 +66,7 @@ class UIState(IntEnum):
NEEDS_AUTH = 2
SHOW_FORGET_CONFIRM = 3
FORGETTING = 4
DISCONNECTING = 5
class NavButton(Widget):
@@ -328,6 +329,7 @@ class WifiManagerUI(Widget):
self._state_network: Network | None = None # for CONNECTING / NEEDS_AUTH / SHOW_FORGET_CONFIRM / FORGETTING
self._password_retry: bool = False # for NEEDS_AUTH
self.btn_width: int = 200
self.disconnect_btn_width: int = 300
self.scroll_panel = GuiScrollPanel()
self.keyboard = Keyboard(max_text_size=MAX_PASSWORD_LENGTH, min_text_size=MIN_PASSWORD_LENGTH, show_password_toggle=True)
self._load_icons()
@@ -335,6 +337,7 @@ class WifiManagerUI(Widget):
self._networks: list[Network] = []
self._networks_buttons: dict[str, Button] = {}
self._forget_networks_buttons: dict[str, Button] = {}
self._disconnect_networks_buttons: dict[str, Button] = {}
self._wifi_manager.add_callbacks(need_auth=self._on_need_auth,
activated=self._on_activated,
@@ -417,7 +420,9 @@ class WifiManagerUI(Widget):
def _draw_network_item(self, rect, network: Network):
spacing = 50
ssid_rect = rl.Rectangle(rect.x, rect.y, rect.width - self.btn_width * 2, ITEM_HEIGHT)
show_disconnect = network.is_connected and self.state not in (UIState.CONNECTING, UIState.DISCONNECTING)
reserved = self.btn_width * 2 + (self.disconnect_btn_width + spacing if show_disconnect else 0)
ssid_rect = rl.Rectangle(rect.x, rect.y, rect.width - reserved, ITEM_HEIGHT)
signal_icon_rect = rl.Rectangle(rect.x + rect.width - ICON_SIZE, rect.y + (ITEM_HEIGHT - ICON_SIZE) / 2, ICON_SIZE, ICON_SIZE)
security_icon_rect = rl.Rectangle(signal_icon_rect.x - spacing - ICON_SIZE, rect.y + (ITEM_HEIGHT - ICON_SIZE) / 2, ICON_SIZE, ICON_SIZE)
@@ -434,6 +439,10 @@ class WifiManagerUI(Widget):
if self._state_network.ssid == network.ssid:
self._networks_buttons[network.ssid].set_enabled(False)
status_text = tr("FORGETTING...")
elif self.state == UIState.DISCONNECTING and self._state_network:
if self._state_network.ssid == network.ssid:
self._networks_buttons[network.ssid].set_enabled(False)
status_text = tr("DISCONNECTING...")
elif network.security_type == SecurityType.UNSUPPORTED:
self._networks_buttons[network.ssid].set_enabled(False)
else:
@@ -455,6 +464,15 @@ class WifiManagerUI(Widget):
)
self._forget_networks_buttons[network.ssid].render(forget_btn_rect)
if show_disconnect:
disconnect_btn_rect = rl.Rectangle(
forget_btn_rect.x - self.btn_width - spacing,
forget_btn_rect.y,
self.btn_width,
80,
)
self._disconnect_networks_buttons[network.ssid].render(disconnect_btn_rect)
self._draw_status_icon(security_icon_rect, network)
self._draw_signal_strength_icon(signal_icon_rect, network)
@@ -470,6 +488,9 @@ class WifiManagerUI(Widget):
self.state = UIState.SHOW_FORGET_CONFIRM
self._state_network = network
def _disconnect_networks_buttons_callback(self, network):
self.disconnect_network(network)
def _draw_status_icon(self, rect, network: Network):
"""Draw the status icon based on network's connection state"""
icon_file = None
@@ -506,6 +527,11 @@ class WifiManagerUI(Widget):
self._state_network = network
self._wifi_manager.forget_connection(network.ssid)
def disconnect_network(self, network: Network):
self.state = UIState.DISCONNECTING
self._state_network = network
self._wifi_manager.disconnect_connection(network.ssid)
def _on_network_updated(self, networks: list[Network]):
self._networks = networks
for n in self._networks:
@@ -515,6 +541,9 @@ class WifiManagerUI(Widget):
self._forget_networks_buttons[n.ssid] = Button(tr("Forget"), partial(self._forget_networks_buttons_callback, n), button_style=ButtonStyle.FORGET_WIFI,
font_size=45)
self._forget_networks_buttons[n.ssid].set_touch_valid_callback(lambda: self.scroll_panel.is_touch_valid())
self._disconnect_networks_buttons[n.ssid] = Button(tr("Disconnect"), partial(self._disconnect_networks_buttons_callback, n),
button_style=ButtonStyle.FORGET_WIFI, font_size=45)
self._disconnect_networks_buttons[n.ssid].set_touch_valid_callback(lambda: self.scroll_panel.is_touch_valid())
def _on_need_auth(self, ssid):
network = next((n for n in self._networks if n.ssid == ssid), None)
@@ -532,7 +561,7 @@ class WifiManagerUI(Widget):
self.state = UIState.IDLE
def _on_disconnected(self):
if self.state == UIState.CONNECTING:
if self.state in (UIState.CONNECTING, UIState.DISCONNECTING):
self.state = UIState.IDLE