diff --git a/selfdrive/ui/mici/layouts/settings/device.py b/selfdrive/ui/mici/layouts/settings/device.py index a810a5d1a..b7ee5b6f4 100644 --- a/selfdrive/ui/mici/layouts/settings/device.py +++ b/selfdrive/ui/mici/layouts/settings/device.py @@ -117,6 +117,8 @@ class PairBigButton(BigButton): return 64 def _update_state(self): + super()._update_state() + if ui_state.prime_state.is_paired(): self.set_text("paired") if ui_state.prime_state.is_prime(): @@ -164,6 +166,8 @@ class UpdateOpenpilotBigButton(BigButton): self.set_enabled(True) def _handle_mouse_release(self, mouse_pos: MousePos): + super()._handle_mouse_release(mouse_pos) + if not system_time_valid(): dlg = BigDialog(tr("Please connect to Wi-Fi to update"), "") gui_app.push_widget(dlg) @@ -191,6 +195,8 @@ class UpdateOpenpilotBigButton(BigButton): self.set_text("update openpilot") def _update_state(self): + super()._update_state() + if ui_state.started: self.set_enabled(False) return diff --git a/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py b/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py index cc45daf24..22d3d1d0d 100644 --- a/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py +++ b/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py @@ -215,6 +215,8 @@ class WifiButton(BigButton): return self._wifi_manager.connected_ssid == self._network.ssid def _update_state(self): + super()._update_state() + if any((self._network_missing, self._is_connecting, self._is_connected, self._network_forgetting, self._network.security_type == SecurityType.UNSUPPORTED)): self.set_enabled(False) diff --git a/selfdrive/ui/mici/widgets/button.py b/selfdrive/ui/mici/widgets/button.py index 231dafa8e..b5bd65e2d 100644 --- a/selfdrive/ui/mici/widgets/button.py +++ b/selfdrive/ui/mici/widgets/button.py @@ -36,6 +36,7 @@ class BigCircleButton(Widget): # State self.set_rect(rl.Rectangle(0, 0, 180, 180)) self._scale_filter = BounceFilter(1.0, 0.1, 1 / gui_app.target_fps) + self._click_delay = 0.075 # Icons self._txt_icon = gui_app.texture(icon, *icon_size) @@ -117,6 +118,7 @@ class BigButton(Widget): self.set_icon(icon) self._scale_filter = BounceFilter(1.0, 0.1, 1 / gui_app.target_fps) + self._click_delay = 0.075 self._shake_start: float | None = None self._rotate_icon_t: float | None = None diff --git a/system/ui/widgets/__init__.py b/system/ui/widgets/__init__.py index 1e2f78381..568f58b98 100644 --- a/system/ui/widgets/__init__.py +++ b/system/ui/widgets/__init__.py @@ -30,6 +30,8 @@ class Widget(abc.ABC): self._enabled: bool | Callable[[], bool] = True self._is_visible: bool | Callable[[], bool] = True self._touch_valid_callback: Callable[[], bool] | None = None + self._click_delay: float | None = None # seconds to hold is_pressed after release + self._click_release_time: float | None = None self._click_callback: Callable[[], None] | None = None self._multi_touch = False self.__was_awake = True @@ -51,7 +53,8 @@ class Widget(abc.ABC): @property def is_pressed(self) -> bool: - return any(self.__is_pressed) + # if actually pressed or holding after release + return any(self.__is_pressed) or self._click_release_time is not None @property def enabled(self) -> bool: @@ -98,6 +101,9 @@ class Widget(abc.ABC): self._update_state() + if self._click_release_time is not None and rl.get_time() >= self._click_release_time: + self._click_release_time = None + if not self.is_visible: return None @@ -182,6 +188,8 @@ class Widget(abc.ABC): def _handle_mouse_release(self, mouse_pos: MousePos) -> None: """Optionally handle mouse release events.""" + if self._click_delay is not None: + self._click_release_time = rl.get_time() + self._click_delay if self._click_callback: self._click_callback()