From 4a60eb50e5541eed8c0b16834c2ab817fafab18d Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Sun, 12 Jan 2025 15:29:08 -0500 Subject: [PATCH] ui: new design for Device panel buttons (#557) * init btns * better design * force offroad in another PR * old calibration design for now * revert * ci: fix position * try this * check ci * Revert "check ci" This reverts commit 80795cc700e01183a1ba6e2831e23f7346dedde0. * test more ci * Revert "test more ci" This reverts commit 05670b5ad66799c2278074ac9d086e66b574a449. * nuke more on CI * unlikely but why not * Revert "unlikely but why not" This reverts commit 72f45a7516174e230e6a52268e0684a0fed4b76f. * Revert "nuke more on CI" This reverts commit 7f406efc244fc72cdb748f5de027e1fa266dead8. * try this * Revert "try this" This reverts commit 3ce67680675bcecc04515c798276ffef79442c72. * same across --- selfdrive/ui/qt/offroad/settings.cc | 11 ++- selfdrive/ui/sunnypilot/SConscript | 1 + .../qt/offroad/settings/device_panel.cc | 88 +++++++++++++++++++ .../qt/offroad/settings/device_panel.h | 51 +++++++++++ .../qt/offroad/settings/settings.cc | 11 +-- .../sunnypilot/qt/offroad/settings/settings.h | 2 +- .../qt/offroad/settings/sunnypilot_panel.cc | 4 +- .../qt/offroad/settings/sunnypilot_panel.h | 2 +- selfdrive/ui/sunnypilot/qt/widgets/controls.h | 4 +- selfdrive/ui/tests/test_ui/run.py | 2 +- selfdrive/ui/translations/main_ar.ts | 39 ++++++++ selfdrive/ui/translations/main_de.ts | 39 ++++++++ selfdrive/ui/translations/main_es.ts | 39 ++++++++ selfdrive/ui/translations/main_fr.ts | 39 ++++++++ selfdrive/ui/translations/main_ja.ts | 39 ++++++++ selfdrive/ui/translations/main_ko.ts | 39 ++++++++ selfdrive/ui/translations/main_pt-BR.ts | 39 ++++++++ selfdrive/ui/translations/main_th.ts | 39 ++++++++ selfdrive/ui/translations/main_tr.ts | 39 ++++++++ selfdrive/ui/translations/main_zh-CHS.ts | 39 ++++++++ selfdrive/ui/translations/main_zh-CHT.ts | 39 ++++++++ 21 files changed, 590 insertions(+), 15 deletions(-) create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 4911dc71e9..b633bdf33a 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -203,6 +203,11 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { }); addItem(pair_device); + QObject::connect(uiState()->prime_state, &PrimeState::changed, [this] (PrimeState::Type type) { + pair_device->setVisible(type == PrimeState::PRIME_TYPE_UNPAIRED); + }); + +#ifndef SUNNYPILOT // offroad-only buttons auto dcamBtn = new ButtonControl(tr("Driver Camera"), tr("PREVIEW"), @@ -214,6 +219,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { dcamBtn->setEnabled(true); }); addItem(dcamBtn); +#endif auto resetCalibBtn = new ButtonControl(tr("Reset Calibration"), tr("RESET"), ""); connect(resetCalibBtn, &ButtonControl::showDescriptionEvent, this, &DevicePanel::updateCalibDescription); @@ -225,6 +231,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { }); addItem(resetCalibBtn); +#ifndef SUNNYPILOT auto retrainingBtn = new ButtonControl(tr("Review Training Guide"), tr("REVIEW"), tr("Review the rules, features, and limitations of openpilot")); connect(retrainingBtn, &ButtonControl::clicked, [=]() { if (ConfirmationDialog::confirm(tr("Are you sure you want to review the training guide?"), tr("Review"), this)) { @@ -255,9 +262,6 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { }); addItem(translateBtn); - QObject::connect(uiState()->prime_state, &PrimeState::changed, [this] (PrimeState::Type type) { - pair_device->setVisible(type == PrimeState::PRIME_TYPE_UNPAIRED); - }); QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) { for (auto btn : findChildren()) { if (btn != pair_device) { @@ -291,6 +295,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { #poweroff_btn:pressed { background-color: #FF2424; } )"); addItem(power_layout); +#endif } void DevicePanel::updateCalibDescription() { diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index 8bfe1d79db..821801e5a7 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -16,6 +16,7 @@ qt_src = [ "sunnypilot/qt/window.cc", "sunnypilot/qt/home.cc", "sunnypilot/qt/offroad/offroad_home.cc", + "sunnypilot/qt/offroad/settings/device_panel.cc", "sunnypilot/qt/offroad/settings/settings.cc", "sunnypilot/qt/offroad/settings/software_panel.cc", "sunnypilot/qt/offroad/settings/sunnylink_panel.cc", diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc new file mode 100644 index 0000000000..36a56c9d88 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + * + * This file is part of sunnypilot and is licensed under the MIT License. + * See the LICENSE.md file in the root directory for more details. + */ + +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h" + +#include "common/watchdog.h" +#include "selfdrive/ui/qt/offroad/driverview.h" +#include "selfdrive/ui/qt/qt_window.h" + +DevicePanelSP::DevicePanelSP(SettingsWindowSP *parent) : DevicePanel(parent) { + QGridLayout *device_grid_layout = new QGridLayout(); + device_grid_layout->setSpacing(30); + device_grid_layout->setHorizontalSpacing(5); + device_grid_layout->setVerticalSpacing(25); + + std::vector> device_btns = { + {"dcamBtn", tr("Driver Camera Preview")}, + {"retrainingBtn", tr("Training Guide")}, + {"regulatoryBtn", tr("Regulatory")}, + {"translateBtn", tr("Language")}, + }; + + for (int i = 0; i < device_btns.size(); i++) { + auto *btn = new PushButtonSP(device_btns[i].second, 720, this); + device_grid_layout->addWidget(btn, i / 2, i % 2); + buttons[device_btns[i].first] = btn; + } + + connect(buttons["dcamBtn"], &PushButtonSP::clicked, [this]() { + buttons["dcamBtn"]->setEnabled(false); + DriverViewDialog driver_view(this); + driver_view.exec(); + buttons["dcamBtn"]->setEnabled(true); + }); + + connect(buttons["retrainingBtn"], &PushButtonSP::clicked, [=]() { + if (ConfirmationDialog::confirm(tr("Are you sure you want to review the training guide?"), tr("Review"), this)) { + emit reviewTrainingGuide(); + } + }); + + if (Hardware::TICI()) { + connect(buttons["regulatoryBtn"], &PushButtonSP::clicked, [=]() { + const std::string txt = util::read_file("../assets/offroad/fcc.html"); + ConfirmationDialog::rich(QString::fromStdString(txt), this); + }); + } else { + buttons["regulatoryBtn"]->setEnabled(false); + } + + connect(buttons["translateBtn"], &PushButtonSP::clicked, [=]() { + QMap langs = getSupportedLanguages(); + QString selection = MultiOptionDialog::getSelection(tr("Select a language"), langs.keys(), langs.key(uiState()->language), this); + if (!selection.isEmpty()) { + // put language setting, exit Qt UI, and trigger fast restart + params.put("LanguageSetting", langs[selection].toStdString()); + qApp->exit(18); + watchdog_kick(0); + } + }); + + addItem(device_grid_layout); + + // offroad mode and power buttons + + QHBoxLayout *power_layout = new QHBoxLayout(); + power_layout->setSpacing(5); + + QPushButton *rebootBtn = new PushButtonSP(tr("Reboot"), 720, this); + rebootBtn->setStyleSheet(rebootButtonStyle); + power_layout->addWidget(rebootBtn); + QObject::connect(rebootBtn, &PushButtonSP::clicked, this, &DevicePanelSP::reboot); + + QPushButton *poweroffBtn = new PushButtonSP(tr("Power Off"), 720, this); + poweroffBtn->setStyleSheet(powerOffButtonStyle); + power_layout->addWidget(poweroffBtn); + QObject::connect(poweroffBtn, &PushButtonSP::clicked, this, &DevicePanelSP::poweroff); + + if (!Hardware::PC()) { + connect(uiState(), &UIState::offroadTransition, poweroffBtn, &PushButtonSP::setVisible); + } + + addItem(power_layout); +} diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h new file mode 100644 index 0000000000..f1a18a8257 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + * + * This file is part of sunnypilot and is licensed under the MIT License. + * See the LICENSE.md file in the root directory for more details. + */ + +#pragma once + +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" + +class DevicePanelSP : public DevicePanel { + Q_OBJECT + +public: + explicit DevicePanelSP(SettingsWindowSP *parent = 0); + +private: + std::map buttons; + + const QString rebootButtonStyle = R"( + PushButtonSP { + border-radius: 20px; + font-size: 50px; + font-weight: 450; + height: 150px; + padding: 0 25px 0 25px; + color: #FFFFFF; + background-color: #393939; + } + PushButtonSP:pressed { + background-color: #4A4A4A; + } + )"; + + const QString powerOffButtonStyle = R"( + PushButtonSP { + border-radius: 20px; + font-size: 50px; + font-weight: 450; + height: 150px; + padding: 0 25px 0 25px; + color: #FFFFFF; + background-color: #E22C2C; + } + PushButtonSP:pressed { + background-color: #FF2424; + } + )"; +}; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc index d8e9d83dee..9338b93220 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc @@ -11,12 +11,13 @@ #include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h" #include "selfdrive/ui/qt/offroad/developer_panel.h" +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/trips_panel.h" -TogglesPanelSP::TogglesPanelSP(SettingsWindow *parent) : TogglesPanel(parent) { +TogglesPanelSP::TogglesPanelSP(SettingsWindowSP *parent) : TogglesPanel(parent) { QObject::connect(uiStateSP(), &UIStateSP::uiUpdate, this, &TogglesPanelSP::updateState); } @@ -50,7 +51,7 @@ SettingsWindowSP::SettingsWindowSP(QWidget *parent) : SettingsWindow(parent) { )"); close_btn->setFixedSize(152, 152); close_btn_layout->addWidget(close_btn, 0, Qt::AlignLeft); - QObject::connect(close_btn, &QPushButton::clicked, this, &SettingsWindow::closeSettings); + QObject::connect(close_btn, &QPushButton::clicked, this, &SettingsWindowSP::closeSettings); // setup buttons widget QWidget *buttons_widget = new QWidget; @@ -59,11 +60,11 @@ SettingsWindowSP::SettingsWindowSP(QWidget *parent) : SettingsWindow(parent) { buttons_layout->addSpacing(10); // setup panels - DevicePanel *device = new DevicePanel(this); - QObject::connect(device, &DevicePanel::reviewTrainingGuide, this, &SettingsWindow::reviewTrainingGuide); + DevicePanelSP *device = new DevicePanelSP(this); + QObject::connect(device, &DevicePanelSP::reviewTrainingGuide, this, &SettingsWindowSP::reviewTrainingGuide); TogglesPanelSP *toggles = new TogglesPanelSP(this); - QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription); + QObject::connect(this, &SettingsWindowSP::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription); auto networking = new Networking(this); QObject::connect(uiState()->prime_state, &PrimeState::changed, networking, &Networking::setPrimeType); diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h index 5678a3171b..2fe511cc48 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h @@ -32,7 +32,7 @@ class TogglesPanelSP : public TogglesPanel { Q_OBJECT public: - explicit TogglesPanelSP(SettingsWindow *parent); + explicit TogglesPanelSP(SettingsWindowSP *parent); private slots: void updateState(const UIStateSP &s); diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.cc index 6671208fea..82d07febb8 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.cc @@ -27,13 +27,13 @@ SunnypilotPanel::SunnypilotPanel(SettingsWindowSP *parent) : QFrame(parent) { madsToggle->setConfirmation(true, false); list->addItem(madsToggle); - madsSettingsButton = new SubPanelButton(tr("Customize MADS")); + madsSettingsButton = new PushButtonSP(tr("Customize MADS")); madsSettingsButton->setObjectName("mads_btn"); connect(madsSettingsButton, &QPushButton::clicked, [=]() { sunnypilotScroller->setLastScrollPosition(); main_layout->setCurrentWidget(madsWidget); }); - QObject::connect(madsToggle, &ToggleControl::toggleFlipped, madsSettingsButton, &SubPanelButton::setEnabled); + QObject::connect(madsToggle, &ToggleControl::toggleFlipped, madsSettingsButton, &PushButtonSP::setEnabled); madsWidget = new MadsSettings(this); connect(madsWidget, &MadsSettings::backPress, [=]() { diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.h index 8077522473..e955995b34 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.h @@ -35,6 +35,6 @@ private: bool offroad; ParamControl *madsToggle; - SubPanelButton *madsSettingsButton; + PushButtonSP *madsSettingsButton; MadsSettings *madsWidget = nullptr; }; diff --git a/selfdrive/ui/sunnypilot/qt/widgets/controls.h b/selfdrive/ui/sunnypilot/qt/widgets/controls.h index a5071d97e7..a7c60980fa 100644 --- a/selfdrive/ui/sunnypilot/qt/widgets/controls.h +++ b/selfdrive/ui/sunnypilot/qt/widgets/controls.h @@ -546,11 +546,11 @@ private: bool button_enabled = true; }; -class SubPanelButton : public QPushButton { +class PushButtonSP : public QPushButton { Q_OBJECT public: - SubPanelButton(const QString &text, const int minimum_button_width = 800, QWidget *parent = nullptr) : QPushButton(text, parent) { + PushButtonSP(const QString &text, const int minimum_button_width = 800, QWidget *parent = nullptr) : QPushButton(text, parent) { const QString buttonStyle = R"( QPushButton { border-radius: 20px; diff --git a/selfdrive/ui/tests/test_ui/run.py b/selfdrive/ui/tests/test_ui/run.py index 5bc4857689..e3c71050ba 100644 --- a/selfdrive/ui/tests/test_ui/run.py +++ b/selfdrive/ui/tests/test_ui/run.py @@ -129,7 +129,7 @@ def setup_keyboard(click, pm: PubMaster, scroll=None): def setup_driver_camera(click, pm: PubMaster, scroll=None): setup_settings_device(click, pm) - click(1950, 435) + click(950, 620) DATA['deviceState'].deviceState.started = False setup_onroad(click, pm) DATA['deviceState'].deviceState.started = True diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 5dbd71ff19..bd1452612c 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -275,6 +275,45 @@ إقران + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + إعادة التشغيل + + + Regulatory + التنظيمية + + + Are you sure you want to review the training guide? + هل أنت متأكد أنك تريد مراجعة دليل التدريب؟ + + + Review + مراجعة + + + Select a language + اختر لغة + + + Power Off + إيقاف التشغيل + + DriveStats diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 9d6d626552..f015d2ea5f 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -275,6 +275,45 @@ + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + Neustart + + + Regulatory + Rechtliche Hinweise + + + Are you sure you want to review the training guide? + Bist du sicher, dass du die Trainingsanleitung wiederholen möchtest? + + + Review + Überprüfen + + + Select a language + Sprache wählen + + + Power Off + Ausschalten + + DriveStats diff --git a/selfdrive/ui/translations/main_es.ts b/selfdrive/ui/translations/main_es.ts index 773704061a..658f131a36 100644 --- a/selfdrive/ui/translations/main_es.ts +++ b/selfdrive/ui/translations/main_es.ts @@ -275,6 +275,45 @@ Desactivar para apagar + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + Reiniciar + + + Regulatory + Regulador + + + Are you sure you want to review the training guide? + ¿Seguro que quiere revisar la guía de entrenamiento? + + + Review + Revisar + + + Select a language + + + + Power Off + Apagar + + DriveStats diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index 4173a6218a..7e2f6649d6 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -275,6 +275,45 @@ + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + Redémarrer + + + Regulatory + Réglementaire + + + Are you sure you want to review the training guide? + Êtes-vous sûr de vouloir revoir le guide de formation ? + + + Review + Revoir + + + Select a language + Choisir une langue + + + Power Off + Éteindre + + DriveStats diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 5e0ac26d29..0229a36bd6 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -275,6 +275,45 @@ + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + 再起動 + + + Regulatory + 認証情報 + + + Are you sure you want to review the training guide? + 使い方の確認をしますか? + + + Review + 確認 + + + Select a language + 言語を選択 + + + Power Off + 電源を切る + + DriveStats diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 899f92c033..0b1c82e92c 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -275,6 +275,45 @@ 동기화 + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + 재부팅 + + + Regulatory + 규제 + + + Are you sure you want to review the training guide? + 트레이닝 가이드를 다시 확인하시겠습니까? + + + Review + 다시보기 + + + Select a language + 언어를 선택하세요 + + + Power Off + 전원 끄기 + + DriveStats diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 997e202cc2..2a2693961e 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -275,6 +275,45 @@ PAREAR + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + Reiniciar + + + Regulatory + Regulatório + + + Are you sure you want to review the training guide? + Tem certeza que quer rever o treinamento? + + + Review + Revisar + + + Select a language + Selecione o Idioma + + + Power Off + Desligar + + DriveStats diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index 54221383b4..c2557a6faa 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -275,6 +275,45 @@ จับคู่ + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + รีบูต + + + Regulatory + ระเบียบข้อบังคับ + + + Are you sure you want to review the training guide? + คุณแน่ใจหรือไม่ว่าต้องการทบทวนคู่มือการใช้งาน? + + + Review + ทบทวน + + + Select a language + เลือกภาษา + + + Power Off + ปิดเครื่อง + + DriveStats diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index 9deae8ba4f..ac22574b97 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -275,6 +275,45 @@ + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + Yeniden başlat + + + Regulatory + Mevzuat + + + Are you sure you want to review the training guide? + Eğitim kılavuzunu incelemek istediğinizden emin misiniz? + + + Review + + + + Select a language + Dil seçin + + + Power Off + Sistemi kapat + + DriveStats diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 30550519a5..d284bbac6e 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -275,6 +275,45 @@ 配对 + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + 重启 + + + Regulatory + 监管信息 + + + Are you sure you want to review the training guide? + 您确定要查看新手指南吗? + + + Review + 预览 + + + Select a language + 选择语言 + + + Power Off + 关机 + + DriveStats diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index f5e89aa4db..37c9d0c70f 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -275,6 +275,45 @@ 配對 + + DevicePanelSP + + Driver Camera Preview + + + + Training Guide + + + + Language + + + + Reboot + 重新啟動 + + + Regulatory + 法規/監管 + + + Are you sure you want to review the training guide? + 您確定要觀看使用教學嗎? + + + Review + 回顧 + + + Select a language + 選擇語言 + + + Power Off + 關機 + + DriveStats