diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index 71be002e..c51414f3 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -61,7 +61,6 @@ void HomeWindow::mousePressEvent(QMouseEvent* e) { } } - // OffroadHome: the offroad home page OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) { @@ -99,7 +98,6 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) { statsAndSetup->addWidget(drive); SetupWidget* setup = new SetupWidget; - //setup->setFixedSize(700, 700); statsAndSetup->addWidget(setup); QWidget* statsAndSetupWidget = new QWidget(); @@ -117,7 +115,6 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) { // set up refresh timer timer = new QTimer(this); QObject::connect(timer, &QTimer::timeout, this, &OffroadHome::refresh); - refresh(); timer->start(10 * 1000); setLayout(main_layout); @@ -131,6 +128,10 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) { )"); } +void OffroadHome::showEvent(QShowEvent *event) { + refresh(); +} + void OffroadHome::openAlerts() { center_layout->setCurrentIndex(1); } diff --git a/selfdrive/ui/qt/home.h b/selfdrive/ui/qt/home.h index f2fbf3e9..3e89386b 100644 --- a/selfdrive/ui/qt/home.h +++ b/selfdrive/ui/qt/home.h @@ -18,6 +18,9 @@ class OffroadHome : public QFrame { public: explicit OffroadHome(QWidget* parent = 0); +protected: + void showEvent(QShowEvent *event) override; + private: QTimer* timer; diff --git a/selfdrive/ui/qt/offroad/onboarding.cc b/selfdrive/ui/qt/offroad/onboarding.cc index 23b0f31d..c6d6166f 100644 --- a/selfdrive/ui/qt/offroad/onboarding.cc +++ b/selfdrive/ui/qt/offroad/onboarding.cc @@ -1,9 +1,9 @@ #include #include #include -#include -#include #include +#include +#include #include "common/params.h" #include "onboarding.h" @@ -50,7 +50,12 @@ void TrainingGuide::paintEvent(QPaintEvent *event) { imageCorner = rect.topLeft(); } -TermsPage::TermsPage(QWidget *parent) : QFrame(parent){ +void TermsPage::showEvent(QShowEvent *event) { + // late init, building QML widget takes 200ms + if (layout()) { + return; + } + QVBoxLayout *main_layout = new QVBoxLayout; main_layout->setMargin(40); main_layout->setSpacing(40); @@ -61,15 +66,17 @@ TermsPage::TermsPage(QWidget *parent) : QFrame(parent){ text->setAttribute(Qt::WA_AlwaysStackOnTop); text->setClearColor(Qt::transparent); - text->rootContext()->setContextProperty("font_size", 55); - QString text_view = util::read_file("../assets/offroad/tc.html").c_str(); text->rootContext()->setContextProperty("text_view", text_view); + text->rootContext()->setContextProperty("font_size", 55); text->setSource(QUrl::fromLocalFile("qt/offroad/text_view.qml")); main_layout->addWidget(text); + QObject *obj = (QObject*)text->rootObject(); + QObject::connect(obj, SIGNAL(qmlSignal()), SLOT(enableAccept())); + // TODO: add decline page QHBoxLayout* buttons = new QHBoxLayout; main_layout->addLayout(buttons); @@ -82,15 +89,11 @@ TermsPage::TermsPage(QWidget *parent) : QFrame(parent){ buttons->addWidget(accept_btn); QObject::connect(accept_btn, &QPushButton::released, this, &TermsPage::acceptedTerms); - QObject *obj = (QObject*)text->rootObject(); - QObject::connect(obj, SIGNAL(qmlSignal()), SLOT(enableAccept())); setLayout(main_layout); setStyleSheet(R"( - * { - font-size: 50px; - } QPushButton { padding: 50px; + font-size: 50px; border-radius: 10px; background-color: #292929; } @@ -136,7 +139,6 @@ OnboardingWindow::OnboardingWindow(QWidget *parent) : QStackedWidget(parent) { }); addWidget(tr); - setStyleSheet(R"( * { color: white; diff --git a/selfdrive/ui/qt/offroad/onboarding.h b/selfdrive/ui/qt/offroad/onboarding.h index 227090fd..30bae2ea 100644 --- a/selfdrive/ui/qt/offroad/onboarding.h +++ b/selfdrive/ui/qt/offroad/onboarding.h @@ -57,7 +57,10 @@ class TermsPage : public QFrame { Q_OBJECT public: - explicit TermsPage(QWidget *parent = 0); + explicit TermsPage(QWidget *parent = 0) : QFrame(parent) {}; + +protected: + void showEvent(QShowEvent *event) override; private: QPushButton *accept_btn; diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index e1a8913d..f0b61919 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -263,7 +263,13 @@ QWidget * network_panel(QWidget * parent) { return w; } -SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { +void SettingsWindow::showEvent(QShowEvent *event) { + if (layout()) { + panel_widget->setCurrentIndex(0); + nav_btns->buttons()[0]->setChecked(true); + return; + } + // setup two main layouts QVBoxLayout *sidebar_layout = new QVBoxLayout(); sidebar_layout->setMargin(0); @@ -366,9 +372,3 @@ void SettingsWindow::hideEvent(QHideEvent *event){ } } } - -void SettingsWindow::showEvent(QShowEvent *event){ - panel_widget->setCurrentIndex(0); - nav_btns->buttons()[0]->setChecked(true); -} - diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index 34447829..1b5e78ba 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -41,7 +41,7 @@ class SettingsWindow : public QFrame { Q_OBJECT public: - explicit SettingsWindow(QWidget *parent = 0); + explicit SettingsWindow(QWidget *parent = 0) : QFrame(parent) {}; protected: void hideEvent(QHideEvent *event); diff --git a/selfdrive/ui/qt/widgets/drive_stats.cc b/selfdrive/ui/qt/widgets/drive_stats.cc index 2d7debb2..65064ea1 100644 --- a/selfdrive/ui/qt/widgets/drive_stats.cc +++ b/selfdrive/ui/qt/widgets/drive_stats.cc @@ -35,35 +35,35 @@ void DriveStats::parseResponse(const QString& response) { labels.hours->setText(QString::number((int)(obj["minutes"].toDouble() / 60))); }; - bool metric = Params().getBool("IsMetric"); QJsonObject json = doc.object(); update(json["all"].toObject(), all_, metric); update(json["week"].toObject(), week_, metric); } DriveStats::DriveStats(QWidget* parent) : QWidget(parent) { - setStyleSheet("QLabel {font-size: 48px; font-weight: 500;}"); + metric = Params().getBool("IsMetric"); + QString distance_unit = metric ? "KM" : "MILES"; - auto add_stats_layouts = [&](QGridLayout* gl, StatsLabels& labels, int row, const char* distance_unit) { + auto add_stats_layouts = [&](QGridLayout* gl, StatsLabels& labels, int row, const QString &distance_unit) { gl->addLayout(build_stat_layout(&labels.routes, "DRIVES"), row, 0, 3, 1); gl->addLayout(build_stat_layout(&labels.distance, distance_unit), row, 1, 3, 1); gl->addLayout(build_stat_layout(&labels.hours, "HOURS"), row, 2, 3, 1); }; - const char* distance_unit = Params().getBool("IsMetric") ? "KM" : "MILES"; - QGridLayout* gl = new QGridLayout(); + QGridLayout* gl = new QGridLayout(this); gl->setMargin(0); + gl->addWidget(new QLabel("ALL TIME"), 0, 0, 1, 3); add_stats_layouts(gl, all_, 1, distance_unit); + gl->addWidget(new QLabel("PAST WEEK"), 6, 0, 1, 3); add_stats_layouts(gl, week_, 7, distance_unit); - QVBoxLayout* vlayout = new QVBoxLayout(this); - vlayout->addLayout(gl); - - // TODO: do we really need to update this frequently? QString dongleId = QString::fromStdString(Params().get("DongleId")); QString url = "https://api.commadotai.com/v1.1/devices/" + dongleId + "/stats"; - RequestRepeater *repeater = new RequestRepeater(this, url, "ApiCache_DriveStats", 13); + RequestRepeater *repeater = new RequestRepeater(this, url, "ApiCache_DriveStats", 30); QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &DriveStats::parseResponse); + + setLayout(gl); + setStyleSheet(R"(QLabel {font-size: 48px; font-weight: 500;})"); } diff --git a/selfdrive/ui/qt/widgets/drive_stats.h b/selfdrive/ui/qt/widgets/drive_stats.h index d90e296b..deeb80f6 100644 --- a/selfdrive/ui/qt/widgets/drive_stats.h +++ b/selfdrive/ui/qt/widgets/drive_stats.h @@ -9,6 +9,7 @@ public: explicit DriveStats(QWidget* parent = 0); private: + bool metric; struct StatsLabels { QLabel *routes, *distance, *hours; } all_, week_; diff --git a/selfdrive/ui/qt/widgets/offroad_alerts.cc b/selfdrive/ui/qt/widgets/offroad_alerts.cc index e395d1cf..a67918e1 100644 --- a/selfdrive/ui/qt/widgets/offroad_alerts.cc +++ b/selfdrive/ui/qt/widgets/offroad_alerts.cc @@ -8,34 +8,18 @@ #include "selfdrive/common/util.h" OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) { - QVBoxLayout *layout = new QVBoxLayout(); + QVBoxLayout *layout = new QVBoxLayout; layout->setMargin(50); layout->setSpacing(30); - QWidget *alerts_widget = new QWidget; - QVBoxLayout *alerts_layout = new QVBoxLayout; + QWidget *alerts_widget = new QWidget(this); + alerts_layout = new QVBoxLayout; alerts_layout->setMargin(0); alerts_layout->setSpacing(30); + alerts_layout->addStretch(1); alerts_widget->setLayout(alerts_layout); alerts_widget->setStyleSheet("background-color: transparent;"); - // setup labels for each alert - QString json = QString::fromStdString(util::read_file("../controls/lib/alerts_offroad.json")); - QJsonObject obj = QJsonDocument::fromJson(json.toUtf8()).object(); - for (auto &k : obj.keys()) { - QLabel *l = new QLabel(this); - alerts[k.toStdString()] = l; - int severity = obj[k].toObject()["severity"].toInt(); - - l->setMargin(60); - l->setWordWrap(true); - l->setStyleSheet("background-color: " + QString(severity ? "#E22C2C" : "#292929")); - l->setVisible(false); - alerts_layout->addWidget(l); - } - - alerts_layout->addStretch(1); - // release notes releaseNotes.setWordWrap(true); releaseNotes.setVisible(false); @@ -80,10 +64,26 @@ OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) { background-color: white; } )"); - } void OffroadAlert::refresh() { + if (alerts.empty()) { + // setup labels for each alert + QString json = QString::fromStdString(util::read_file("../controls/lib/alerts_offroad.json")); + QJsonObject obj = QJsonDocument::fromJson(json.toUtf8()).object(); + for (auto &k : obj.keys()) { + QLabel *l = new QLabel(this); + alerts[k.toStdString()] = l; + int severity = obj[k].toObject()["severity"].toInt(); + + l->setMargin(60); + l->setWordWrap(true); + l->setStyleSheet("background-color: " + QString(severity ? "#E22C2C" : "#292929")); + l->setVisible(false); + alerts_layout->addWidget(l); + } + } + updateAlerts(); rebootBtn.setVisible(updateAvailable); diff --git a/selfdrive/ui/qt/widgets/offroad_alerts.h b/selfdrive/ui/qt/widgets/offroad_alerts.h index ae6c03b3..871f7197 100644 --- a/selfdrive/ui/qt/widgets/offroad_alerts.h +++ b/selfdrive/ui/qt/widgets/offroad_alerts.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "common/params.h" #include "widgets/scrollview.h" @@ -17,14 +18,16 @@ public: bool updateAvailable; private: - Params params; - QLabel releaseNotes; - std::map alerts; - QPushButton rebootBtn; void updateAlerts(); - ScrollView *releaseNotesScroll; + Params params; + std::map alerts; + + QLabel releaseNotes; + QPushButton rebootBtn; ScrollView *alertsScroll; + ScrollView *releaseNotesScroll; + QVBoxLayout *alerts_layout; signals: void closeAlerts(); diff --git a/selfdrive/ui/qt/widgets/setup.cc b/selfdrive/ui/qt/widgets/setup.cc index 342c2ff4..c15301f5 100644 --- a/selfdrive/ui/qt/widgets/setup.cc +++ b/selfdrive/ui/qt/widgets/setup.cc @@ -24,12 +24,16 @@ PairingQRWidget::PairingQRWidget(QWidget* parent) : QWidget(parent) { QTimer* timer = new QTimer(this); timer->start(30 * 1000); connect(timer, &QTimer::timeout, this, &PairingQRWidget::refresh); - refresh(); // don't wait for the first refresh +} + +void PairingQRWidget::showEvent(QShowEvent *event){ + refresh(); } void PairingQRWidget::refresh(){ - QString IMEI = QString::fromStdString(Params().get("IMEI")); - QString serial = QString::fromStdString(Params().get("HardwareSerial")); + Params params; + QString IMEI = QString::fromStdString(params.get("IMEI")); + QString serial = QString::fromStdString(params.get("HardwareSerial")); if (std::min(IMEI.length(), serial.length()) <= 5) { qrCode->setText("Error getting serial: contact support"); diff --git a/selfdrive/ui/qt/widgets/setup.h b/selfdrive/ui/qt/widgets/setup.h index 5259d92e..83a41530 100644 --- a/selfdrive/ui/qt/widgets/setup.h +++ b/selfdrive/ui/qt/widgets/setup.h @@ -16,6 +16,7 @@ public: private: QLabel* qrCode; void updateQrCode(QString text); + void showEvent(QShowEvent *event); private slots: void refresh(); diff --git a/selfdrive/ui/qt/widgets/ssh_keys.cc b/selfdrive/ui/qt/widgets/ssh_keys.cc index 42f77c47..f118fafd 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.cc +++ b/selfdrive/ui/qt/widgets/ssh_keys.cc @@ -34,8 +34,8 @@ SshControl::SshControl() : AbstractControl("SSH Keys", "Warning: This grants SSH getUserKeys(username); } } else { - Params().remove("GithubUsername"); - Params().remove("GithubSshKeys"); + params.remove("GithubUsername"); + params.remove("GithubSshKeys"); refresh(); } }); @@ -51,9 +51,9 @@ SshControl::SshControl() : AbstractControl("SSH Keys", "Warning: This grants SSH } void SshControl::refresh() { - QString param = QString::fromStdString(Params().get("GithubSshKeys")); + QString param = QString::fromStdString(params.get("GithubSshKeys")); if (param.length()) { - username_label.setText(QString::fromStdString(Params().get("GithubUsername"))); + username_label.setText(QString::fromStdString(params.get("GithubUsername"))); btn.setText("REMOVE"); } else { username_label.setText(""); @@ -82,8 +82,8 @@ void SshControl::parseResponse(){ networkTimer->stop(); QString response = reply->readAll(); if (reply->error() == QNetworkReply::NoError && response.length()) { - Params().put("GithubUsername", username.toStdString()); - Params().put("GithubSshKeys", response.toStdString()); + params.put("GithubUsername", username.toStdString()); + params.put("GithubSshKeys", response.toStdString()); } else if(reply->error() == QNetworkReply::NoError){ err = "Username '" + username + "' has no keys on GitHub"; } else { diff --git a/selfdrive/ui/qt/widgets/ssh_keys.h b/selfdrive/ui/qt/widgets/ssh_keys.h index 04eba835..bae98af1 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.h +++ b/selfdrive/ui/qt/widgets/ssh_keys.h @@ -27,6 +27,8 @@ public: SshControl(); private: + Params params; + QPushButton btn; QString username; QLabel username_label;