pull/36410/head
Shane Smiskol 4 weeks ago
parent 6d4f568f7d
commit deb4239fe6
  1. 0
      selfdrive/ui/layouts/__init__.py
  2. 4
      selfdrive/ui/layouts/home.py
  3. 23
      selfdrive/ui/update_translations.sh
  4. 47
      selfdrive/ui/update_translations_raylib.py
  5. 14
      selfdrive/ui/widgets/prime.py
  6. 6
      selfdrive/ui/widgets/setup.py
  7. 5
      system/ui/lib/application.py
  8. 10
      system/ui/lib/multilang.py

@ -8,7 +8,7 @@ from openpilot.selfdrive.ui.widgets.exp_mode_button import ExperimentalModeButto
from openpilot.selfdrive.ui.widgets.prime import PrimeWidget
from openpilot.selfdrive.ui.widgets.setup import SetupWidget
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_TEXT_COLOR
from openpilot.system.ui.lib.application import tr, gui_app, FontWeight, DEFAULT_TEXT_COLOR
from openpilot.system.ui.widgets import Widget
HEADER_HEIGHT = 80
@ -139,7 +139,7 @@ class HomeLayout(Widget):
highlight_color = rl.Color(255, 140, 40, 255) if self.current_state == HomeLayoutState.UPDATE else rl.Color(255, 102, 0, 255)
rl.draw_rectangle_rounded(self.update_notif_rect, 0.3, 10, highlight_color)
text = "UPDATE"
text = tr("UPDATE")
text_width = measure_text_cached(font, text, HEAD_BUTTON_FONT_SIZE).x
text_x = self.update_notif_rect.x + (self.update_notif_rect.width - text_width) // 2
text_y = self.update_notif_rect.y + (self.update_notif_rect.height - HEAD_BUTTON_FONT_SIZE) // 2

@ -0,0 +1,23 @@
#!/usr/bin/env bash
BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$BASEDIR"
pwd
PY_FILES=$(git ls-files 'layouts/*.py' 'widgets/*.py')
xgettext -L Python \
--keyword=tr \
--keyword=trn:1,2 \
--keyword=pgettext:1c,2 \
--from-code=UTF-8 \
--flag=tr:1:python-brace-format \
--flag=trn:1:python-brace-format --flag=trn:2:python-brace-format \
-o translations/app.pot \
$PY_FILES
msginit \
-l es \
--no-translator \
--input translations/app.pot \
--output-file translations/app.po

@ -0,0 +1,47 @@
#!/usr/bin/env python3
import argparse
import json
import os
from openpilot.common.basedir import BASEDIR
UI_DIR = os.path.join(BASEDIR, "selfdrive", "ui")
TRANSLATIONS_DIR = os.path.join(UI_DIR, "translations")
LANGUAGES_FILE = os.path.join(TRANSLATIONS_DIR, "languages.json")
def update_translations():
files = []
for root, _, filenames in os.walk(os.path.join(UI_DIR, "widgets")):
for filename in filenames:
if filename.endswith(".py"):
files.append(os.path.join(root, filename))
# Create main translation file
print(files)
cmd = ("xgettext -L Python --keyword=tr --keyword=trn:1,2 --keyword=pgettext:1c,2 --from-code=UTF-8 " +
"--flag=tr:1:python-brace-format --flag=trn:1:python-brace-format --flag=trn:2:python-brace-format " +
"-o translations/app.pot {}").format(" ".join(files))
print(cmd)
ret = os.system(cmd)
assert ret == 0
# Generate/update translation files for each language
with open(LANGUAGES_FILE) as f:
translation_files = json.load(f).values()
for file in translation_files:
name = file.replace("main_", "")
if os.path.exists(os.path.join(TRANSLATIONS_DIR, f"app_{name}.po")):
cmd = "msgmerge --update --backup=none --sort-output translations/app.pot translations/app_{}.po".format(name)
ret = os.system(cmd)
assert ret == 0
else:
cmd = "msginit -l es --no-translator --input translations/app.pot --output-file translations/app_{}.po".format(name)
ret = os.system(cmd)
assert ret == 0
if __name__ == "__main__":
update_translations()

