Offroad alerts (#2664)
We now have a working offroad alerts
old-commit-hash: 744a3317e3
commatwo_master
parent
bc4fd60f20
commit
e4b5b9a297
6 changed files with 269 additions and 9 deletions
@ -0,0 +1,160 @@ |
|||||||
|
#include <QWidget> |
||||||
|
#include <QLabel> |
||||||
|
#include <QFile> |
||||||
|
#include <QJsonDocument> |
||||||
|
#include <QJsonObject> |
||||||
|
#include <QDebug> |
||||||
|
|
||||||
|
#include "offroad_alerts.hpp" |
||||||
|
|
||||||
|
#include "common/params.h" |
||||||
|
|
||||||
|
|
||||||
|
void cleanLayout(QLayout* layout) { |
||||||
|
while (QLayoutItem* item = layout->takeAt(0)) { |
||||||
|
if (QWidget* widget = item->widget()){ |
||||||
|
widget->deleteLater(); |
||||||
|
} |
||||||
|
if (QLayout* childLayout = item->layout()) { |
||||||
|
cleanLayout(childLayout); |
||||||
|
} |
||||||
|
delete item; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QString vectorToQString(std::vector<char> v){ |
||||||
|
return QString::fromStdString(std::string(v.begin(), v.end())); |
||||||
|
} |
||||||
|
|
||||||
|
OffroadAlert::OffroadAlert(QWidget* parent){ |
||||||
|
vlayout = new QVBoxLayout; |
||||||
|
refresh(); |
||||||
|
setLayout(vlayout); |
||||||
|
} |
||||||
|
|
||||||
|
void OffroadAlert::refresh(){ |
||||||
|
cleanLayout(vlayout); |
||||||
|
parse_alerts(); |
||||||
|
|
||||||
|
bool updateAvailable = false; |
||||||
|
std::vector<char> bytes = Params().read_db_bytes("UpdateAvailable"); |
||||||
|
if (bytes.size() && bytes[0] == '1'){ |
||||||
|
updateAvailable = true; |
||||||
|
} |
||||||
|
show_alert = updateAvailable || alerts.size() ; |
||||||
|
|
||||||
|
if (updateAvailable){ |
||||||
|
//If there is update available, don't show alerts
|
||||||
|
alerts.clear(); |
||||||
|
|
||||||
|
QFrame *f = new QFrame(); |
||||||
|
|
||||||
|
QVBoxLayout *update_layout = new QVBoxLayout; |
||||||
|
update_layout->addWidget(new QLabel("Update available")); |
||||||
|
|
||||||
|
std::vector<char> release_notes_bytes = Params().read_db_bytes("ReleaseNotes"); |
||||||
|
QString releaseNotes = vectorToQString(release_notes_bytes); |
||||||
|
QLabel *notes_label = new QLabel(releaseNotes); |
||||||
|
notes_label->setWordWrap(true); |
||||||
|
update_layout->addSpacing(20); |
||||||
|
update_layout->addWidget(notes_label); |
||||||
|
update_layout->addSpacing(20); |
||||||
|
|
||||||
|
QPushButton *update_button = new QPushButton("Reboot and Update"); |
||||||
|
update_layout->addWidget(update_button); |
||||||
|
update_layout->setMargin(10); |
||||||
|
#ifdef __aarch64__ |
||||||
|
QObject::connect(update_button, &QPushButton::released,[=]() {std::system("sudo reboot");}); |
||||||
|
#endif |
||||||
|
|
||||||
|
f->setLayout(update_layout); |
||||||
|
f->setStyleSheet(R"( |
||||||
|
.QFrame{ |
||||||
|
border-radius: 30px; |
||||||
|
border: 2px solid white; |
||||||
|
background-color: #114267; |
||||||
|
} |
||||||
|
QLabel{ |
||||||
|
font-size: 60px; |
||||||
|
background-color: #114267; |
||||||
|
} |
||||||
|
)"); |
||||||
|
|
||||||
|
vlayout->addWidget(f); |
||||||
|
vlayout->addSpacing(60); |
||||||
|
}else{ |
||||||
|
vlayout->addSpacing(60); |
||||||
|
|
||||||
|
for (auto alert : alerts){ |
||||||
|
QLabel *l = new QLabel(alert.text); |
||||||
|
l->setWordWrap(true); |
||||||
|
l->setMargin(60); |
||||||
|
|
||||||
|
if (alert.severity){ |
||||||
|
l->setStyleSheet(R"( |
||||||
|
QLabel { |
||||||
|
font-size: 40px; |
||||||
|
font-weight: bold; |
||||||
|
border-radius: 30px; |
||||||
|
background-color: #971b1c; |
||||||
|
border-style: solid; |
||||||
|
border-width: 2px; |
||||||
|
border-color: white; |
||||||
|
} |
||||||
|
)");//red rounded rectange with white surround |
||||||
|
}else{ |
||||||
|
l->setStyleSheet(R"( |
||||||
|
QLabel { |
||||||
|
font-size: 40px; |
||||||
|
font-weight: bold; |
||||||
|
border-radius: 30px; |
||||||
|
background-color: #114267; |
||||||
|
border-style: solid; |
||||||
|
border-width: 2px; |
||||||
|
border-color: white; |
||||||
|
} |
||||||
|
)");//blue rounded rectange with white surround |
||||||
|
} |
||||||
|
|
||||||
|
vlayout->addWidget(l); |
||||||
|
vlayout->addSpacing(20); |
||||||
|
} |
||||||
|
|
||||||
|
//Pad the vlayout
|
||||||
|
for (int i = alerts.size(); i < 4; i++){ |
||||||
|
QWidget *w = new QWidget(); |
||||||
|
vlayout->addWidget(w); |
||||||
|
vlayout->addSpacing(50); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QPushButton *hide_alerts_button = new QPushButton(updateAvailable ? "Later" : "Hide alerts"); |
||||||
|
vlayout->addWidget(hide_alerts_button); |
||||||
|
QObject::connect(hide_alerts_button, SIGNAL(released()), this, SIGNAL(closeAlerts())); |
||||||
|
} |
||||||
|
|
||||||
|
void OffroadAlert::parse_alerts(){ |
||||||
|
alerts.clear(); |
||||||
|
//We launch in selfdrive/ui
|
||||||
|
QFile inFile("../controls/lib/alerts_offroad.json"); |
||||||
|
inFile.open(QIODevice::ReadOnly | QIODevice::Text); |
||||||
|
QByteArray data = inFile.readAll(); |
||||||
|
inFile.close(); |
||||||
|
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(data); |
||||||
|
if (doc.isNull()) { |
||||||
|
qDebug() << "Parse failed"; |
||||||
|
} |
||||||
|
|
||||||
|
QJsonObject json = doc.object(); |
||||||
|
for (const QString& key : json.keys()) { |
||||||
|
std::vector<char> bytes = Params().read_db_bytes(key.toStdString().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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
|
||||||
|
#include <QWidget> |
||||||
|
#include <QFrame> |
||||||
|
#include <QTimer> |
||||||
|
#include <QCheckBox> |
||||||
|
#include <QStackedLayout> |
||||||
|
#include <QPushButton> |
||||||
|
|
||||||
|
struct Alert{ |
||||||
|
QString text; |
||||||
|
int severity; |
||||||
|
}; |
||||||
|
|
||||||
|
class OffroadAlert : public QWidget{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
public: |
||||||
|
explicit OffroadAlert(QWidget *parent = 0); |
||||||
|
bool show_alert; |
||||||
|
QVector<Alert> alerts; |
||||||
|
|
||||||
|
private: |
||||||
|
QVBoxLayout *vlayout; |
||||||
|
|
||||||
|
void parse_alerts(); |
||||||
|
|
||||||
|
signals: |
||||||
|
void closeAlerts(); |
||||||
|
|
||||||
|
public slots: |
||||||
|
void refresh(); |
||||||
|
}; |
Loading…
Reference in new issue