diff --git a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py index d5f651e77..24e02f140 100644 --- a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py +++ b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py @@ -1005,7 +1005,13 @@ class StarPilotLongitudinalLayout(_SettingsPage): def _on_priority_clicked(self): primary_options = ["Dashboard", "Map Data", "Vision", "Highest", "Lowest"] + if not starpilot_state.car_state.hasDashSpeedLimits: + primary_options.remove("Dashboard") + current_primary = self._params.get("SLCPriority1", encoding="utf-8") or "Map Data" + if current_primary not in primary_options: + current_primary = primary_options[0] + current_secondary = self._params.get("SLCPriority2", encoding="utf-8") or "None" def on_secondary_select(primary, dialog, res): @@ -1015,6 +1021,8 @@ class StarPilotLongitudinalLayout(_SettingsPage): def show_secondary_dialog(primary): secondary_options = ["None"] + [option for option in ("Dashboard", "Map Data", "Vision") if option != primary] + if not starpilot_state.car_state.hasDashSpeedLimits and "Dashboard" in secondary_options: + secondary_options.remove("Dashboard") selected_secondary = current_secondary if current_secondary in secondary_options else "None" secondary_dialog = MultiOptionDialog(tr("SLC Secondary Priority"), secondary_options, selected_secondary, callback=lambda res: on_secondary_select(primary, secondary_dialog, res)) @@ -1141,6 +1149,15 @@ class StarPilotLongitudinalLayout(_SettingsPage): params so they read correctly in the new unit. The first call (no prior state) is a no-op so the user's saved values aren't rewritten on boot.""" current = self._is_metric() + + # Update offset row titles dynamically to reflect correct unit-specific bounds (parity with C++). + ranges_metric = ["0-29", "30-49", "50-59", "60-79", "80-99", "100-119", "120-140"] + ranges_imperial = ["0-24", "25-34", "35-44", "45-54", "55-64", "65-74", "75-99"] + unit = "km/h" if current else "mph" + ranges = ranges_metric if current else ranges_imperial + for i, row in enumerate(self._slc_offset_rows): + row.title = f"Speed Offset ({ranges[i]} {unit})" + last = self._last_is_metric self._last_is_metric = current if last is None or last == current: diff --git a/selfdrive/ui/layouts/settings/starpilot/panel.py b/selfdrive/ui/layouts/settings/starpilot/panel.py index 29dd26e1e..4fe2812d0 100644 --- a/selfdrive/ui/layouts/settings/starpilot/panel.py +++ b/selfdrive/ui/layouts/settings/starpilot/panel.py @@ -422,14 +422,17 @@ class _SettingsPage(StarPilotPanel): gui_app.push_widget(dialog) def _show_labeled_select(self, title, key, options, current_value): - """Integer-based multi-option selector with label/value pairs (puts int).""" + """Integer-based multi-option selector with label/value pairs (puts int). + + Mirrors Qt's ButtonParamControl: resolve by index so no KeyError is possible. + """ option_labels = [tr(label) for _, label in options] - label_to_value = {tr(label): value for value, label in options} + option_values = [value for value, _ in options] default = next((tr(label) for value, label in options if value == current_value), option_labels[0]) def on_select(res): - if res == DialogResult.CONFIRM and dialog.selection: - self._params.put_int(key, label_to_value[dialog.selection]) + if res == DialogResult.CONFIRM and dialog.selection in option_labels: + self._params.put_int(key, option_values[option_labels.index(dialog.selection)]) dialog = MultiOptionDialog(tr(title), option_labels, default, callback=on_select) gui_app.push_widget(dialog) diff --git a/system/ui/widgets/option_dialog.py b/system/ui/widgets/option_dialog.py index 206400a74..8e6fe56d5 100644 --- a/system/ui/widgets/option_dialog.py +++ b/system/ui/widgets/option_dialog.py @@ -75,5 +75,5 @@ class MultiOptionDialog(Widget): self.cancel_button.render(cancel_rect) select_rect = rl.Rectangle(content_rect.x + button_w + BUTTON_SPACING, button_y, button_w, BUTTON_HEIGHT) - self.select_button.set_enabled(self.selection != self.current) + self.select_button.set_enabled(bool(self.selection)) self.select_button.render(select_rect)