OffroadAlert: update alerts inplace (#20463)

* refactor

* cleanup

* use QWdiget instead of QStackWidget

* continue

* remove duplicate setMargin

* dont parse alerts if updateAvailable

* kind of works

* alerts work

* cleanup

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
pull/20507/head
Dean Lee 4 years ago committed by GitHub
parent 0fb00e10b1
commit bf1001e54b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      selfdrive/ui/qt/home.cc
  2. 110
      selfdrive/ui/qt/widgets/offroad_alerts.cc
  3. 20
      selfdrive/ui/qt/widgets/offroad_alerts.hpp

@ -153,7 +153,7 @@ void OffroadHome::refresh() {
// update alerts // update alerts
alerts_widget->refresh(); alerts_widget->refresh();
if (!alerts_widget->alerts.size() && !alerts_widget->updateAvailable) { if (!alerts_widget->alertCount && !alerts_widget->updateAvailable) {
emit closeAlerts(); emit closeAlerts();
alert_notification->setVisible(false); alert_notification->setVisible(false);
return; return;
@ -162,7 +162,7 @@ void OffroadHome::refresh() {
if (alerts_widget->updateAvailable) { if (alerts_widget->updateAvailable) {
alert_notification->setText("UPDATE"); alert_notification->setText("UPDATE");
} else { } else {
int alerts = alerts_widget->alerts.size(); int alerts = alerts_widget->alertCount;
alert_notification->setText(QString::number(alerts) + " ALERT" + (alerts == 1 ? "" : "S")); alert_notification->setText(QString::number(alerts) + " ALERT" + (alerts == 1 ? "" : "S"));
} }

@ -1,47 +1,52 @@
#include <QFile>
#include <QLabel>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
#include <QDebug>
#include "offroad_alerts.hpp" #include "offroad_alerts.hpp"
#include "common/params.h"
#include "selfdrive/hardware/hw.h" #include "selfdrive/hardware/hw.h"
#include "selfdrive/common/util.h"
void cleanStackedWidget(QStackedWidget* swidget) {
while(swidget->count() > 0) {
QWidget *w = swidget->widget(0);
swidget->removeWidget(w);
w->deleteLater();
}
}
OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) { OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(); QVBoxLayout *layout = new QVBoxLayout();
main_layout->setMargin(25); 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(); // release notes
main_layout->addWidget(alerts_stack, 1); releaseNotes.setVisible(false);
releaseNotes.setStyleSheet("font-size: 48px;");
layout->addWidget(&releaseNotes);
// bottom footer // bottom footer, dismiss + reboot buttons
QHBoxLayout *footer_layout = new QHBoxLayout(); QHBoxLayout *footer_layout = new QHBoxLayout();
main_layout->addLayout(footer_layout); layout->addLayout(footer_layout);
QPushButton *dismiss_btn = new QPushButton("Dismiss"); QPushButton *dismiss_btn = new QPushButton("Dismiss");
dismiss_btn->setFixedSize(400, 125); dismiss_btn->setFixedSize(400, 125);
footer_layout->addWidget(dismiss_btn, 0, Qt::AlignLeft); footer_layout->addWidget(dismiss_btn, 0, Qt::AlignBottom | 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);
QObject::connect(dismiss_btn, SIGNAL(released()), this, SIGNAL(closeAlerts())); 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"( setStyleSheet(R"(
* { * {
font-size: 48px; font-size: 48px;
@ -58,54 +63,33 @@ OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) {
background-color: white; 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() { void OffroadAlert::refresh() {
parse_alerts(); updateAlerts();
cleanStackedWidget(alerts_stack);
updateAvailable = Params().read_db_bool("UpdateAvailable");
reboot_btn->setVisible(updateAvailable);
QVBoxLayout *layout = new QVBoxLayout; rebootBtn.setVisible(updateAvailable);
layout->setSpacing(20); releaseNotes.setVisible(updateAvailable);
releaseNotes.setText(QString::fromStdString(params.get("ReleaseNotes")));
if (updateAvailable) { for (const auto& [k, label] : alerts) {
QLabel *body = new QLabel(QString::fromStdString(Params().get("ReleaseNotes"))); label->setVisible(!updateAvailable && !label->text().isEmpty());
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);
}
} }
QWidget *w = new QWidget();
w->setLayout(layout);
alerts_stack->addWidget(w);
} }
void OffroadAlert::parse_alerts() { void OffroadAlert::updateAlerts() {
alerts.clear(); alertCount = 0;
for (const QString &key : alert_keys) { updateAvailable = params.read_db_bool("UpdateAvailable");
std::vector<char> bytes = Params().read_db_bytes(key.toStdString().c_str()); for (const auto& [key, label] : alerts) {
auto bytes = params.read_db_bytes(key.c_str());
if (bytes.size()) { if (bytes.size()) {
QJsonDocument doc_par = QJsonDocument::fromJson(QByteArray(bytes.data(), bytes.size())); QJsonDocument doc_par = QJsonDocument::fromJson(QByteArray(bytes.data(), bytes.size()));
QJsonObject obj = doc_par.object(); QJsonObject obj = doc_par.object();
Alert alert = {obj.value("text").toString(), obj.value("severity").toInt()}; label->setText(obj.value("text").toString());
alerts.push_back(alert); alertCount++;
} else {
label->setText("");
} }
} }
} }

@ -1,28 +1,26 @@
#pragma once #pragma once
#include <map>
#include <QFrame> #include <QFrame>
#include <QStackedWidget>
#include <QPushButton> #include <QPushButton>
#include <QStringList> #include <QLabel>
struct Alert { #include "common/params.h"
QString text;
int severity;
};
class OffroadAlert : public QFrame { class OffroadAlert : public QFrame {
Q_OBJECT Q_OBJECT
public: public:
explicit OffroadAlert(QWidget *parent = 0); explicit OffroadAlert(QWidget *parent = 0);
QVector<Alert> alerts; int alertCount = 0;
QStringList alert_keys;
bool updateAvailable; bool updateAvailable;
private: private:
QStackedWidget *alerts_stack; Params params;
QPushButton *reboot_btn; QLabel releaseNotes;
void parse_alerts(); std::map<std::string, QLabel*> alerts;
QPushButton rebootBtn;
void updateAlerts();
signals: signals:
void closeAlerts(); void closeAlerts();

Loading…
Cancel
Save