|
|
|
@ -2,11 +2,11 @@ from dataclasses import dataclass |
|
|
|
|
from typing import Literal |
|
|
|
|
|
|
|
|
|
import pyray as rl |
|
|
|
|
from openpilot.system.ui.lib.wifi_manager import NetworkInfo, WifiManagerCallbacks, WifiManagerWrapper |
|
|
|
|
from openpilot.system.ui.lib.application import gui_app |
|
|
|
|
from openpilot.system.ui.lib.button import gui_button |
|
|
|
|
from openpilot.system.ui.lib.label import gui_label |
|
|
|
|
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel |
|
|
|
|
from openpilot.system.ui.lib.wifi_manager import NetworkInfo, WifiManagerCallbacks, WifiManagerWrapper, SecurityType |
|
|
|
|
from openpilot.system.ui.widgets.keyboard import Keyboard |
|
|
|
|
from openpilot.system.ui.widgets.confirm_dialog import confirm_dialog |
|
|
|
|
|
|
|
|
@ -14,7 +14,14 @@ NM_DEVICE_STATE_NEED_AUTH = 60 |
|
|
|
|
MIN_PASSWORD_LENGTH = 8 |
|
|
|
|
MAX_PASSWORD_LENGTH = 64 |
|
|
|
|
ITEM_HEIGHT = 160 |
|
|
|
|
ICON_SIZE = 49 |
|
|
|
|
|
|
|
|
|
STRENGTH_ICONS = [ |
|
|
|
|
"icons/wifi_strength_low.png", |
|
|
|
|
"icons/wifi_strength_medium.png", |
|
|
|
|
"icons/wifi_strength_high.png", |
|
|
|
|
"icons/wifi_strength_full.png", |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
@dataclass |
|
|
|
|
class StateIdle: |
|
|
|
@ -109,14 +116,14 @@ class WifiManagerUI: |
|
|
|
|
rl.end_scissor_mode() |
|
|
|
|
|
|
|
|
|
def _draw_network_item(self, rect, network: NetworkInfo, clicked: bool): |
|
|
|
|
label_rect = rl.Rectangle(rect.x, rect.y, rect.width - self.btn_width * 2, ITEM_HEIGHT) |
|
|
|
|
state_rect = rl.Rectangle(rect.x + rect.width - self.btn_width * 2 - 150, rect.y, 300, ITEM_HEIGHT) |
|
|
|
|
spacing = 50 |
|
|
|
|
ssid_rect = rl.Rectangle(rect.x, rect.y, rect.width - self.btn_width * 2, 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) |
|
|
|
|
|
|
|
|
|
gui_label(label_rect, network.ssid, 55) |
|
|
|
|
gui_label(ssid_rect, network.ssid, 55) |
|
|
|
|
|
|
|
|
|
status_text = "" |
|
|
|
|
if network.is_connected: |
|
|
|
|
status_text = "Connected" |
|
|
|
|
match self.state: |
|
|
|
|
case StateConnecting(network=connecting): |
|
|
|
|
if connecting.ssid == network.ssid: |
|
|
|
@ -124,26 +131,49 @@ class WifiManagerUI: |
|
|
|
|
case StateForgetting(network=forgetting): |
|
|
|
|
if forgetting.ssid == network.ssid: |
|
|
|
|
status_text = "FORGETTING..." |
|
|
|
|
|
|
|
|
|
if status_text: |
|
|
|
|
rl.gui_label(state_rect, status_text) |
|
|
|
|
|
|
|
|
|
# If the network is saved, show the "Forget" button |
|
|
|
|
if network.is_saved: |
|
|
|
|
forget_btn_rect = rl.Rectangle( |
|
|
|
|
rect.x + rect.width - self.btn_width, |
|
|
|
|
rect.y + (ITEM_HEIGHT - 80) / 2, |
|
|
|
|
self.btn_width, |
|
|
|
|
80, |
|
|
|
|
) |
|
|
|
|
if isinstance(self.state, StateIdle) and gui_button(forget_btn_rect, "Forget") and clicked: |
|
|
|
|
self.state = StateShowForgetConfirm(network) |
|
|
|
|
|
|
|
|
|
if isinstance(self.state, StateIdle) and rl.check_collision_point_rec(rl.get_mouse_position(), label_rect) and clicked: |
|
|
|
|
status_text_rect = rl.Rectangle(security_icon_rect.x - 410, rect.y, 410, ITEM_HEIGHT) |
|
|
|
|
rl.gui_label(status_text_rect, status_text) |
|
|
|
|
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, |
|
|
|
|
rect.y + (ITEM_HEIGHT - 80) / 2, |
|
|
|
|
self.btn_width, |
|
|
|
|
80, |
|
|
|
|
) |
|
|
|
|
if isinstance(self.state, StateIdle) and gui_button(forget_btn_rect, "Forget") and clicked: |
|
|
|
|
self.state = StateShowForgetConfirm(network) |
|
|
|
|
|
|
|
|
|
self._draw_status_icon(security_icon_rect, network) |
|
|
|
|
self._draw_signal_strength_icon(signal_icon_rect, network) |
|
|
|
|
|
|
|
|
|
if isinstance(self.state, StateIdle) and rl.check_collision_point_rec(rl.get_mouse_position(), ssid_rect) and clicked: |
|
|
|
|
if not network.is_saved: |
|
|
|
|
self.state = StateNeedsAuth(network) |
|
|
|
|
else: |
|
|
|
|
self.connect_to_network(network) |
|
|
|
|
|
|
|
|
|
def _draw_status_icon(self, rect, network: NetworkInfo): |
|
|
|
|
"""Draw the status icon based on network's connection state""" |
|
|
|
|
icon_file = "" |
|
|
|
|
if network.is_connected: |
|
|
|
|
icon_file = "icons/checkmark.png" |
|
|
|
|
elif network.security_type == SecurityType.UNSUPPORTED: |
|
|
|
|
icon_file = "icons/circled_slash.png" |
|
|
|
|
else: |
|
|
|
|
icon_file = "icons/lock_closed.png" |
|
|
|
|
|
|
|
|
|
texture = gui_app.texture(icon_file, ICON_SIZE, ICON_SIZE) |
|
|
|
|
icon_rect = rl.Vector2(rect.x, rect.y + (ICON_SIZE - texture.height) / 2) |
|
|
|
|
rl.draw_texture_v(texture, icon_rect, rl.WHITE) |
|
|
|
|
|
|
|
|
|
def _draw_signal_strength_icon(self, rect: rl.Rectangle, network: NetworkInfo): |
|
|
|
|
"""Draw the Wi-Fi signal strength icon based on network's signal strength""" |
|
|
|
|
strength_level = max(0, min(3, round(network.strength / 33.0))) |
|
|
|
|
rl.draw_texture_v(gui_app.texture(STRENGTH_ICONS[strength_level], ICON_SIZE, ICON_SIZE), rl.Vector2(rect.x, rect.y), rl.WHITE) |
|
|
|
|
|
|
|
|
|
def connect_to_network(self, network: NetworkInfo, password=''): |
|
|
|
|
self.state = StateConnecting(network) |
|
|
|
|
if network.is_saved and not password: |
|
|
|
|