mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-12 12:52:13 +08:00
mici ui: wifi scanning card (#37564)
* start * yes * no more show * clean up
This commit is contained in:
@@ -3,7 +3,6 @@ import numpy as np
|
||||
import pyray as rl
|
||||
from collections.abc import Callable
|
||||
|
||||
from openpilot.common.filter_simple import FirstOrderFilter
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.selfdrive.ui.mici.widgets.dialog import BigInputDialog, BigConfirmationDialogV2
|
||||
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, LABEL_COLOR
|
||||
@@ -14,39 +13,26 @@ from openpilot.system.ui.lib.wifi_manager import WifiManager, Network, SecurityT
|
||||
|
||||
|
||||
class LoadingAnimation(Widget):
|
||||
HIDE_TIME = 4
|
||||
RADIUS = 8
|
||||
SPACING = 24 # center-to-center: diameter (16) + gap (8)
|
||||
Y_MAG = 11.2
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._opacity_filter = FirstOrderFilter(0.0, 0.1, 1 / gui_app.target_fps)
|
||||
self._opacity_target = 1.0
|
||||
self._hide_time = 0.0
|
||||
|
||||
def show_event(self):
|
||||
self._opacity_target = 1.0
|
||||
self._hide_time = rl.get_time()
|
||||
w = self.SPACING * 2 + self.RADIUS * 2
|
||||
h = self.RADIUS * 2 + int(self.Y_MAG)
|
||||
self.set_rect(rl.Rectangle(0, 0, w, h))
|
||||
|
||||
def _render(self, _):
|
||||
if rl.get_time() - self._hide_time > self.HIDE_TIME:
|
||||
self._opacity_target = 0.0
|
||||
|
||||
self._opacity_filter.update(self._opacity_target)
|
||||
|
||||
if self._opacity_filter.x < 0.01:
|
||||
return
|
||||
|
||||
cx = int(self._rect.x + self._rect.width / 2)
|
||||
cy = int(self._rect.y + self._rect.height / 2)
|
||||
|
||||
y_mag = 7
|
||||
anim_scale = 4
|
||||
spacing = 14
|
||||
# Balls rest at bottom center; bounce upward
|
||||
base_x = int(self._rect.x + self._rect.width / 2)
|
||||
base_y = int(self._rect.y + self._rect.height - self.RADIUS)
|
||||
|
||||
for i in range(3):
|
||||
x = cx - spacing + i * spacing
|
||||
y = int(cy + min(math.sin((rl.get_time() - i * 0.2) * anim_scale) * y_mag, 0))
|
||||
alpha = int(np.interp(cy - y, [0, y_mag], [255 * 0.45, 255 * 0.9]) * self._opacity_filter.x)
|
||||
rl.draw_circle(x, y, 5, rl.Color(255, 255, 255, alpha))
|
||||
x = base_x + (i - 1) * self.SPACING
|
||||
y = int(base_y + min(math.sin((rl.get_time() - i * 0.2) * 4) * self.Y_MAG, 0))
|
||||
alpha = int(np.interp(base_y - y, [0, self.Y_MAG], [255 * 0.45, 255 * 0.9]))
|
||||
rl.draw_circle(x, y, self.RADIUS, rl.Color(255, 255, 255, alpha))
|
||||
|
||||
|
||||
class WifiIcon(Widget):
|
||||
@@ -270,11 +256,26 @@ class ForgetButton(Widget):
|
||||
rl.draw_texture_ex(self._trash_txt, (trash_x, trash_y), 0, 1.0, rl.WHITE)
|
||||
|
||||
|
||||
class ScanningButton(BigButton):
|
||||
def __init__(self):
|
||||
super().__init__("", "searching for networks")
|
||||
self.set_enabled(False)
|
||||
self._loading_animation = LoadingAnimation()
|
||||
|
||||
def _draw_content(self, btn_y: float):
|
||||
super()._draw_content(btn_y)
|
||||
anim = self._loading_animation
|
||||
x = self._rect.x + self._rect.width - anim.rect.width - 40
|
||||
y = btn_y + self._rect.height - anim.rect.height - 30
|
||||
anim.set_position(x, y)
|
||||
anim.render()
|
||||
|
||||
|
||||
class WifiUIMici(NavScroller):
|
||||
def __init__(self, wifi_manager: WifiManager):
|
||||
super().__init__()
|
||||
|
||||
self._loading_animation = LoadingAnimation()
|
||||
self._scanning_btn = ScanningButton()
|
||||
|
||||
self._wifi_manager = wifi_manager
|
||||
self._networks: dict[str, Network] = {}
|
||||
@@ -288,9 +289,9 @@ class WifiUIMici(NavScroller):
|
||||
def show_event(self):
|
||||
# Clear scroller items and update from latest scan results
|
||||
super().show_event()
|
||||
self._loading_animation.show_event()
|
||||
self._wifi_manager.set_active(True)
|
||||
self._scroller.items.clear()
|
||||
self._scroller.add_widget(self._scanning_btn)
|
||||
# trigger button update on latest sorted networks
|
||||
self._on_network_updated(self._wifi_manager.networks)
|
||||
|
||||
@@ -310,6 +311,11 @@ class WifiUIMici(NavScroller):
|
||||
btn.set_click_callback(lambda ssid=network.ssid: self._connect_to_network(ssid))
|
||||
self._scroller.add_widget(btn)
|
||||
|
||||
# Keep scanning button at the end
|
||||
items = self._scroller.items
|
||||
if self._scanning_btn in items:
|
||||
items.append(items.pop(items.index(self._scanning_btn)))
|
||||
|
||||
# Mark networks no longer in scan results (display handled by _update_state)
|
||||
for btn in self._scroller.items:
|
||||
if isinstance(btn, WifiButton) and btn.network.ssid not in self._networks:
|
||||
@@ -371,16 +377,4 @@ class WifiUIMici(NavScroller):
|
||||
|
||||
self._move_network_to_front(self._wifi_manager.wifi_state.ssid)
|
||||
|
||||
# Show loading animation near end
|
||||
max_scroll = max(self._scroller.content_size - self._scroller.rect.width, 1)
|
||||
progress = -self._scroller.scroll_panel.get_offset() / max_scroll
|
||||
if progress > 0.8 or len(self._scroller.items) <= 1:
|
||||
self._loading_animation.show_event()
|
||||
|
||||
def _render(self, _):
|
||||
super()._render(self._rect)
|
||||
|
||||
anim_w = 90
|
||||
anim_x = self._rect.x + self._rect.width - anim_w
|
||||
anim_y = self._rect.y + self._rect.height - 25 + 2
|
||||
self._loading_animation.render(rl.Rectangle(anim_x, anim_y, anim_w, 20))
|
||||
|
||||
Reference in New Issue
Block a user