From 0b16ed9dc9a30b18998087e114acf14ff09c9708 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Mar 2021 21:18:07 -0700 Subject: [PATCH] Qt UI: offroad home touchups (#20416) * brand * fix overlap * touchup prime widget * more prime widget cleanup * don't need background layout * fix overlap again * more prime * looks pretty good Co-authored-by: Comma Device --- selfdrive/ui/qt/home.cc | 12 ++- selfdrive/ui/qt/widgets/setup.cc | 159 +++++++++++++++--------------- selfdrive/ui/qt/widgets/setup.hpp | 4 +- 3 files changed, 92 insertions(+), 83 deletions(-) diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index d617db8a3b..d8ced484ad 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -93,8 +93,9 @@ OffroadHome::OffroadHome(QWidget* parent) : QWidget(parent) { date->setStyleSheet(R"(font-size: 55px;)"); header_layout->addWidget(date, 0, Qt::AlignTop | Qt::AlignLeft); - QLabel* version = new QLabel(QString::fromStdString("openpilot v" + Params().get("Version"))); - version->setStyleSheet(R"(font-size: 45px;)"); + std::string brand = Params().read_db_bool("Passive") ? "dashcam" : "openpilot"; + QLabel* version = new QLabel(QString::fromStdString(brand + " v" + Params().get("Version"))); + version->setStyleSheet(R"(font-size: 55px;)"); header_layout->addWidget(version, 0, Qt::AlignTop | Qt::AlignRight); main_layout->addLayout(header_layout); @@ -110,11 +111,12 @@ OffroadHome::OffroadHome(QWidget* parent) : QWidget(parent) { QHBoxLayout* statsAndSetup = new QHBoxLayout(); DriveStats* drive = new DriveStats; - drive->setFixedSize(1000, 800); - statsAndSetup->addWidget(drive); + drive->setFixedSize(800, 800); + statsAndSetup->addWidget(drive, 0, Qt::AlignLeft); SetupWidget* setup = new SetupWidget; - statsAndSetup->addWidget(setup); + setup->setFixedSize(700, 700); + statsAndSetup->addWidget(setup, 0, Qt::AlignRight); QWidget* statsAndSetupWidget = new QWidget(); statsAndSetupWidget->setLayout(statsAndSetup); diff --git a/selfdrive/ui/qt/widgets/setup.cc b/selfdrive/ui/qt/widgets/setup.cc index fccfe0d206..43e3387a70 100644 --- a/selfdrive/ui/qt/widgets/setup.cc +++ b/selfdrive/ui/qt/widgets/setup.cc @@ -24,7 +24,7 @@ PairingQRWidget::PairingQRWidget(QWidget* parent) : QWidget(parent) { QTimer* timer = new QTimer(this); timer->start(30 * 1000); connect(timer, SIGNAL(timeout()), this, SLOT(refresh())); - refresh(); // Not waiting for the first refresh + refresh(); // don't wait for the first refresh } void PairingQRWidget::refresh(){ @@ -48,7 +48,7 @@ void PairingQRWidget::refresh(){ void PairingQRWidget::updateQrCode(QString text) { QrCode qr = QrCode::encodeText(text.toUtf8().data(), QrCode::Ecc::LOW); qint32 sz = qr.getSize(); - // We make the image larger so we can have a white border + // make the image larger so we can have a white border QImage im(sz + 2, sz + 2, QImage::Format_RGB32); QRgb black = qRgb(0, 0, 0); QRgb white = qRgb(255, 255, 255); @@ -71,32 +71,43 @@ void PairingQRWidget::updateQrCode(QString text) { PrimeUserWidget::PrimeUserWidget(QWidget* parent) : QWidget(parent) { mainLayout = new QVBoxLayout; + mainLayout->setMargin(30); + QLabel* commaPrime = new QLabel("COMMA PRIME"); - commaPrime->setStyleSheet(R"( - font-size: 60px; - )"); - mainLayout->addWidget(commaPrime); + mainLayout->addWidget(commaPrime, 0, Qt::AlignTop); - username = new QLabel(""); - mainLayout->addWidget(username); + username = new QLabel(); + username->setStyleSheet("font-size: 55px;"); // TODO: fit width + mainLayout->addWidget(username, 0, Qt::AlignTop); - mainLayout->addSpacing(200); + mainLayout->addSpacing(100); QLabel* commaPoints = new QLabel("COMMA POINTS"); commaPoints->setStyleSheet(R"( - font-size: 60px; color: #b8b8b8; )"); - mainLayout->addWidget(commaPoints); + mainLayout->addWidget(commaPoints, 0, Qt::AlignTop); - points = new QLabel(""); - mainLayout->addWidget(points); + points = new QLabel(); + mainLayout->addWidget(points, 0, Qt::AlignTop); setLayout(mainLayout); + setStyleSheet(R"( + QLabel { + font-size: 70px; + font-weight: 500; + } + )"); + + // set up API requests QString dongleId = QString::fromStdString(Params().get("DongleId")); + if (!dongleId.length()) { + return; + } + + // TODO: only send the request when widget is shown QString url = "https://api.commadotai.com/v1/devices/" + dongleId + "/owner"; RequestRepeater* repeater = new RequestRepeater(this, url, 6); - QObject::connect(repeater, SIGNAL(receivedResponse(QString)), this, SLOT(replyFinished(QString))); } @@ -106,12 +117,13 @@ void PrimeUserWidget::replyFinished(QString response) { qDebug() << "JSON Parse failed on getting username and points"; return; } + QJsonObject json = doc.object(); + QString points_str = QString::number(json["points"].toInt()); QString username_str = json["username"].toString(); if (username_str.length()) { username_str = "@" + username_str; } - QString points_str = QString::number(json["points"].toInt()); username->setText(username_str); points->setText(points_str); @@ -119,101 +131,106 @@ void PrimeUserWidget::replyFinished(QString response) { PrimeAdWidget::PrimeAdWidget(QWidget* parent) : QWidget(parent) { QVBoxLayout* vlayout = new QVBoxLayout; + vlayout->setMargin(30); + vlayout->setSpacing(15); - QLabel* upgradeNow = new QLabel("Upgrade now"); - vlayout->addWidget(upgradeNow); + vlayout->addWidget(new QLabel("Upgrade now"), 1, Qt::AlignTop); - QLabel* description = new QLabel("Become a comma prime member in the comma app and get premium features!"); + QLabel* description = new QLabel("Become a comma prime member in the comma connect app and get premium features!"); description->setStyleSheet(R"( font-size: 50px; color: #b8b8b8; )"); description->setWordWrap(true); - vlayout->addWidget(description); - - vlayout->addSpacing(50); + vlayout->addWidget(description, 2, Qt::AlignTop); QVector features = {"✓ REMOTE ACCESS", "✓ 14 DAYS OF STORAGE", "✓ DEVELOPER PERKS"}; - for (auto featureContent : features) { - QLabel* feature = new QLabel(featureContent); - feature->setStyleSheet(R"( - font-size: 40px; - )"); - - vlayout->addWidget(feature); - vlayout->addSpacing(15); + for (auto &f: features) { + QLabel* feature = new QLabel(f); + feature->setStyleSheet(R"(font-size: 40px;)"); + vlayout->addWidget(feature, 0, Qt::AlignBottom); } setLayout(vlayout); } -SetupWidget::SetupWidget(QWidget* parent) : QWidget(parent) { - QVBoxLayout* backgroundLayout = new QVBoxLayout; - - backgroundLayout->addSpacing(100); - - QFrame* background = new QFrame; - +SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) { mainLayout = new QStackedLayout; QWidget* blankWidget = new QWidget; + //blankWidget->setStyleSheet(R"background-color: transparent;"); mainLayout->addWidget(blankWidget); - QWidget* finishRegistration = new QWidget; + // Unpaired, registration prompt layout QVBoxLayout* finishRegistationLayout = new QVBoxLayout; - finishRegistationLayout->addSpacing(30); - QPushButton* finishButton = new QPushButton("Finish registration"); - finishButton->setFixedHeight(200); - finishButton->setStyleSheet(R"( - border-radius: 30px; - font-size: 55px; - background: #585858; - )"); - QObject::connect(finishButton, SIGNAL(released()), this, SLOT(showQrCode())); - finishRegistationLayout->addWidget(finishButton); + finishRegistationLayout ->setMargin(30); QLabel* registrationDescription = new QLabel("Pair your device with the comma connect app"); + registrationDescription->setWordWrap(true); + registrationDescription->setAlignment(Qt::AlignCenter); registrationDescription->setStyleSheet(R"( font-size: 55px; font-weight: 400; )"); - registrationDescription->setWordWrap(true); finishRegistationLayout->addWidget(registrationDescription); + QPushButton* finishButton = new QPushButton("Finish setup"); + finishButton->setFixedHeight(200); + finishButton->setStyleSheet(R"( + border-radius: 30px; + font-size: 55px; + font-weight: 500; + background: #585858; + )"); + finishRegistationLayout->addWidget(finishButton); + QObject::connect(finishButton, SIGNAL(released()), this, SLOT(showQrCode())); + + QWidget* finishRegistration = new QWidget; finishRegistration->setLayout(finishRegistationLayout); mainLayout->addWidget(finishRegistration); + // Pairing QR code layout + QVBoxLayout* qrLayout = new QVBoxLayout; - QLabel* qrLabel = new QLabel("Pair with comma connect!"); - qrLabel->setStyleSheet(R"(font-size: 40px)"); - qrLayout->addWidget(qrLabel); + qrLayout->addSpacing(40); + QLabel* qrLabel = new QLabel("Scan with comma connect!"); + qrLabel->setWordWrap(true); + qrLabel->setAlignment(Qt::AlignHCenter); + qrLabel->setStyleSheet(R"( + font-size: 55px; + font-weight: 400; + )"); + qrLayout->addWidget(qrLabel, 0, Qt::AlignTop); - qrLayout->addWidget(new PairingQRWidget); + qrLayout->addWidget(new PairingQRWidget, 1); QWidget* q = new QWidget; q->setLayout(qrLayout); mainLayout->addWidget(q); - PrimeAdWidget* primeAd = new PrimeAdWidget; + primeAd = new PrimeAdWidget; mainLayout->addWidget(primeAd); - PrimeUserWidget* primeUserWidget = new PrimeUserWidget; - mainLayout->addWidget(primeUserWidget); + primeUser = new PrimeUserWidget; + mainLayout->addWidget(primeUser); - background->setLayout(mainLayout); - background->setStyleSheet(R"( - .QFrame { + setLayout(mainLayout); + setStyleSheet(R"( + QFrame { + background-color: #292929; + } + * { + font-size: 90px; + font-weight: 500; border-radius: 40px; - padding: 40px; } )"); - backgroundLayout->addWidget(background); - setLayout(backgroundLayout); + // set up API requests QString dongleId = QString::fromStdString(Params().get("DongleId")); QString url = "https://api.commadotai.com/v1.1/devices/" + dongleId + "/"; RequestRepeater* repeater = new RequestRepeater(this, url, 5); @@ -225,10 +242,6 @@ SetupWidget::SetupWidget(QWidget* parent) : QWidget(parent) { void SetupWidget::parseError(QString response) { showQr = false; mainLayout->setCurrentIndex(0); - setStyleSheet(R"( - font-size: 90px; - background-color: #000000; - )"); } void SetupWidget::showQrCode(){ @@ -243,25 +256,17 @@ void SetupWidget::replyFinished(QString response) { return; } - if (mainLayout->currentIndex() == 0) { // If we are still on the blank widget - setStyleSheet(R"( - font-size: 90px; - font-weight: bold; - background-color: #292929; - )"); - } - QJsonObject json = doc.object(); bool is_paired = json["is_paired"].toBool(); bool is_prime = json["prime"].toBool(); if (!is_paired) { mainLayout->setCurrentIndex(1 + showQr); - } else if (is_paired && !is_prime) { + } else if (!is_prime) { showQr = false; - mainLayout->setCurrentIndex(3); - } else if (is_paired && is_prime) { + mainLayout->setCurrentWidget(primeAd); + } else { showQr = false; - mainLayout->setCurrentIndex(4); + mainLayout->setCurrentWidget(primeUser); } } diff --git a/selfdrive/ui/qt/widgets/setup.hpp b/selfdrive/ui/qt/widgets/setup.hpp index 8fed2a1bbc..6cd18b1bc7 100644 --- a/selfdrive/ui/qt/widgets/setup.hpp +++ b/selfdrive/ui/qt/widgets/setup.hpp @@ -41,7 +41,7 @@ public: explicit PrimeAdWidget(QWidget* parent = 0); }; -class SetupWidget : public QWidget { +class SetupWidget : public QFrame { Q_OBJECT public: @@ -50,6 +50,8 @@ public: private: QStackedLayout* mainLayout; CommaApi* api; + PrimeAdWidget *primeAd; + PrimeUserWidget *primeUser; bool showQr = false; private slots: