mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 08:14:00 +08:00
raylib: dismiss dialog on pair (#36205)
* show for unknown * use Button to make clicking work * close on pair * close on pair * make widget! * dynamic pairing btn * whyyy * clean up * can do this * this button is also hard to tap
This commit is contained in:
@@ -44,10 +44,13 @@ class DeviceLayout(Widget):
|
||||
dongle_id = self._params.get("DongleId") or "N/A"
|
||||
serial = self._params.get("HardwareSerial") or "N/A"
|
||||
|
||||
self._pair_device_btn = button_item("Pair Device", "PAIR", DESCRIPTIONS['pair_device'], callback=self._pair_device)
|
||||
self._pair_device_btn.set_visible(lambda: not ui_state.prime_state.is_paired())
|
||||
|
||||
items = [
|
||||
text_item("Dongle ID", dongle_id),
|
||||
text_item("Serial", serial),
|
||||
button_item("Pair Device", "PAIR", DESCRIPTIONS['pair_device'], callback=self._pair_device),
|
||||
self._pair_device_btn,
|
||||
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),
|
||||
|
||||
@@ -11,14 +11,14 @@ from openpilot.selfdrive.ui.lib.api_helpers import get_token
|
||||
|
||||
|
||||
class PrimeType(IntEnum):
|
||||
UNKNOWN = -2,
|
||||
UNPAIRED = -1,
|
||||
NONE = 0,
|
||||
MAGENTA = 1,
|
||||
LITE = 2,
|
||||
BLUE = 3,
|
||||
MAGENTA_NEW = 4,
|
||||
PURPLE = 5,
|
||||
UNKNOWN = -2
|
||||
UNPAIRED = -1
|
||||
NONE = 0
|
||||
MAGENTA = 1
|
||||
LITE = 2
|
||||
BLUE = 3
|
||||
MAGENTA_NEW = 4
|
||||
PURPLE = 5
|
||||
|
||||
|
||||
class PrimeState:
|
||||
@@ -96,5 +96,9 @@ class PrimeState:
|
||||
with self._lock:
|
||||
return bool(self.prime_type > PrimeType.NONE)
|
||||
|
||||
def is_paired(self) -> bool:
|
||||
with self._lock:
|
||||
return self.prime_type > PrimeType.UNPAIRED
|
||||
|
||||
def __del__(self):
|
||||
self.stop()
|
||||
|
||||
+4
-5
@@ -10,15 +10,14 @@ def main():
|
||||
gui_app.init_window("UI")
|
||||
main_layout = MainLayout()
|
||||
main_layout.set_rect(rl.Rectangle(0, 0, gui_app.width, gui_app.height))
|
||||
for _ in gui_app.render():
|
||||
for showing_dialog in gui_app.render():
|
||||
ui_state.update()
|
||||
|
||||
# TODO handle brigntness and awake state here
|
||||
|
||||
main_layout.render()
|
||||
|
||||
kick_watchdog()
|
||||
|
||||
if not showing_dialog:
|
||||
main_layout.render()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -6,17 +6,20 @@ import time
|
||||
from openpilot.common.api import Api
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.lib.application import FontWeight, gui_app
|
||||
from openpilot.system.ui.lib.wrap_text import wrap_text
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
|
||||
|
||||
class PairingDialog:
|
||||
class PairingDialog(Widget):
|
||||
"""Dialog for device pairing with QR code."""
|
||||
|
||||
QR_REFRESH_INTERVAL = 300 # 5 minutes in seconds
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.params = Params()
|
||||
self.qr_texture: rl.Texture | None = None
|
||||
self.last_qr_generation = 0
|
||||
@@ -60,7 +63,11 @@ class PairingDialog:
|
||||
self._generate_qr_code()
|
||||
self.last_qr_generation = current_time
|
||||
|
||||
def render(self, rect: rl.Rectangle) -> int:
|
||||
def _update_state(self):
|
||||
if ui_state.prime_state.is_paired():
|
||||
gui_app.set_modal_overlay(None)
|
||||
|
||||
def _render(self, rect: rl.Rectangle) -> int:
|
||||
rl.clear_background(rl.Color(224, 224, 224, 255))
|
||||
|
||||
self._check_qr_refresh()
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import pyray as rl
|
||||
from openpilot.selfdrive.ui.lib.prime_state import PrimeType
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.selfdrive.ui.widgets.pairing_dialog import PairingDialog
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
from openpilot.system.ui.lib.wrap_text import wrap_text
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.widgets.button import gui_button, ButtonStyle
|
||||
from openpilot.system.ui.widgets.button import Button, ButtonStyle
|
||||
|
||||
|
||||
class SetupWidget(Widget):
|
||||
@@ -13,12 +12,15 @@ class SetupWidget(Widget):
|
||||
super().__init__()
|
||||
self._open_settings_callback = None
|
||||
self._pairing_dialog: PairingDialog | None = None
|
||||
self._pair_device_btn = Button("Pair device", self._show_pairing, button_style=ButtonStyle.PRIMARY)
|
||||
self._open_settings_btn = Button("Open", lambda: self._open_settings_callback() if self._open_settings_callback else None,
|
||||
button_style=ButtonStyle.PRIMARY)
|
||||
|
||||
def set_open_settings_callback(self, callback):
|
||||
self._open_settings_callback = callback
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
if ui_state.prime_state.get_type() == PrimeType.UNPAIRED:
|
||||
if not ui_state.prime_state.is_paired():
|
||||
self._render_registration(rect)
|
||||
else:
|
||||
self._render_firehose_prompt(rect)
|
||||
@@ -46,8 +48,7 @@ class SetupWidget(Widget):
|
||||
y += 50
|
||||
|
||||
button_rect = rl.Rectangle(x, y + 50, w, 128)
|
||||
if gui_button(button_rect, "Pair device", button_style=ButtonStyle.PRIMARY):
|
||||
self._show_pairing()
|
||||
self._pair_device_btn.render(button_rect)
|
||||
|
||||
def _render_firehose_prompt(self, rect: rl.Rectangle):
|
||||
"""Render firehose prompt widget."""
|
||||
@@ -80,9 +81,7 @@ class SetupWidget(Widget):
|
||||
# Open button
|
||||
button_height = 48 + 64 # font size + padding
|
||||
button_rect = rl.Rectangle(x, y, w, button_height)
|
||||
if gui_button(button_rect, "Open", button_style=ButtonStyle.PRIMARY):
|
||||
if self._open_settings_callback:
|
||||
self._open_settings_callback()
|
||||
self._open_settings_btn.render(button_rect)
|
||||
|
||||
def _show_pairing(self):
|
||||
if not self._pairing_dialog:
|
||||
|
||||
@@ -274,8 +274,9 @@ class GuiApplication:
|
||||
self._modal_overlay = ModalOverlay()
|
||||
if original_modal.callback is not None:
|
||||
original_modal.callback(result)
|
||||
yield True
|
||||
else:
|
||||
yield
|
||||
yield False
|
||||
|
||||
if self._render_texture:
|
||||
rl.end_texture_mode()
|
||||
|
||||
@@ -27,7 +27,7 @@ class Scroller(Widget):
|
||||
super().__init__()
|
||||
self._items: list[Widget] = []
|
||||
self._spacing = spacing
|
||||
self._line_separator = line_separator
|
||||
self._line_separator = LineSeparator() if line_separator else None
|
||||
self._pad_end = pad_end
|
||||
|
||||
self.scroll_panel = GuiScrollPanel()
|
||||
@@ -36,14 +36,19 @@ class Scroller(Widget):
|
||||
self.add_widget(item)
|
||||
|
||||
def add_widget(self, item: Widget) -> None:
|
||||
if self._line_separator and len(self._items) > 0:
|
||||
self._items.append(LineSeparator())
|
||||
self._items.append(item)
|
||||
item.set_touch_valid_callback(self.scroll_panel.is_touch_valid)
|
||||
|
||||
def _render(self, _):
|
||||
# TODO: don't draw items that are not in the viewport
|
||||
visible_items = [item for item in self._items if item.is_visible]
|
||||
|
||||
# Add line separator between items
|
||||
if self._line_separator is not None:
|
||||
l = len(visible_items)
|
||||
for i in range(1, len(visible_items)):
|
||||
visible_items.insert(l - i, self._line_separator)
|
||||
|
||||
content_height = sum(item.rect.height for item in visible_items) + self._spacing * (len(visible_items))
|
||||
if not self._pad_end:
|
||||
content_height -= self._spacing
|
||||
|
||||
Reference in New Issue
Block a user