mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-05 16:26:06 +08:00
ui: adapt network to raylib touch api (#35881)
* start * for now * con * more
This commit is contained in:
@@ -15,6 +15,7 @@ class ButtonStyle(IntEnum):
|
||||
TRANSPARENT = 3 # For buttons with transparent background and border
|
||||
ACTION = 4
|
||||
LIST_ACTION = 5 # For list items with action buttons
|
||||
NO_EFFECT = 6
|
||||
|
||||
|
||||
class TextAlignment(IntEnum):
|
||||
@@ -36,6 +37,7 @@ BUTTON_TEXT_COLOR = {
|
||||
ButtonStyle.TRANSPARENT: rl.BLACK,
|
||||
ButtonStyle.ACTION: rl.Color(0, 0, 0, 255),
|
||||
ButtonStyle.LIST_ACTION: rl.Color(228, 228, 228, 255),
|
||||
ButtonStyle.NO_EFFECT: rl.Color(228, 228, 228, 255),
|
||||
}
|
||||
|
||||
BUTTON_BACKGROUND_COLORS = {
|
||||
@@ -45,6 +47,7 @@ BUTTON_BACKGROUND_COLORS = {
|
||||
ButtonStyle.TRANSPARENT: rl.BLACK,
|
||||
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),
|
||||
}
|
||||
|
||||
BUTTON_PRESSED_BACKGROUND_COLORS = {
|
||||
@@ -54,6 +57,7 @@ BUTTON_PRESSED_BACKGROUND_COLORS = {
|
||||
ButtonStyle.TRANSPARENT: rl.BLACK,
|
||||
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),
|
||||
}
|
||||
|
||||
_pressed_buttons: set[str] = set() # Track mouse press state globally
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import pyray as rl
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.widgets import DialogResult
|
||||
from openpilot.system.ui.widgets.button import gui_button, ButtonStyle
|
||||
from openpilot.system.ui.widgets.button import gui_button, ButtonStyle, Button
|
||||
from openpilot.system.ui.widgets.label import gui_text_box
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
|
||||
DIALOG_WIDTH = 1520
|
||||
DIALOG_HEIGHT = 600
|
||||
@@ -11,6 +12,63 @@ MARGIN = 50
|
||||
TEXT_AREA_HEIGHT_REDUCTION = 200
|
||||
BACKGROUND_COLOR = rl.Color(27, 27, 27, 255)
|
||||
|
||||
class ConfirmDialog(Widget):
|
||||
def __init__(self, text: str, confirm_text: str, cancel_text: str = "Cancel"):
|
||||
super().__init__()
|
||||
self.text = text
|
||||
self._cancel_button = Button(cancel_text, self._cancel_button_callback)
|
||||
self._confirm_button = Button(confirm_text, self._confirm_button_callback, button_style=ButtonStyle.PRIMARY)
|
||||
self._dialog_result = DialogResult.NO_ACTION
|
||||
self._cancel_text = cancel_text
|
||||
|
||||
def reset(self):
|
||||
self._dialog_result = DialogResult.NO_ACTION
|
||||
|
||||
def _cancel_button_callback(self):
|
||||
self._dialog_result = DialogResult.CANCEL
|
||||
|
||||
def _confirm_button_callback(self):
|
||||
self._dialog_result = DialogResult.CONFIRM
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
dialog_x = (gui_app.width - DIALOG_WIDTH) / 2
|
||||
dialog_y = (gui_app.height - DIALOG_HEIGHT) / 2
|
||||
dialog_rect = rl.Rectangle(dialog_x, dialog_y, DIALOG_WIDTH, DIALOG_HEIGHT)
|
||||
|
||||
bottom = dialog_rect.y + dialog_rect.height
|
||||
button_width = (dialog_rect.width - 3 * MARGIN) // 2
|
||||
cancel_button_x = dialog_rect.x + MARGIN
|
||||
confirm_button_x = dialog_rect.x + dialog_rect.width - button_width - MARGIN
|
||||
button_y = bottom - BUTTON_HEIGHT - MARGIN
|
||||
cancel_button = rl.Rectangle(cancel_button_x, button_y, button_width, BUTTON_HEIGHT)
|
||||
confirm_button = rl.Rectangle(confirm_button_x, button_y, button_width, BUTTON_HEIGHT)
|
||||
|
||||
rl.draw_rectangle_rec(dialog_rect, BACKGROUND_COLOR)
|
||||
|
||||
text_rect = rl.Rectangle(dialog_rect.x + MARGIN, dialog_rect.y, dialog_rect.width - 2 * MARGIN, dialog_rect.height - TEXT_AREA_HEIGHT_REDUCTION)
|
||||
gui_text_box(
|
||||
text_rect,
|
||||
self.text,
|
||||
font_size=70,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
alignment_vertical=rl.GuiTextAlignmentVertical.TEXT_ALIGN_MIDDLE,
|
||||
font_weight=FontWeight.BOLD,
|
||||
)
|
||||
|
||||
if rl.is_key_pressed(rl.KeyboardKey.KEY_ENTER):
|
||||
self._dialog_result = DialogResult.CONFIRM
|
||||
elif rl.is_key_pressed(rl.KeyboardKey.KEY_ESCAPE):
|
||||
self._dialog_result = DialogResult.CANCEL
|
||||
|
||||
if self._cancel_text:
|
||||
self._confirm_button.render(confirm_button)
|
||||
self._cancel_button.render(cancel_button)
|
||||
else:
|
||||
centered_button_x = dialog_rect.x + (dialog_rect.width - button_width) / 2
|
||||
centered_confirm_button = rl.Rectangle(centered_button_x, button_y, button_width, BUTTON_HEIGHT)
|
||||
self._confirm_button.render(centered_confirm_button)
|
||||
|
||||
return self._dialog_result
|
||||
|
||||
def confirm_dialog(message: str, confirm_text: str, cancel_text: str = "Cancel") -> DialogResult:
|
||||
dialog_x = (gui_app.width - DIALOG_WIDTH) / 2
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from dataclasses import dataclass
|
||||
from functools import partial
|
||||
from threading import Lock
|
||||
from typing import Literal
|
||||
|
||||
@@ -7,8 +8,8 @@ from openpilot.system.ui.lib.application import gui_app
|
||||
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 import Widget
|
||||
from openpilot.system.ui.widgets.button import ButtonStyle, gui_button
|
||||
from openpilot.system.ui.widgets.confirm_dialog import confirm_dialog
|
||||
from openpilot.system.ui.widgets.button import ButtonStyle, Button, TextAlignment
|
||||
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.keyboard import Keyboard
|
||||
from openpilot.system.ui.widgets.label import gui_label
|
||||
|
||||
@@ -67,8 +68,11 @@ class WifiManagerUI(Widget):
|
||||
self.keyboard = Keyboard(max_text_size=MAX_PASSWORD_LENGTH, min_text_size=MIN_PASSWORD_LENGTH, show_password_toggle=True)
|
||||
|
||||
self._networks: list[NetworkInfo] = []
|
||||
self._networks_buttons: dict[str, Button] = {}
|
||||
self._forget_networks_buttons: dict[str, Button] = {}
|
||||
self._lock = Lock()
|
||||
self.wifi_manager = wifi_manager
|
||||
self._confirm_dialog = ConfirmDialog("", "Forget", "Cancel")
|
||||
|
||||
self.wifi_manager.set_callbacks(
|
||||
WifiManagerCallbacks(
|
||||
@@ -91,10 +95,12 @@ class WifiManagerUI(Widget):
|
||||
match self.state:
|
||||
case StateNeedsAuth(network):
|
||||
self.keyboard.set_title("Enter password", f"for {network.ssid}")
|
||||
self.keyboard.reset()
|
||||
gui_app.set_modal_overlay(self.keyboard, lambda result: self._on_password_entered(network, result))
|
||||
case StateShowForgetConfirm(network):
|
||||
gui_app.set_modal_overlay(lambda: confirm_dialog(f'Forget Wi-Fi Network "{network.ssid}"?', "Forget"),
|
||||
callback=lambda result: self.on_forgot_confirm_finished(network, result))
|
||||
self._confirm_dialog.text = f'Forget Wi-Fi Network "{network.ssid}"?'
|
||||
self._confirm_dialog.reset()
|
||||
gui_app.set_modal_overlay(self._confirm_dialog, callback=lambda result: self.on_forgot_confirm_finished(network, result))
|
||||
case _:
|
||||
self._draw_network_list(rect)
|
||||
|
||||
@@ -139,7 +145,7 @@ class WifiManagerUI(Widget):
|
||||
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(ssid_rect, network.ssid, 55)
|
||||
self._networks_buttons[network.ssid].render(ssid_rect)
|
||||
|
||||
status_text = ""
|
||||
match self.state:
|
||||
@@ -162,18 +168,23 @@ class WifiManagerUI(Widget):
|
||||
self.btn_width,
|
||||
80,
|
||||
)
|
||||
if isinstance(self.state, StateIdle) and gui_button(forget_btn_rect, "Forget", button_style=ButtonStyle.ACTION) and clicked:
|
||||
self.state = StateShowForgetConfirm(network)
|
||||
self._forget_networks_buttons[network.ssid].render(forget_btn_rect)
|
||||
|
||||
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:
|
||||
def _networks_buttons_callback(self, network):
|
||||
if self.scroll_panel.is_touch_valid():
|
||||
if not network.is_saved and network.security_type != SecurityType.OPEN:
|
||||
self.state = StateNeedsAuth(network)
|
||||
elif not network.is_connected:
|
||||
self.connect_to_network(network)
|
||||
|
||||
def _forget_networks_buttons_callback(self, network):
|
||||
if self.scroll_panel.is_touch_valid():
|
||||
if isinstance(self.state, StateIdle):
|
||||
self.state = StateShowForgetConfirm(network)
|
||||
|
||||
def _draw_status_icon(self, rect, network: NetworkInfo):
|
||||
"""Draw the status icon based on network's connection state"""
|
||||
icon_file = None
|
||||
@@ -211,6 +222,10 @@ class WifiManagerUI(Widget):
|
||||
def _on_network_updated(self, networks: list[NetworkInfo]):
|
||||
with self._lock:
|
||||
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)
|
||||
self._forget_networks_buttons[n.ssid] = Button("Forget", partial(self._forget_networks_buttons_callback, n), button_style=ButtonStyle.ACTION)
|
||||
|
||||
def _on_need_auth(self, ssid):
|
||||
with self._lock:
|
||||
|
||||
Reference in New Issue
Block a user