ui: handle custom steering button on comma 4

This commit is contained in:
royjr
2026-08-16 16:18:09 -04:00
parent 83999585ec
commit 1a75c53ea4
4 changed files with 38 additions and 34 deletions
+25
View File
@@ -0,0 +1,25 @@
from enum import IntEnum
from opendbc.car.structs import car
class CustomButtonAction(IntEnum):
NONE = 0
BOOKMARK = 1
QUIET_MODE = 2
def handle_custom_button(sm, params, bookmark_callback):
if not sm.updated['carState']:
return
custom_pressed = any(be.type == car.CarState.ButtonEvent.Type.altButton2 and be.pressed
for be in sm['carState'].buttonEvents)
if not custom_pressed:
return
action = CustomButtonAction(params.get('SteeringCustomButtonMapping', return_default=True))
if action == CustomButtonAction.BOOKMARK:
bookmark_callback()
elif action == CustomButtonAction.QUIET_MODE:
params.put_bool('QuietMode', not params.get_bool('QuietMode'))
+2 -23
View File
@@ -1,9 +1,9 @@
import pyray as rl
from enum import IntEnum
import openpilot.cereal.messaging as messaging
from opendbc.car.structs import car
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.widgets import Widget
from openpilot.selfdrive.ui.custom_button import handle_custom_button
from openpilot.selfdrive.ui.layouts.sidebar import Sidebar, SIDEBAR_WIDTH
from openpilot.selfdrive.ui.layouts.home import HomeLayout
from openpilot.selfdrive.ui.layouts.settings.settings import SettingsLayout, PanelType
@@ -23,12 +23,6 @@ class MainState(IntEnum):
ONROAD = 2
class CustomButtonAction(IntEnum):
NONE = 0
BOOKMARK = 1
QUIET_MODE = 2
class MainLayout(Widget):
def __init__(self):
super().__init__()
@@ -62,7 +56,7 @@ class MainLayout(Widget):
gui_app.push_widget(self._onboarding_window)
def _render(self, _):
self._handle_custom_button()
handle_custom_button(ui_state.sm, ui_state.params, self._on_bookmark_clicked)
self._handle_onroad_transition()
self._render_main_content()
@@ -127,21 +121,6 @@ class MainLayout(Widget):
msg = messaging.new_message(service, valid=True)
self._pm.send(service, msg)
def _handle_custom_button(self):
if not ui_state.sm.updated['carState']:
return
custom_pressed = any(be.type == car.CarState.ButtonEvent.Type.altButton2 and be.pressed
for be in ui_state.sm['carState'].buttonEvents)
if not custom_pressed:
return
action = CustomButtonAction(ui_state.params.get('SteeringCustomButtonMapping', return_default=True))
if action == CustomButtonAction.BOOKMARK:
self._on_bookmark_clicked()
elif action == CustomButtonAction.QUIET_MODE:
ui_state.params.put_bool('QuietMode', not ui_state.params.get_bool('QuietMode'))
def _on_onroad_clicked(self):
self._sidebar.set_visible(not self._sidebar.is_visible)
@@ -4,6 +4,7 @@ from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout
from openpilot.selfdrive.ui.mici.layouts.settings.settings import SettingsLayout
from openpilot.selfdrive.ui.mici.layouts.offroad_alerts import MiciOffroadAlerts
from openpilot.selfdrive.ui.mici.onroad.augmented_road_view import AugmentedRoadView
from openpilot.selfdrive.ui.custom_button import handle_custom_button
from openpilot.selfdrive.ui.ui_state import device, ui_state
from openpilot.selfdrive.ui.mici.layouts.onboarding import OnboardingWindow
from openpilot.selfdrive.ui.body.layouts.onroad import BodyLayout
@@ -95,6 +96,8 @@ class MiciMainLayout(Scroller):
self._alerts_layout._update_state()
def _render(self, _):
handle_custom_button(ui_state.sm, ui_state.params, self._on_bookmark_clicked)
if not self._setup:
if self._alerts_layout.active_alerts() > 0:
self._scroller.scroll_to(self._alerts_layout.rect.x)
@@ -3,7 +3,7 @@ from unittest.mock import Mock
from opendbc.car.structs import car
from openpilot.selfdrive.ui.layouts import main
from openpilot.selfdrive.ui.custom_button import CustomButtonAction, handle_custom_button
class FakeSubMaster:
@@ -15,7 +15,7 @@ class FakeSubMaster:
return self.messages[key]
def test_custom_button_actions(monkeypatch):
def test_custom_button_actions():
params = Mock()
params.get_bool.return_value = False
sm = FakeSubMaster({
@@ -24,15 +24,12 @@ def test_custom_button_actions(monkeypatch):
pressed=True,
)]),
})
monkeypatch.setattr(main, 'ui_state', SimpleNamespace(sm=sm, params=params))
bookmark_callback = Mock()
layout = main.MainLayout.__new__(main.MainLayout)
layout._on_bookmark_clicked = Mock()
params.get.return_value = CustomButtonAction.BOOKMARK
handle_custom_button(sm, params, bookmark_callback)
bookmark_callback.assert_called_once()
params.get.return_value = main.CustomButtonAction.BOOKMARK
layout._handle_custom_button()
layout._on_bookmark_clicked.assert_called_once()
params.get.return_value = main.CustomButtonAction.QUIET_MODE
layout._handle_custom_button()
params.get.return_value = CustomButtonAction.QUIET_MODE
handle_custom_button(sm, params, bookmark_callback)
params.put_bool.assert_called_once_with('QuietMode', True)