@ -1,7 +1,7 @@
import pyray as rl
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.application import gui_app, FontWeight
from openpilot.system.ui.lib.application import tr, gui_app, FontWeight
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.wrap_text import wrap_text
from openpilot.system.ui.widgets import Widget
@ -29,21 +29,21 @@ class PrimeWidget(Widget):
w = rect.width - 160
# Title
gui_label(rl.Rectangle(x, y, w, 90), "Upgrade Now", 75, font_weight=FontWeight.BOLD)
gui_label(rl.Rectangle(x, y, w, 90), tr("Upgrade Now12345"), 75, font_weight=FontWeight.BOLD)
# Description with wrapping
desc_y = y + 140
font = gui_app.font(FontWeight.LIGHT)
wrapped_text = "\n".join(wrap_text(font, "Become a comma prime member at connect.comma.ai", 56, int(w)))
wrapped_text = "\n".join(wrap_text(font, tr("Become a comma prime member at connect.comma.ai"), 56, int(w)))
text_size = measure_text_cached(font, wrapped_text, 56)
rl.draw_text_ex(font, wrapped_text, rl.Vector2(x, desc_y), 56, 0, rl.WHITE)
# Features section
features_y = desc_y + text_size.y + 50
gui_label(rl.Rectangle(x, features_y, w, 50), "PRIME FEATURES:", 41, font_weight=FontWeight.BOLD)
gui_label(rl.Rectangle(x, features_y, w, 50), tr("PRIME FEATURES:"), 41, font_weight=FontWeight.BOLD)
# Feature list
features = ["Remote access", "24/7 LTE connectivity", "1 year of drive storage", "Remote snapshots"]
features = [tr("Remote access"), tr("24/7 LTE connectivity"), tr("1 year of drive storage"), tr("Remote snapshots")]
for i, feature in enumerate(features):
item_y = features_y + 80 + i * 65
gui_label(rl.Rectangle(x, item_y, 50, 60), "", 50, color=rl.Color(70, 91, 234, 255))
@ -58,5 +58,5 @@ class PrimeWidget(Widget):
y = rect.y + 40
font = gui_app.font(FontWeight.BOLD)
rl.draw_text_ex(font, "✓ SUBSCRIBED", rl.Vector2(x, y), 41, 0, rl.Color(134, 255, 78, 255))
rl.draw_text_ex(font, "comma prime", rl.Vector2(x, y + 61), 75, 0, rl.WHITE)
rl.draw_text_ex(font, tr("✓ SUBSCRIBED"), rl.Vector2(x, y), 41, 0, rl.Color(134, 255, 78, 255))
rl.draw_text_ex(font, tr("comma prime"), rl.Vector2(x, y + 61), 75, 0, rl.WHITE)

@ -2,7 +2,7 @@ import pyray as rl
from openpilot.selfdrive.ui.lib.prime_state import PrimeType
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.selfdrive.ui.widgets.pairing_dialog import PairingDialog
from openpilot.system.ui.lib.application import gui_app, FontWeight
from openpilot.system.ui.lib.application import tr, gui_app, FontWeight
from openpilot.system.ui.lib.wrap_text import wrap_text
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.widgets.button import gui_button, ButtonStyle
@ -38,7 +38,7 @@ class SetupWidget(Widget):
y += 113 # 75 + 38 spacing
# Description
desc = "Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer."
desc = tr("Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.")
light_font = gui_app.font(FontWeight.LIGHT)
wrapped = wrap_text(light_font, desc, 50, int(w))
for line in wrapped:
@ -62,7 +62,7 @@ class SetupWidget(Widget):
# Title with fire emojis
title_font = gui_app.font(FontWeight.MEDIUM)
title_text = "Firehose Mode"
title_text = tr('Firehose Mode1')
rl.draw_text_ex(title_font, title_text, rl.Vector2(x, y), 64, 0, rl.WHITE)
y += 64 + spacing

@ -136,7 +136,6 @@ class GuiApplication:
self._window_close_requested = False
self._trace_log_callback = None
self._modal_overlay = ModalOverlay()
self._multilang = Multilang()
self._mouse = MouseState(self._scale)
self._mouse_events: list[MouseEvent] = []
@ -320,7 +319,6 @@ class GuiApplication:
def height(self):
return self._height
def _load_fonts(self):
# Create a character set from our keyboard layouts
from openpilot.system.ui.widgets.keyboard import KEYBOARD_LAYOUTS
@ -406,4 +404,7 @@ class GuiApplication:
os._exit(1)
multilang = Multilang()
tr = multilang.translate
gui_app = GuiApplication(2160, 1080)

@ -13,6 +13,11 @@ class Multilang:
self._load_languages()
self._hook_draw_text()
def translate(self, text: str) -> str:
if self._language not in self._translations:
return text
return self._translations[self._language].get(text, text)
def _load_languages(self):
self._language = Params().get("LanguageSetting")
@ -21,11 +26,6 @@ class Multilang:
if file.endswith(".ts"):
pass
def _get_translated_text(self, text: str) -> str:
if self._language not in self._translations:
return text
return self._translations[self._language].get(text, text)
def _hook_draw_text(self):
# hook rl.draw_text* to get text for multilang
# TODO: and measure text

Loading…
Cancel
Save