diff --git a/selfdrive/ui/layouts/onboarding.py b/selfdrive/ui/layouts/onboarding.py
index a817fc53ad..df259a8fb5 100644
--- a/selfdrive/ui/layouts/onboarding.py
+++ b/selfdrive/ui/layouts/onboarding.py
@@ -6,6 +6,7 @@ from enum import IntEnum
import pyray as rl
from openpilot.common.basedir import BASEDIR
from openpilot.system.ui.lib.application import FontWeight, gui_app
+from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.widgets.button import Button, ButtonStyle
from openpilot.system.ui.widgets.label import Label
@@ -107,12 +108,12 @@ class TermsPage(Widget):
self._on_accept = on_accept
self._on_decline = on_decline
- self._title = Label("Welcome to openpilot", font_size=90, font_weight=FontWeight.BOLD, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT)
- self._desc = Label("You must accept the Terms and Conditions to use openpilot. Read the latest terms at https://comma.ai/terms before continuing.",
+ self._title = Label(tr("Welcome to openpilot"), font_size=90, font_weight=FontWeight.BOLD, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT)
+ self._desc = Label(tr("You must accept the Terms and Conditions to use openpilot. Read the latest terms at https://comma.ai/terms before continuing."),
font_size=90, font_weight=FontWeight.MEDIUM, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT)
- self._decline_btn = Button("Decline", click_callback=on_decline)
- self._accept_btn = Button("Agree", button_style=ButtonStyle.PRIMARY, click_callback=on_accept)
+ self._decline_btn = Button(tr("Decline"), click_callback=on_decline)
+ self._accept_btn = Button(tr("Agree"), button_style=ButtonStyle.PRIMARY, click_callback=on_accept)
def _render(self, _):
welcome_x = self._rect.x + 165
@@ -141,10 +142,10 @@ class TermsPage(Widget):
class DeclinePage(Widget):
def __init__(self, back_callback=None):
super().__init__()
- self._text = Label("You must accept the Terms and Conditions in order to use openpilot.",
+ self._text = Label(tr("You must accept the Terms and Conditions in order to use openpilot."),
font_size=90, font_weight=FontWeight.MEDIUM, text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT)
- self._back_btn = Button("Back", click_callback=back_callback)
- self._uninstall_btn = Button("Decline, uninstall openpilot", button_style=ButtonStyle.DANGER,
+ self._back_btn = Button(tr("Back"), click_callback=back_callback)
+ self._uninstall_btn = Button(tr("Decline, uninstall openpilot"), button_style=ButtonStyle.DANGER,
click_callback=self._on_uninstall_clicked)
def _on_uninstall_clicked(self):
diff --git a/selfdrive/ui/layouts/settings/developer.py b/selfdrive/ui/layouts/settings/developer.py
index 21eb44efe7..47cf5c07a4 100644
--- a/selfdrive/ui/layouts/settings/developer.py
+++ b/selfdrive/ui/layouts/settings/developer.py
@@ -6,19 +6,20 @@ from openpilot.system.ui.widgets.list_view import toggle_item
from openpilot.system.ui.widgets.scroller import Scroller
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
from openpilot.system.ui.lib.application import gui_app
+from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.widgets import DialogResult
# Description constants
DESCRIPTIONS = {
- 'enable_adb': (
+ 'enable_adb': tr(
"ADB (Android Debug Bridge) allows connecting to your device over USB or over the network. " +
"See https://docs.comma.ai/how-to/connect-to-comma for more info."
),
- 'ssh_key': (
+ 'ssh_key': tr(
"Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username " +
"other than your own. A comma employee will NEVER ask you to add their GitHub username."
),
- 'alpha_longitudinal': (
+ 'alpha_longitudinal': tr(
"WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB).
" +
"On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. " +
"Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha."
@@ -34,7 +35,7 @@ class DeveloperLayout(Widget):
# Build items and keep references for callbacks/state updates
self._adb_toggle = toggle_item(
- "Enable ADB",
+ tr("Enable ADB"),
description=DESCRIPTIONS["enable_adb"],
initial_state=self._params.get_bool("AdbEnabled"),
callback=self._on_enable_adb,
@@ -43,7 +44,7 @@ class DeveloperLayout(Widget):
# SSH enable toggle + SSH key management
self._ssh_toggle = toggle_item(
- "Enable SSH",
+ tr("Enable SSH"),
description="",
initial_state=self._params.get_bool("SshEnabled"),
callback=self._on_enable_ssh,
@@ -51,7 +52,7 @@ class DeveloperLayout(Widget):
self._ssh_keys = ssh_key_item("SSH Keys", description=DESCRIPTIONS["ssh_key"])
self._joystick_toggle = toggle_item(
- "Joystick Debug Mode",
+ tr("Joystick Debug Mode"),
description="",
initial_state=self._params.get_bool("JoystickDebugMode"),
callback=self._on_joystick_debug_mode,
@@ -59,14 +60,14 @@ class DeveloperLayout(Widget):
)
self._long_maneuver_toggle = toggle_item(
- "Longitudinal Maneuver Mode",
+ tr("Longitudinal Maneuver Mode"),
description="",
initial_state=self._params.get_bool("LongitudinalManeuverMode"),
callback=self._on_long_maneuver_mode,
)
self._alpha_long_toggle = toggle_item(
- "openpilot Longitudinal Control (Alpha)",
+ tr("openpilot Longitudinal Control (Alpha)"),
description=DESCRIPTIONS["alpha_longitudinal"],
initial_state=self._params.get_bool("AlphaLongitudinalEnabled"),
callback=self._on_alpha_long_enabled,
diff --git a/selfdrive/ui/layouts/settings/device.py b/selfdrive/ui/layouts/settings/device.py
index bfaa03857b..c6ca8611c5 100644
--- a/selfdrive/ui/layouts/settings/device.py
+++ b/selfdrive/ui/layouts/settings/device.py
@@ -49,24 +49,23 @@ 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 = button_item(tr("Pair Device"), tr("PAIR"), DESCRIPTIONS['pair_device'], callback=self._pair_device)
self._pair_device_btn.set_visible(lambda: not ui_state.prime_state.is_paired())
- self._reset_calib_btn = button_item("Reset Calibration", "RESET", DESCRIPTIONS['reset_calibration'], callback=self._reset_calibration_prompt)
+ self._reset_calib_btn = button_item(tr("Reset Calibration"), tr("RESET"), DESCRIPTIONS['reset_calibration'], callback=self._reset_calibration_prompt)
self._reset_calib_btn.set_description_opened_callback(self._update_calib_description)
- self._power_off_btn = dual_button_item("Reboot", "Power Off", left_callback=self._reboot_prompt, right_callback=self._power_off_prompt)
+ self._power_off_btn = dual_button_item(tr("Reboot"), tr("Power Off"), left_callback=self._reboot_prompt, right_callback=self._power_off_prompt)
items = [
- text_item("Dongle ID", dongle_id),
- text_item("Serial", serial),
+ text_item(tr("Dongle ID"), dongle_id),
+ text_item(tr("Serial"), serial),
self._pair_device_btn,
- button_item("Driver Camera", "PREVIEW", DESCRIPTIONS['driver_camera'], callback=self._show_driver_camera, enabled=ui_state.is_offroad),
+ button_item(tr("Driver Camera"), tr("PREVIEW"), DESCRIPTIONS['driver_camera'], callback=self._show_driver_camera, enabled=ui_state.is_offroad),
self._reset_calib_btn,
- button_item("Review Training Guide", "REVIEW", DESCRIPTIONS['review_guide'], self._on_review_training_guide, enabled=ui_state.is_offroad),
- regulatory_btn := button_item("Regulatory", "VIEW", callback=self._on_regulatory, enabled=ui_state.is_offroad),
- # TODO: implement multilang
- button_item("Change Language", "CHANGE", callback=self._show_language_dialog, enabled=ui_state.is_offroad),
+ button_item(tr("Review Training Guide"), tr("REVIEW"), DESCRIPTIONS['review_guide'], self._on_review_training_guide, enabled=ui_state.is_offroad),
+ regulatory_btn := button_item(tr("Regulatory"), tr("VIEW"), callback=self._on_regulatory, enabled=ui_state.is_offroad),
+ button_item(tr("Change Language"), tr("CHANGE"), callback=self._show_language_dialog, enabled=ui_state.is_offroad),
self._power_off_btn,
]
regulatory_btn.set_visible(TICI)
@@ -108,7 +107,7 @@ class DeviceLayout(Widget):
def _reset_calibration_prompt(self):
if ui_state.engaged:
- gui_app.set_modal_overlay(alert_dialog("Disengage to Reset Calibration"))
+ gui_app.set_modal_overlay(alert_dialog(tr("Disengage to Reset Calibration")))
return
def reset_calibration(result: int):
@@ -124,7 +123,7 @@ class DeviceLayout(Widget):
self._params.put_bool("OnroadCycleRequested", True)
self._update_calib_description()
- dialog = ConfirmDialog("Are you sure you want to reset calibration?", "Reset")
+ dialog = ConfirmDialog(tr("Are you sure you want to reset calibration?"), tr("Reset"))
gui_app.set_modal_overlay(dialog, callback=reset_calibration)
def _update_calib_description(self):
@@ -176,10 +175,10 @@ class DeviceLayout(Widget):
def _reboot_prompt(self):
if ui_state.engaged:
- gui_app.set_modal_overlay(alert_dialog("Disengage to Reboot"))
+ gui_app.set_modal_overlay(alert_dialog(tr("Disengage to Reboot")))
return
- dialog = ConfirmDialog("Are you sure you want to reboot?", "Reboot")
+ dialog = ConfirmDialog(tr("Are you sure you want to reboot?"), tr("Reboot"))
gui_app.set_modal_overlay(dialog, callback=self._perform_reboot)
def _perform_reboot(self, result: int):
@@ -188,10 +187,10 @@ class DeviceLayout(Widget):
def _power_off_prompt(self):
if ui_state.engaged:
- gui_app.set_modal_overlay(alert_dialog("Disengage to Power Off"))
+ gui_app.set_modal_overlay(alert_dialog(tr("Disengage to Power Off")))
return
- dialog = ConfirmDialog("Are you sure you want to power off?", "Power Off")
+ dialog = ConfirmDialog(tr("Are you sure you want to power off?"), tr("Power Off"))
gui_app.set_modal_overlay(dialog, callback=self._perform_power_off)
def _perform_power_off(self, result: int):
diff --git a/selfdrive/ui/layouts/settings/firehose.py b/selfdrive/ui/layouts/settings/firehose.py
index e8eaaa44f2..c211da1af0 100644
--- a/selfdrive/ui/layouts/settings/firehose.py
+++ b/selfdrive/ui/layouts/settings/firehose.py
@@ -8,19 +8,20 @@ from openpilot.common.swaglog import cloudlog
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.athena.registration import UNREGISTERED_DONGLE_ID
from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE
+from openpilot.system.ui.lib.multilang import tr, trn
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
from openpilot.system.ui.lib.wrap_text import wrap_text
from openpilot.system.ui.widgets import Widget
from openpilot.selfdrive.ui.lib.api_helpers import get_token
-TITLE = "Firehose Mode"
-DESCRIPTION = (
+TITLE = tr("Firehose Mode")
+DESCRIPTION = tr(
"openpilot learns to drive by watching humans, like you, drive.\n\n"
+ "Firehose Mode allows you to maximize your training data uploads to improve "
+ "openpilot's driving models. More data means bigger models, which means better Experimental Mode."
)
-INSTRUCTIONS = (
+INSTRUCTIONS = tr(
"For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.\n\n"
+ "Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.\n\n\n"
+ "Frequently Asked Questions\n\n"
@@ -106,7 +107,8 @@ class FirehoseLayout(Widget):
# Contribution count (if available)
if self.segment_count > 0:
- contrib_text = f"{self.segment_count} segment(s) of your driving is in the training dataset so far."
+ contrib_text = trn("{} segment of your driving is in the training dataset so far.",
+ "{} segment of your driving is in the training dataset so far.", self.segment_count).format(self.segment_count)
y = self._draw_wrapped_text(x, y, w, contrib_text, gui_app.font(FontWeight.BOLD), 52, rl.WHITE)
y += 20 + 20
@@ -132,9 +134,9 @@ class FirehoseLayout(Widget):
network_metered = ui_state.sm["deviceState"].networkMetered
if not network_metered and network_type != 0: # Not metered and connected
- return "ACTIVE", self.GREEN
+ return tr("ACTIVE"), self.GREEN
else:
- return "INACTIVE: connect to an unmetered network", self.RED
+ return tr("INACTIVE: connect to an unmetered network"), self.RED
def _fetch_firehose_stats(self):
try:
diff --git a/selfdrive/ui/layouts/settings/settings.py b/selfdrive/ui/layouts/settings/settings.py
index d43382f199..7f431d3a77 100644
--- a/selfdrive/ui/layouts/settings/settings.py
+++ b/selfdrive/ui/layouts/settings/settings.py
@@ -8,6 +8,7 @@ from openpilot.selfdrive.ui.layouts.settings.firehose import FirehoseLayout
from openpilot.selfdrive.ui.layouts.settings.software import SoftwareLayout
from openpilot.selfdrive.ui.layouts.settings.toggles import TogglesLayout
from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos
+from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.wifi_manager import WifiManager
from openpilot.system.ui.widgets import Widget
@@ -58,12 +59,12 @@ class SettingsLayout(Widget):
wifi_manager.set_active(False)
self._panels = {
- PanelType.DEVICE: PanelInfo("Device", DeviceLayout()),
- PanelType.NETWORK: PanelInfo("Network", NetworkUI(wifi_manager)),
- PanelType.TOGGLES: PanelInfo("Toggles", TogglesLayout()),
- PanelType.SOFTWARE: PanelInfo("Software", SoftwareLayout()),
- PanelType.FIREHOSE: PanelInfo("Firehose", FirehoseLayout()),
- PanelType.DEVELOPER: PanelInfo("Developer", DeveloperLayout()),
+ PanelType.DEVICE: PanelInfo(tr("Device"), DeviceLayout()),
+ PanelType.NETWORK: PanelInfo(tr("Network"), NetworkUI(wifi_manager)),
+ PanelType.TOGGLES: PanelInfo(tr("Toggles"), TogglesLayout()),
+ PanelType.SOFTWARE: PanelInfo(tr("Software"), SoftwareLayout()),
+ PanelType.FIREHOSE: PanelInfo(tr("Firehose"), FirehoseLayout()),
+ PanelType.DEVELOPER: PanelInfo(tr("Developer"), DeveloperLayout()),
}
self._font_medium = gui_app.font(FontWeight.MEDIUM)
diff --git a/selfdrive/ui/layouts/settings/software.py b/selfdrive/ui/layouts/settings/software.py
index 0c17a54fbe..8e0cfdbc3c 100644
--- a/selfdrive/ui/layouts/settings/software.py
+++ b/selfdrive/ui/layouts/settings/software.py
@@ -4,6 +4,7 @@ import datetime
from openpilot.common.time_helpers import system_time_valid
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.application import gui_app
+from openpilot.system.ui.lib.multilang import tr, trn
from openpilot.system.ui.widgets import Widget, DialogResult
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
from openpilot.system.ui.widgets.list_view import button_item, text_item, ListItem
@@ -15,7 +16,7 @@ UPDATED_TIMEOUT = 10 # seconds to wait for updated to respond
def time_ago(date: datetime.datetime | None) -> str:
if not date:
- return "never"
+ return tr("never")
if not system_time_valid():
return date.strftime("%a %b %d %Y")
@@ -26,16 +27,16 @@ def time_ago(date: datetime.datetime | None) -> str:
diff_seconds = int((now - date).total_seconds())
if diff_seconds < 60:
- return "now"
+ return tr("now")
if diff_seconds < 3600:
m = diff_seconds // 60
- return f"{m} minute{'s' if m != 1 else ''} ago"
+ return trn("{} minute ago", "{} minutes ago", m).format(m)
if diff_seconds < 86400:
h = diff_seconds // 3600
- return f"{h} hour{'s' if h != 1 else ''} ago"
+ return trn("{} hour ago", "{} hours ago", h).format(h)
if diff_seconds < 604800:
d = diff_seconds // 86400
- return f"{d} day{'s' if d != 1 else ''} ago"
+ return trn("{} day ago", "{} days ago", d).format(d)
return date.strftime("%a %b %d %Y")
@@ -43,12 +44,12 @@ class SoftwareLayout(Widget):
def __init__(self):
super().__init__()
- self._onroad_label = ListItem(title="Updates are only downloaded while the car is off.")
- self._version_item = text_item("Current Version", ui_state.params.get("UpdaterCurrentDescription") or "")
- self._download_btn = button_item("Download", "CHECK", callback=self._on_download_update)
+ self._onroad_label = ListItem(title=tr("Updates are only downloaded while the car is off."))
+ self._version_item = text_item(tr("Current Version"), ui_state.params.get("UpdaterCurrentDescription") or "")
+ self._download_btn = button_item(tr("Download"), tr("CHECK"), callback=self._on_download_update)
# Install button is initially hidden
- self._install_btn = button_item("Install Update", "INSTALL", callback=self._on_install_update)
+ self._install_btn = button_item(tr("Install Update"), tr("INSTALL"), callback=self._on_install_update)
self._install_btn.set_visible(False)
# Track waiting-for-updater transition to avoid brief re-enable while still idle
@@ -66,7 +67,7 @@ class SoftwareLayout(Widget):
self._install_btn,
# TODO: implement branch switching
# button_item("Target Branch", "SELECT", callback=self._on_select_branch),
- button_item("Uninstall", "UNINSTALL", callback=self._on_uninstall),
+ button_item("Uninstall", tr("UNINSTALL"), callback=self._on_uninstall),
]
return items
@@ -101,19 +102,19 @@ class SoftwareLayout(Widget):
self._download_btn.action_item.set_value(updater_state)
else:
if failed_count > 0:
- self._download_btn.action_item.set_value("failed to check for update")
- self._download_btn.action_item.set_text("CHECK")
+ self._download_btn.action_item.set_value(tr("failed to check for update"))
+ self._download_btn.action_item.set_text(tr("CHECK"))
elif fetch_available:
- self._download_btn.action_item.set_value("update available")
- self._download_btn.action_item.set_text("DOWNLOAD")
+ self._download_btn.action_item.set_value(tr("update available"))
+ self._download_btn.action_item.set_text(tr("DOWNLOAD"))
else:
last_update = ui_state.params.get("LastUpdateTime")
if last_update:
formatted = time_ago(last_update)
- self._download_btn.action_item.set_value(f"up to date, last checked {formatted}")
+ self._download_btn.action_item.set_value(tr("up to date, last checked {}").format(formatted))
else:
- self._download_btn.action_item.set_value("up to date, last checked never")
- self._download_btn.action_item.set_text("CHECK")
+ self._download_btn.action_item.set_value(tr("up to date, last checked never"))
+ self._download_btn.action_item.set_text(tr("CHECK"))
# If we've been waiting too long without a state change, reset state
if self._waiting_for_updater and (time.monotonic() - self._waiting_start_ts > UPDATED_TIMEOUT):
@@ -127,7 +128,7 @@ class SoftwareLayout(Widget):
if update_available:
new_desc = ui_state.params.get("UpdaterNewDescription") or ""
new_release_notes = (ui_state.params.get("UpdaterNewReleaseNotes") or b"").decode("utf-8", "replace")
- self._install_btn.action_item.set_text("INSTALL")
+ self._install_btn.action_item.set_text(tr("INSTALL"))
self._install_btn.action_item.set_value(new_desc)
self._install_btn.set_description(new_release_notes)
# Enable install button for testing (like Qt showEvent)
@@ -138,7 +139,7 @@ class SoftwareLayout(Widget):
def _on_download_update(self):
# Check if we should start checking or start downloading
self._download_btn.action_item.set_enabled(False)
- if self._download_btn.action_item.text == "CHECK":
+ if self._download_btn.action_item.text == tr("CHECK"):
# Start checking for updates
self._waiting_for_updater = True
self._waiting_start_ts = time.monotonic()
@@ -154,7 +155,7 @@ class SoftwareLayout(Widget):
if result == DialogResult.CONFIRM:
ui_state.params.put_bool("DoUninstall", True)
- dialog = ConfirmDialog("Are you sure you want to uninstall?", "Uninstall")
+ dialog = ConfirmDialog(tr("Are you sure you want to uninstall?"), tr("Uninstall"))
gui_app.set_modal_overlay(dialog, callback=handle_uninstall_confirmation)
def _on_install_update(self):
diff --git a/selfdrive/ui/layouts/settings/toggles.py b/selfdrive/ui/layouts/settings/toggles.py
index c425e45920..1e4d5c6c85 100644
--- a/selfdrive/ui/layouts/settings/toggles.py
+++ b/selfdrive/ui/layouts/settings/toggles.py
@@ -43,49 +43,49 @@ class TogglesLayout(Widget):
# param, title, desc, icon, needs_restart
self._toggle_defs = {
"OpenpilotEnabledToggle": (
- "Enable openpilot",
+ tr("Enable openpilot"),
DESCRIPTIONS["OpenpilotEnabledToggle"],
"chffr_wheel.png",
True,
),
"ExperimentalMode": (
- "Experimental Mode",
+ tr("Experimental Mode"),
"",
"experimental_white.png",
False,
),
"DisengageOnAccelerator": (
- "Disengage on Accelerator Pedal",
+ tr("Disengage on Accelerator Pedal"),
DESCRIPTIONS["DisengageOnAccelerator"],
"disengage_on_accelerator.png",
False,
),
"IsLdwEnabled": (
- "Enable Lane Departure Warnings",
+ tr("Enable Lane Departure Warnings"),
DESCRIPTIONS["IsLdwEnabled"],
"warning.png",
False,
),
"AlwaysOnDM": (
- "Always-On Driver Monitoring",
+ tr("Always-On Driver Monitoring"),
DESCRIPTIONS["AlwaysOnDM"],
"monitoring.png",
False,
),
"RecordFront": (
- "Record and Upload Driver Camera",
+ tr("Record and Upload Driver Camera"),
DESCRIPTIONS["RecordFront"],
"monitoring.png",
True,
),
"RecordAudio": (
- "Record and Upload Microphone Audio",
+ tr("Record and Upload Microphone Audio"),
DESCRIPTIONS["RecordAudio"],
"microphone.png",
True,
),
"IsMetric": (
- "Use Metric System",
+ tr("Use Metric System"),
DESCRIPTIONS["IsMetric"],
"metric.png",
False,
@@ -93,9 +93,9 @@ class TogglesLayout(Widget):
}
self._long_personality_setting = multiple_button_item(
- "Driving Personality",
+ tr("Driving Personality"),
DESCRIPTIONS["LongitudinalPersonality"],
- buttons=["Aggressive", "Standard", "Relaxed"],
+ buttons=[tr("Aggressive"), tr("Standard"), tr("Relaxed")],
button_width=255,
callback=self._set_longitudinal_personality,
selected_index=self._params.get("LongitudinalPersonality", return_default=True),
@@ -120,7 +120,7 @@ class TogglesLayout(Widget):
toggle.action_item.set_enabled(not locked)
if needs_restart and not locked:
- toggle.set_description(toggle.description + " Changing this setting will restart openpilot if the car is powered on.")
+ toggle.set_description(toggle.description + tr(" Changing this setting will restart openpilot if the car is powered on."))
# track for engaged state updates
if locked:
@@ -151,7 +151,7 @@ class TogglesLayout(Widget):
def _update_toggles(self):
ui_state.update_params()
- e2e_description = (
+ e2e_description = tr(
"openpilot defaults to driving in chill mode. Experimental mode enables alpha-level features that aren't ready for chill mode. " +
"Experimental features are listed below:
" +
"
{self._toggles['ExperimentalMode'].description}
") - dlg = ConfirmDialog(content, "Enable", rich=True) + dlg = ConfirmDialog(content, tr("Enable"), rich=True) gui_app.set_modal_overlay(dlg, callback=confirm_callback) else: self._update_experimental_mode_icon() diff --git a/selfdrive/ui/layouts/sidebar.py b/selfdrive/ui/layouts/sidebar.py index 9337b3c239..48b577ea59 100644 --- a/selfdrive/ui/layouts/sidebar.py +++ b/selfdrive/ui/layouts/sidebar.py @@ -5,6 +5,7 @@ from collections.abc import Callable from cereal import log from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos, FONT_SCALE +from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.lib.text_measure import measure_text_cached from openpilot.system.ui.widgets import Widget @@ -39,13 +40,13 @@ class Colors: NETWORK_TYPES = { - NetworkType.none: "--", - NetworkType.wifi: "Wi-Fi", - NetworkType.ethernet: "ETH", - NetworkType.cell2G: "2G", - NetworkType.cell3G: "3G", - NetworkType.cell4G: "LTE", - NetworkType.cell5G: "5G", + NetworkType.none: tr("--"), + NetworkType.wifi: tr("Wi-Fi"), + NetworkType.ethernet: tr("ETH"), + NetworkType.cell2G: tr("2G"), + NetworkType.cell3G: tr("3G"), + NetworkType.cell4G: tr("LTE"), + NetworkType.cell5G: tr("5G"), } @@ -67,9 +68,9 @@ class Sidebar(Widget): self._net_type = NETWORK_TYPES.get(NetworkType.none) self._net_strength = 0 - self._temp_status = MetricData("TEMP", "GOOD", Colors.GOOD) - self._panda_status = MetricData("VEHICLE", "ONLINE", Colors.GOOD) - self._connect_status = MetricData("CONNECT", "OFFLINE", Colors.WARNING) + self._temp_status = MetricData(tr("TEMP"), tr("GOOD"), Colors.GOOD) + self._panda_status = MetricData(tr("VEHICLE"), tr("ONLINE"), Colors.GOOD) + self._connect_status = MetricData(tr("CONNECT"), tr("OFFLINE"), Colors.WARNING) self._recording_audio = False self._home_img = gui_app.texture("images/button_home.png", HOME_BTN.width, HOME_BTN.height) @@ -113,7 +114,7 @@ class Sidebar(Widget): self._update_panda_status() def _update_network_status(self, device_state): - self._net_type = NETWORK_TYPES.get(device_state.networkType.raw, "Unknown") + self._net_type = NETWORK_TYPES.get(device_state.networkType.raw, tr("Unknown")) strength = device_state.networkStrength self._net_strength = max(0, min(5, strength.raw + 1)) if strength > 0 else 0 @@ -121,26 +122,26 @@ class Sidebar(Widget): thermal_status = device_state.thermalStatus if thermal_status == ThermalStatus.green: - self._temp_status.update("TEMP", "GOOD", Colors.GOOD) + self._temp_status.update(tr("TEMP"), tr("GOOD"), Colors.GOOD) elif thermal_status == ThermalStatus.yellow: - self._temp_status.update("TEMP", "OK", Colors.WARNING) + self._temp_status.update(tr("TEMP"), tr("OK"), Colors.WARNING) else: - self._temp_status.update("TEMP", "HIGH", Colors.DANGER) + self._temp_status.update(tr("TEMP"), tr("HIGH"), Colors.DANGER) def _update_connection_status(self, device_state): last_ping = device_state.lastAthenaPingTime if last_ping == 0: - self._connect_status.update("CONNECT", "OFFLINE", Colors.WARNING) + self._connect_status.update(tr("CONNECT"), tr("OFFLINE"), Colors.WARNING) elif time.monotonic_ns() - last_ping < 80_000_000_000: # 80 seconds in nanoseconds - self._connect_status.update("CONNECT", "ONLINE", Colors.GOOD) + self._connect_status.update(tr("CONNECT"), tr("ONLINE"), Colors.GOOD) else: - self._connect_status.update("CONNECT", "ERROR", Colors.DANGER) + self._connect_status.update(tr("CONNECT"), tr("ERROR"), Colors.DANGER) def _update_panda_status(self): if ui_state.panda_type == log.PandaState.PandaType.unknown: - self._panda_status.update("NO", "PANDA", Colors.DANGER) + self._panda_status.update(tr("NO"), tr("PANDA"), Colors.DANGER) else: - self._panda_status.update("VEHICLE", "ONLINE", Colors.GOOD) + self._panda_status.update(tr("VEHICLE"), tr("ONLINE"), Colors.GOOD) def _handle_mouse_release(self, mouse_pos: MousePos): if rl.check_collision_point_rec(mouse_pos, SETTINGS_BTN):