Port `reset` to new raylib events handling (#35762)

* test

* more

* type

* type

* order

* _

* __
pull/35766/head
Maxime Desroches 4 days ago committed by GitHub
parent 48892e339d
commit 1936c42ee7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 58
      system/ui/reset.py
  2. 49
      system/ui/widgets/button.py

@ -1,14 +1,15 @@
#!/usr/bin/env python3
import os
import pyray as rl
import sys
import threading
from enum import IntEnum
import pyray as rl
from openpilot.system.hardware import PC
from openpilot.system.ui.lib.application import gui_app, FontWeight
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
from openpilot.system.ui.widgets.label import gui_label, gui_text_box
NVME = "/dev/nvme0n1"
@ -31,8 +32,15 @@ class ResetState(IntEnum):
class Reset(Widget):
def __init__(self, mode):
super().__init__()
self.mode = mode
self.reset_state = ResetState.NONE
self._mode = mode
self._reset_state = ResetState.NONE
self._cancel_button = Button("Cancel", self._cancel_callback)
self._confirm_button = Button("Confirm", self._confirm, button_style=ButtonStyle.PRIMARY)
self._reboot_button = Button("Reboot", lambda: os.system("sudo reboot"))
self._render_status = True
def _cancel_callback(self):
self._render_status = False
def _do_erase(self):
if PC:
@ -50,10 +58,10 @@ class Reset(Widget):
if rm == 0 or fmt == 0:
os.system("sudo reboot")
else:
self.reset_state = ResetState.FAILED
self._reset_state = ResetState.FAILED
def start_reset(self):
self.reset_state = ResetState.RESETTING
self._reset_state = ResetState.RESETTING
threading.Timer(0.1, self._do_erase).start()
def _render(self, rect: rl.Rectangle):
@ -61,42 +69,38 @@ class Reset(Widget):
gui_label(label_rect, "System Reset", 100, font_weight=FontWeight.BOLD)
text_rect = rl.Rectangle(rect.x + 140, rect.y + 140, rect.width - 280, rect.height - 90 - 100)
gui_text_box(text_rect, self.get_body_text(), 90)
gui_text_box(text_rect, self._get_body_text(), 90)
button_height = 160
button_spacing = 50
button_top = rect.y + rect.height - button_height
button_width = (rect.width - button_spacing) / 2.0
if self.reset_state != ResetState.RESETTING:
if self.mode == ResetMode.RECOVER or self.reset_state == ResetState.FAILED:
if gui_button(rl.Rectangle(rect.x, button_top, button_width, button_height), "Reboot"):
os.system("sudo reboot")
elif self.mode == ResetMode.USER_RESET:
if gui_button(rl.Rectangle(rect.x, button_top, button_width, button_height), "Cancel"):
return False
if self._reset_state != ResetState.RESETTING:
if self._mode == ResetMode.RECOVER or self._reset_state == ResetState.FAILED:
self._reboot_button.render(rl.Rectangle(rect.x, button_top, rect.width, button_height))
elif self._mode == ResetMode.USER_RESET:
self._cancel_button.render(rl.Rectangle(rect.x, button_top, button_width, button_height))
if self.reset_state != ResetState.FAILED:
if gui_button(rl.Rectangle(rect.x + button_width + 50, button_top, button_width, button_height),
"Confirm", button_style=ButtonStyle.PRIMARY):
self.confirm()
if self._reset_state != ResetState.FAILED:
self._confirm_button.render(rl.Rectangle(rect.x + button_width + 50, button_top, button_width, button_height))
return True
return self._render_status
def confirm(self):
if self.reset_state == ResetState.CONFIRM:
def _confirm(self):
if self._reset_state == ResetState.CONFIRM:
self.start_reset()
else:
self.reset_state = ResetState.CONFIRM
self._reset_state = ResetState.CONFIRM
def get_body_text(self):
if self.reset_state == ResetState.CONFIRM:
def _get_body_text(self):
if self._reset_state == ResetState.CONFIRM:
return "Are you sure you want to reset your device?"
if self.reset_state == ResetState.RESETTING:
if self._reset_state == ResetState.RESETTING:
return "Resetting device...\nThis may take up to a minute."
if self.reset_state == ResetState.FAILED:
if self._reset_state == ResetState.FAILED:
return "Reset failed. Reboot to try again."
if self.mode == ResetMode.RECOVER:
if self._mode == ResetMode.RECOVER:
return "Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device."
return "System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot."

@ -1,7 +1,11 @@
import pyray as rl
from collections.abc import Callable
from enum import IntEnum
from openpilot.system.ui.lib.application import gui_app, FontWeight
import pyray as rl
from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.widgets import Widget
class ButtonStyle(IntEnum):
@ -148,3 +152,44 @@ def gui_button(
rl.draw_text_ex(font, text, text_pos, font_size, 0, color)
return result
class Button(Widget):
def __init__(self,
text: str,
click_callback: Callable[[], None] = None,
font_size: int = DEFAULT_BUTTON_FONT_SIZE,
font_weight: FontWeight = FontWeight.MEDIUM,
button_style: ButtonStyle = ButtonStyle.NORMAL,
border_radius: int = 10,
):
super().__init__()
self._text = text
self._click_callback = click_callback
self._label_font = gui_app.font(FontWeight.SEMI_BOLD)
self._button_style = button_style
self._font_size = font_size
self._border_radius = border_radius
self._font_size = font_size
self._text_color = BUTTON_TEXT_COLOR[button_style]
self._text_size = measure_text_cached(gui_app.font(font_weight), text, font_size)
def _handle_mouse_release(self, mouse_pos: MousePos):
if self._click_callback:
print(f"Button clicked: {self._text}")
self._click_callback()
def _get_background_color(self) -> rl.Color:
if self._is_pressed:
return BUTTON_PRESSED_BACKGROUND_COLORS[self._button_style]
else:
return BUTTON_BACKGROUND_COLORS[self._button_style]
def _render(self, _):
roundness = self._border_radius / (min(self._rect.width, self._rect.height) / 2)
rl.draw_rectangle_rounded(self._rect, roundness, 10, self._get_background_color())
text_pos = rl.Vector2(0, self._rect.y + (self._rect.height - self._text_size.y) // 2)
text_pos.x = self._rect.x + (self._rect.width - self._text_size.x) // 2
rl.draw_text_ex(self._label_font, self._text, text_pos, self._font_size, 0, self._text_color)

Loading…
Cancel
Save