diff --git a/selfdrive/assets/offroad/icon_wifi_uploading.svg b/selfdrive/assets/offroad/icon_wifi_uploading.svg
new file mode 100644
index 0000000000..95cb0e283e
--- /dev/null
+++ b/selfdrive/assets/offroad/icon_wifi_uploading.svg
@@ -0,0 +1,6 @@
+
diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript
index f54d72ae31..f46e3d5873 100644
--- a/selfdrive/ui/SConscript
+++ b/selfdrive/ui/SConscript
@@ -20,7 +20,7 @@ if arch == "Darwin":
qt_env['FRAMEWORKS'] += ['OpenCL']
qt_util = qt_env.Library("qt_util", ["#selfdrive/ui/qt/api.cc", "#selfdrive/ui/qt/util.cc"], LIBS=base_libs)
-widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/drive_stats.cc",
+widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/drive_stats.cc", "qt/widgets/wifi.cc",
"qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc",
"qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc",
"qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc",
diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc
index 2b8974f73a..587e2f445e 100644
--- a/selfdrive/ui/qt/home.cc
+++ b/selfdrive/ui/qt/home.cc
@@ -2,6 +2,7 @@
#include
#include
+#include
#include
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
@@ -136,21 +137,34 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
home_layout->setContentsMargins(0, 0, 0, 0);
home_layout->setSpacing(30);
- // left: ExperimentalModeButton, DriveStats
- QWidget* left_widget = new QWidget(this);
- QVBoxLayout* left_column = new QVBoxLayout(left_widget);
- left_column->setContentsMargins(0, 0, 0, 0);
- left_column->setSpacing(30);
+ // left: DriveStats/PrimeAdWidget
+ QStackedWidget *left_widget = new QStackedWidget(this);
+ left_widget->addWidget(new DriveStats);
+ left_widget->addWidget(new PrimeAdWidget);
+
+ left_widget->setCurrentIndex(uiState()->primeType() ? 0 : 1);
+ connect(uiState(), &UIState::primeTypeChanged, [=](int prime_type) {
+ left_widget->setCurrentIndex(prime_type ? 0 : 1);
+ });
+
+ home_layout->addWidget(left_widget, 1);
+
+ // right: ExperimentalModeButton, SetupWidget
+ QWidget* right_widget = new QWidget(this);
+ QVBoxLayout* right_column = new QVBoxLayout(right_widget);
+ right_column->setContentsMargins(0, 0, 0, 0);
+ right_widget->setFixedWidth(750);
+ right_column->setSpacing(30);
ExperimentalModeButton *experimental_mode = new ExperimentalModeButton(this);
QObject::connect(experimental_mode, &ExperimentalModeButton::openSettings, this, &OffroadHome::openSettings);
- left_column->addWidget(experimental_mode, 1);
- left_column->addWidget(new DriveStats, 1);
+ right_column->addWidget(experimental_mode, 1);
- home_layout->addWidget(left_widget, 1);
+ SetupWidget *setup_widget = new SetupWidget;
+ QObject::connect(setup_widget, &SetupWidget::openSettings, this, &OffroadHome::openSettings);
+ right_column->addWidget(setup_widget, 1);
- // right: SetupWidget
- home_layout->addWidget(new SetupWidget);
+ home_layout->addWidget(right_widget, 1);
}
center_layout->addWidget(home_widget);
@@ -170,7 +184,7 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
setStyleSheet(R"(
* {
- color: white;
+ color: white;
}
OffroadHome {
background-color: black;
diff --git a/selfdrive/ui/qt/widgets/prime.cc b/selfdrive/ui/qt/widgets/prime.cc
index fb4aea2b1c..86bd918e0c 100644
--- a/selfdrive/ui/qt/widgets/prime.cc
+++ b/selfdrive/ui/qt/widgets/prime.cc
@@ -14,6 +14,7 @@
#include "selfdrive/ui/qt/request_repeater.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/qt_window.h"
+#include "selfdrive/ui/qt/widgets/wifi.h"
using qrcodegen::QrCode;
@@ -123,26 +124,18 @@ PrimeUserWidget::PrimeUserWidget(QWidget* parent) : QFrame(parent) {
QWidget *primeWidget = new QWidget;
primeWidget->setObjectName("primeWidget");
QVBoxLayout *primeLayout = new QVBoxLayout(primeWidget);
- primeLayout->setContentsMargins(60, 50, 60, 50);
+ primeLayout->setContentsMargins(56, 40, 56, 40);
+ primeLayout->setSpacing(20);
QLabel *subscribed = new QLabel(tr("✓ SUBSCRIBED"));
subscribed->setStyleSheet("font-size: 41px; font-weight: bold; color: #86FF4E;");
- primeLayout->addWidget(subscribed, 0, Qt::AlignTop);
-
- primeLayout->addSpacing(60);
+ primeLayout->addWidget(subscribed);
QLabel *commaPrime = new QLabel(tr("comma prime"));
commaPrime->setStyleSheet("font-size: 75px; font-weight: bold;");
- primeLayout->addWidget(commaPrime, 0, Qt::AlignTop);
-
- primeLayout->addSpacing(20);
-
- QLabel *connectUrl = new QLabel(tr("CONNECT.COMMA.AI"));
- connectUrl->setStyleSheet("font-size: 41px; font-family: Inter SemiBold; color: #A0A0A0;");
- primeLayout->addWidget(connectUrl, 0, Qt::AlignTop);
+ primeLayout->addWidget(commaPrime);
mainLayout->addWidget(primeWidget);
-
mainLayout->addStretch();
}
@@ -195,8 +188,8 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
QFrame* finishRegistration = new QFrame;
finishRegistration->setObjectName("primeWidget");
QVBoxLayout* finishRegistationLayout = new QVBoxLayout(finishRegistration);
- finishRegistationLayout->setSpacing(40);
- finishRegistationLayout->setContentsMargins(64, 64, 64, 64);
+ finishRegistationLayout->setSpacing(38);
+ finishRegistationLayout->setContentsMargins(64, 48, 64, 48);
QLabel* registrationTitle = new QLabel(tr("Finish Setup"));
registrationTitle->setStyleSheet("font-size: 75px; font-weight: bold;");
@@ -204,7 +197,7 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
QLabel* registrationDescription = new QLabel(tr("Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer."));
registrationDescription->setWordWrap(true);
- registrationDescription->setStyleSheet("font-size: 55px; font-weight: light;");
+ registrationDescription->setStyleSheet("font-size: 50px; font-weight: light;");
finishRegistationLayout->addWidget(registrationDescription);
finishRegistationLayout->addStretch();
@@ -234,15 +227,24 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
outer_layout->setContentsMargins(0, 0, 0, 0);
outer_layout->addWidget(mainLayout);
- primeAd = new PrimeAdWidget;
- mainLayout->addWidget(primeAd);
+ QWidget *content = new QWidget;
+ QVBoxLayout *content_layout = new QVBoxLayout(content);
+ content_layout->setContentsMargins(0, 0, 0, 0);
+ content_layout->setSpacing(30);
primeUser = new PrimeUserWidget;
- mainLayout->addWidget(primeUser);
+ content_layout->addWidget(primeUser);
- mainLayout->setCurrentWidget(uiState()->primeType() ? (QWidget*)primeUser : (QWidget*)primeAd);
+ WiFiPromptWidget *wifi_prompt = new WiFiPromptWidget;
+ QObject::connect(wifi_prompt, &WiFiPromptWidget::openSettings, this, &SetupWidget::openSettings);
+ content_layout->addWidget(wifi_prompt);
+ content_layout->addStretch();
+
+ mainLayout->addWidget(content);
+
+ primeUser->setVisible(uiState()->primeType());
+ mainLayout->setCurrentIndex(1);
- setFixedWidth(750);
setStyleSheet(R"(
#primeWidget {
border-radius: 10px;
@@ -282,10 +284,7 @@ void SetupWidget::replyFinished(const QString &response, bool success) {
} else {
popup->reject();
- if (prime_type) {
- mainLayout->setCurrentWidget(primeUser);
- } else {
- mainLayout->setCurrentWidget(primeAd);
- }
+ primeUser->setVisible(prime_type);
+ mainLayout->setCurrentIndex(1);
}
}
diff --git a/selfdrive/ui/qt/widgets/prime.h b/selfdrive/ui/qt/widgets/prime.h
index 9c7b4460fc..b41bab1695 100644
--- a/selfdrive/ui/qt/widgets/prime.h
+++ b/selfdrive/ui/qt/widgets/prime.h
@@ -69,10 +69,12 @@ class SetupWidget : public QFrame {
public:
explicit SetupWidget(QWidget* parent = 0);
+signals:
+ void openSettings(int index = 0, const QString ¶m = "");
+
private:
PairingPopup *popup;
QStackedWidget *mainLayout;
- PrimeAdWidget *primeAd;
PrimeUserWidget *primeUser;
private slots:
diff --git a/selfdrive/ui/qt/widgets/wifi.cc b/selfdrive/ui/qt/widgets/wifi.cc
new file mode 100644
index 0000000000..b717a00d98
--- /dev/null
+++ b/selfdrive/ui/qt/widgets/wifi.cc
@@ -0,0 +1,103 @@
+#include "selfdrive/ui/qt/widgets/wifi.h"
+
+#include
+#include
+#include
+#include
+
+WiFiPromptWidget::WiFiPromptWidget(QWidget *parent) : QFrame(parent) {
+ stack = new QStackedLayout(this);
+
+ // Setup Wi-Fi
+ QFrame *setup = new QFrame;
+ QVBoxLayout *setup_layout = new QVBoxLayout(setup);
+ setup_layout->setContentsMargins(56, 40, 56, 40);
+ setup_layout->setSpacing(20);
+ {
+ QHBoxLayout *title_layout = new QHBoxLayout;
+ title_layout->setSpacing(32);
+ {
+ QLabel *icon = new QLabel;
+ QPixmap *pixmap = new QPixmap("../assets/offroad/icon_wifi_strength_full.svg");
+ icon->setPixmap(pixmap->scaledToWidth(80, Qt::SmoothTransformation));
+ title_layout->addWidget(icon);
+
+ QLabel *title = new QLabel(tr("Setup Wi-Fi"));
+ title->setStyleSheet("font-size: 64px; font-weight: 600;");
+ title_layout->addWidget(title);
+ title_layout->addStretch();
+ }
+ setup_layout->addLayout(title_layout);
+
+ QLabel *desc = new QLabel(tr("Connect to Wi-Fi to upload driving data and help improve openpilot"));
+ desc->setStyleSheet("font-size: 40px; font-weight: 400;");
+ desc->setWordWrap(true);
+ setup_layout->addWidget(desc);
+
+ QPushButton *settings_btn = new QPushButton(tr("Open Settings"));
+ connect(settings_btn, &QPushButton::clicked, [=]() { emit openSettings(1); });
+ settings_btn->setStyleSheet(R"(
+ QPushButton {
+ font-size: 48px;
+ font-weight: 500;
+ border-radius: 10px;
+ background-color: #465BEA;
+ padding: 32px;
+ }
+ QPushButton:pressed {
+ background-color: #3049F4;
+ }
+ )");
+ setup_layout->addWidget(settings_btn);
+ }
+ stack->addWidget(setup);
+
+ // Uploading data
+ QWidget *uploading = new QWidget;
+ QVBoxLayout *uploading_layout = new QVBoxLayout(uploading);
+ uploading_layout->setContentsMargins(64, 56, 64, 56);
+ uploading_layout->setSpacing(36);
+ {
+ QHBoxLayout *title_layout = new QHBoxLayout;
+ {
+ QLabel *title = new QLabel(tr("Uploading training data"));
+ title->setStyleSheet("font-size: 64px; font-weight: 600;");
+ title->setWordWrap(true);
+ title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ title_layout->addWidget(title);
+ title_layout->addStretch();
+
+ QLabel *icon = new QLabel;
+ QPixmap *pixmap = new QPixmap("../assets/offroad/icon_wifi_uploading.svg");
+ icon->setPixmap(pixmap->scaledToWidth(120, Qt::SmoothTransformation));
+ title_layout->addWidget(icon);
+ }
+ uploading_layout->addLayout(title_layout);
+
+ QLabel *desc = new QLabel(tr("Your data is used to train driving models and help improve openpilot"));
+ desc->setStyleSheet("font-size: 48px; font-weight: 400;");
+ desc->setWordWrap(true);
+ uploading_layout->addWidget(desc);
+ }
+ stack->addWidget(uploading);
+
+ setStyleSheet(R"(
+ WiFiPromptWidget {
+ background-color: #333333;
+ border-radius: 10px;
+ }
+ )");
+
+ QObject::connect(uiState(), &UIState::uiUpdate, this, &WiFiPromptWidget::updateState);
+}
+
+void WiFiPromptWidget::updateState(const UIState &s) {
+ if (!isVisible()) return;
+
+ auto &sm = *(s.sm);
+
+ auto network_type = sm["deviceState"].getDeviceState().getNetworkType();
+ auto uploading = network_type == cereal::DeviceState::NetworkType::WIFI ||
+ network_type == cereal::DeviceState::NetworkType::ETHERNET;
+ stack->setCurrentIndex(uploading ? 1 : 0);
+}
diff --git a/selfdrive/ui/qt/widgets/wifi.h b/selfdrive/ui/qt/widgets/wifi.h
new file mode 100644
index 0000000000..60c865f2b8
--- /dev/null
+++ b/selfdrive/ui/qt/widgets/wifi.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include "selfdrive/ui/ui.h"
+
+class WiFiPromptWidget : public QFrame {
+ Q_OBJECT
+
+public:
+ explicit WiFiPromptWidget(QWidget* parent = 0);
+
+signals:
+ void openSettings(int index = 0, const QString ¶m = "");
+
+public slots:
+ void updateState(const UIState &s);
+
+protected:
+ QStackedLayout *stack;
+};
diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts
index 5bec3f674a..71f3df7597 100644
--- a/selfdrive/ui/translations/main_de.ts
+++ b/selfdrive/ui/translations/main_de.ts
@@ -517,10 +517,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1076,6 +1072,29 @@ This may take up to a minute.
Aktualisierung fehlgeschlagen
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts
index 43e4974784..019eb1b71b 100644
--- a/selfdrive/ui/translations/main_ja.ts
+++ b/selfdrive/ui/translations/main_ja.ts
@@ -518,10 +518,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1070,6 +1066,29 @@ This may take up to a minute.
更新失敗
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts
index c985fae0e9..cab5e2ada6 100644
--- a/selfdrive/ui/translations/main_ko.ts
+++ b/selfdrive/ui/translations/main_ko.ts
@@ -518,10 +518,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1071,6 +1067,29 @@ This may take up to a minute.
업데이트 실패
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts
index 9eeedea29c..70f06670a9 100644
--- a/selfdrive/ui/translations/main_pt-BR.ts
+++ b/selfdrive/ui/translations/main_pt-BR.ts
@@ -519,10 +519,6 @@ trabalho definido
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1075,6 +1071,29 @@ Isso pode levar até um minuto.
Falha na atualização
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts
index 9302047ab0..f6924b3c57 100644
--- a/selfdrive/ui/translations/main_zh-CHS.ts
+++ b/selfdrive/ui/translations/main_zh-CHS.ts
@@ -516,10 +516,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1068,6 +1064,29 @@ This may take up to a minute.
更新失败
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts
index 5d17a7b86a..243a91ebd1 100644
--- a/selfdrive/ui/translations/main_zh-CHT.ts
+++ b/selfdrive/ui/translations/main_zh-CHT.ts
@@ -518,10 +518,6 @@ location set
comma prime
comma 高級會員
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1070,6 +1066,29 @@ This may take up to a minute.
更新失敗
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI