diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index fead4ae1b1..f10222efcd 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -153,7 +153,7 @@ void OffroadHome::refresh() { // update alerts alerts_widget->refresh(); - if (!alerts_widget->alerts.size() && !alerts_widget->updateAvailable) { + if (!alerts_widget->alertCount && !alerts_widget->updateAvailable) { emit closeAlerts(); alert_notification->setVisible(false); return; @@ -162,7 +162,7 @@ void OffroadHome::refresh() { if (alerts_widget->updateAvailable) { alert_notification->setText("UPDATE"); } else { - int alerts = alerts_widget->alerts.size(); + int alerts = alerts_widget->alertCount; alert_notification->setText(QString::number(alerts) + " ALERT" + (alerts == 1 ? "" : "S")); } diff --git a/selfdrive/ui/qt/widgets/offroad_alerts.cc b/selfdrive/ui/qt/widgets/offroad_alerts.cc index cd1173722a..bb5f007027 100644 --- a/selfdrive/ui/qt/widgets/offroad_alerts.cc +++ b/selfdrive/ui/qt/widgets/offroad_alerts.cc @@ -1,47 +1,52 @@ -#include -#include #include #include #include #include -#include #include "offroad_alerts.hpp" -#include "common/params.h" #include "selfdrive/hardware/hw.h" - -void cleanStackedWidget(QStackedWidget* swidget) { - while(swidget->count() > 0) { - QWidget *w = swidget->widget(0); - swidget->removeWidget(w); - w->deleteLater(); - } -} +#include "selfdrive/common/util.h" OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) { - QVBoxLayout *main_layout = new QVBoxLayout(); - main_layout->setMargin(25); + QVBoxLayout *layout = new QVBoxLayout(); + layout->setMargin(50); + + // 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); + layout->addWidget(l); + } - alerts_stack = new QStackedWidget(); - main_layout->addWidget(alerts_stack, 1); + // release notes + releaseNotes.setVisible(false); + releaseNotes.setStyleSheet("font-size: 48px;"); + layout->addWidget(&releaseNotes); - // bottom footer + // bottom footer, dismiss + reboot buttons QHBoxLayout *footer_layout = new QHBoxLayout(); - main_layout->addLayout(footer_layout); + layout->addLayout(footer_layout); QPushButton *dismiss_btn = new QPushButton("Dismiss"); dismiss_btn->setFixedSize(400, 125); - footer_layout->addWidget(dismiss_btn, 0, Qt::AlignLeft); - - reboot_btn = new QPushButton("Reboot and Update"); - reboot_btn->setFixedSize(600, 125); - reboot_btn->setVisible(false); - footer_layout->addWidget(reboot_btn, 0, Qt::AlignRight); - + footer_layout->addWidget(dismiss_btn, 0, Qt::AlignBottom | Qt::AlignLeft); QObject::connect(dismiss_btn, SIGNAL(released()), this, SIGNAL(closeAlerts())); - QObject::connect(reboot_btn, &QPushButton::released, [=]() { Hardware::reboot(); }); - setLayout(main_layout); + rebootBtn.setText("Reboot and Update"); + rebootBtn.setFixedSize(600, 125); + rebootBtn.setVisible(false); + footer_layout->addWidget(&rebootBtn, 0, Qt::AlignBottom | Qt::AlignRight); + QObject::connect(&rebootBtn, &QPushButton::released, [=]() { Hardware::reboot(); }); + + setLayout(layout); setStyleSheet(R"( * { font-size: 48px; @@ -58,54 +63,33 @@ OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) { background-color: white; } )"); - main_layout->setMargin(50); - QFile inFile("../controls/lib/alerts_offroad.json"); - bool ret = inFile.open(QIODevice::ReadOnly | QIODevice::Text); - assert(ret); - QJsonDocument doc = QJsonDocument::fromJson(inFile.readAll()); - assert(!doc.isNull()); - alert_keys = doc.object().keys(); } void OffroadAlert::refresh() { - parse_alerts(); - cleanStackedWidget(alerts_stack); - - updateAvailable = Params().read_db_bool("UpdateAvailable"); - reboot_btn->setVisible(updateAvailable); + updateAlerts(); - QVBoxLayout *layout = new QVBoxLayout; - layout->setSpacing(20); + rebootBtn.setVisible(updateAvailable); + releaseNotes.setVisible(updateAvailable); + releaseNotes.setText(QString::fromStdString(params.get("ReleaseNotes"))); - if (updateAvailable) { - QLabel *body = new QLabel(QString::fromStdString(Params().get("ReleaseNotes"))); - body->setStyleSheet(R"(font-size: 48px;)"); - layout->addWidget(body, 0, Qt::AlignLeft | Qt::AlignTop); - } else { - for (const auto &alert : alerts) { - QLabel *l = new QLabel(alert.text); - l->setMargin(60); - l->setWordWrap(true); - l->setStyleSheet("background-color: " + QString(alert.severity ? "#E22C2C" : "#292929")); - layout->addWidget(l, 0, Qt::AlignTop); - } + for (const auto& [k, label] : alerts) { + label->setVisible(!updateAvailable && !label->text().isEmpty()); } - - QWidget *w = new QWidget(); - w->setLayout(layout); - alerts_stack->addWidget(w); } -void OffroadAlert::parse_alerts() { - alerts.clear(); - for (const QString &key : alert_keys) { - std::vector bytes = Params().read_db_bytes(key.toStdString().c_str()); +void OffroadAlert::updateAlerts() { + alertCount = 0; + updateAvailable = params.read_db_bool("UpdateAvailable"); + for (const auto& [key, label] : alerts) { + auto bytes = params.read_db_bytes(key.c_str()); if (bytes.size()) { QJsonDocument doc_par = QJsonDocument::fromJson(QByteArray(bytes.data(), bytes.size())); QJsonObject obj = doc_par.object(); - Alert alert = {obj.value("text").toString(), obj.value("severity").toInt()}; - alerts.push_back(alert); + label->setText(obj.value("text").toString()); + alertCount++; + } else { + label->setText(""); } } } diff --git a/selfdrive/ui/qt/widgets/offroad_alerts.hpp b/selfdrive/ui/qt/widgets/offroad_alerts.hpp index ec48f89c7e..b05d68d334 100644 --- a/selfdrive/ui/qt/widgets/offroad_alerts.hpp +++ b/selfdrive/ui/qt/widgets/offroad_alerts.hpp @@ -1,28 +1,26 @@ #pragma once +#include #include -#include #include -#include +#include -struct Alert { - QString text; - int severity; -}; +#include "common/params.h" class OffroadAlert : public QFrame { Q_OBJECT public: explicit OffroadAlert(QWidget *parent = 0); - QVector alerts; - QStringList alert_keys; + int alertCount = 0; bool updateAvailable; private: - QStackedWidget *alerts_stack; - QPushButton *reboot_btn; - void parse_alerts(); + Params params; + QLabel releaseNotes; + std::map alerts; + QPushButton rebootBtn; + void updateAlerts(); signals: void closeAlerts();