move offroad alerts to home screen (#2681)
* move offroad alerts to home screen * offroad aletrs work, but sidebar doesn't look nice * fix sidebar * looks better * cleanup * little bigger Co-authored-by: grekiki <gregor1234567890@gmail.com>albatross
parent
fcb3ed727b
commit
8320a153fb
|
@ -3,10 +3,12 @@
|
|||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QStackedLayout>
|
||||
#include <QLayout>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "common/params.h"
|
||||
|
@ -19,14 +21,16 @@
|
|||
#define BACKLIGHT_TS 2.00
|
||||
|
||||
|
||||
QWidget * home_widget() {
|
||||
OffroadHome::OffroadHome(QWidget *parent) : QWidget(parent) {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout();
|
||||
main_layout->setContentsMargins(sbr_w + 50, 50, 50, 50);
|
||||
|
||||
center_layout = new QStackedLayout();
|
||||
|
||||
// header
|
||||
QHBoxLayout *header_layout = new QHBoxLayout();
|
||||
QString date_str = QDateTime::currentDateTime().toString("dddd, MMMM d");
|
||||
QLabel *date = new QLabel(date_str);
|
||||
|
||||
date = new QLabel();
|
||||
date->setStyleSheet(R"(font-size: 55px;)");
|
||||
header_layout->addWidget(date, 0, Qt::AlignTop | Qt::AlignLeft);
|
||||
|
||||
|
@ -36,33 +40,91 @@ QWidget * home_widget() {
|
|||
|
||||
main_layout->addLayout(header_layout);
|
||||
|
||||
alert_notification = new QPushButton();
|
||||
QObject::connect(alert_notification, SIGNAL(released()), this, SLOT(openAlerts()));
|
||||
main_layout->addWidget(alert_notification, 0, Qt::AlignTop | Qt::AlignRight);
|
||||
|
||||
// center
|
||||
QLabel *drive = new QLabel("Drive me");
|
||||
drive->setStyleSheet(R"(font-size: 175px;)");
|
||||
main_layout->addWidget(drive, 1, Qt::AlignHCenter);
|
||||
center_layout->addWidget(drive);
|
||||
|
||||
QWidget *w = new QWidget();
|
||||
w->setLayout(main_layout);
|
||||
w->setStyleSheet(R"(
|
||||
* {
|
||||
background-color: none;
|
||||
}
|
||||
)");
|
||||
return w;
|
||||
alerts_widget = new OffroadAlert();
|
||||
QObject::connect(alerts_widget, SIGNAL(closeAlerts()), this, SLOT(closeAlerts()));
|
||||
center_layout->addWidget(alerts_widget);
|
||||
center_layout->setAlignment(alerts_widget, Qt::AlignCenter);
|
||||
|
||||
main_layout->addLayout(center_layout, 1);
|
||||
|
||||
// set up refresh timer
|
||||
timer = new QTimer(this);
|
||||
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh()));
|
||||
refresh();
|
||||
timer->start(10 * 1000);
|
||||
|
||||
setLayout(main_layout);
|
||||
setStyleSheet(R"(background-color: none;)");
|
||||
}
|
||||
|
||||
HomeWindow::HomeWindow(QWidget *parent) : QWidget(parent) {
|
||||
void OffroadHome::openAlerts() {
|
||||
center_layout->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
void OffroadHome::closeAlerts() {
|
||||
center_layout->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void OffroadHome::refresh() {
|
||||
bool first_refresh = !date->text().size();
|
||||
if (!isVisible() && !first_refresh) {
|
||||
return;
|
||||
}
|
||||
|
||||
date->setText(QDateTime::currentDateTime().toString("dddd, MMMM d"));
|
||||
|
||||
// update alerts
|
||||
|
||||
alerts_widget->refresh();
|
||||
if (!alerts_widget->alerts.size() && !alerts_widget->updateAvailable){
|
||||
alert_notification->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (alerts_widget->updateAvailable){
|
||||
// There is a new release
|
||||
alert_notification->setText("UPDATE");
|
||||
} else {
|
||||
int alerts = alerts_widget->alerts.size();
|
||||
alert_notification->setText(QString::number(alerts) + " ALERT" + (alerts == 1 ? "" : "S"));
|
||||
}
|
||||
|
||||
alert_notification->setVisible(true);
|
||||
alert_notification->setStyleSheet(QString(R"(
|
||||
padding: 15px;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
border: 1px solid;
|
||||
border-radius: 5px;
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
background-color: red;
|
||||
)"));
|
||||
}
|
||||
|
||||
|
||||
HomeWindow::HomeWindow(QWidget *parent) : QWidget(parent) {
|
||||
layout = new QGridLayout;
|
||||
layout->setMargin(0);
|
||||
|
||||
// onroad UI
|
||||
glWindow = new GLWindow(this);
|
||||
layout->addWidget(glWindow, 0, 0);
|
||||
|
||||
home = home_widget();
|
||||
// draw offroad UI on top of onroad UI
|
||||
home = new OffroadHome();
|
||||
layout->addWidget(home, 0, 0);
|
||||
QObject::connect(glWindow, SIGNAL(offroadTransition(bool)), this, SLOT(setVisibility(bool)));
|
||||
|
||||
QObject::connect(this, SIGNAL(openSettings()), home, SLOT(refresh()));
|
||||
setLayout(layout);
|
||||
setStyleSheet(R"(
|
||||
* {
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
#include <QGridLayout>
|
||||
#include <QStackedWidget>
|
||||
#include <QStackedLayout>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "qt_sound.hpp"
|
||||
#include "widgets/offroad_alerts.hpp"
|
||||
#include "ui/ui.hpp"
|
||||
|
||||
|
||||
|
@ -49,6 +53,28 @@ public slots:
|
|||
void backlightUpdate();
|
||||
};
|
||||
|
||||
// offroad home screen
|
||||
class OffroadHome : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OffroadHome(QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
QTimer *timer;
|
||||
|
||||
// offroad home screen widgets
|
||||
QLabel *date;
|
||||
QStackedLayout *center_layout;
|
||||
OffroadAlert *alerts_widget;
|
||||
QPushButton *alert_notification;
|
||||
|
||||
public slots:
|
||||
void closeAlerts();
|
||||
void openAlerts();
|
||||
void refresh();
|
||||
};
|
||||
|
||||
|
||||
class HomeWindow : public QWidget {
|
||||
Q_OBJECT
|
||||
|
@ -64,8 +90,8 @@ protected:
|
|||
void mousePressEvent(QMouseEvent *e) override;
|
||||
|
||||
private:
|
||||
QWidget *home;
|
||||
QGridLayout *layout;
|
||||
OffroadHome *home;
|
||||
|
||||
private slots:
|
||||
void setVisibility(bool offroad);
|
||||
|
|
|
@ -227,15 +227,6 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QWidget(parent) {
|
|||
sidebar_layout->addWidget(close_button);
|
||||
QObject::connect(close_button, SIGNAL(released()), this, SIGNAL(closeSettings()));
|
||||
|
||||
// offroad alerts
|
||||
alerts_widget = new OffroadAlert();
|
||||
QObject::connect(alerts_widget, SIGNAL(closeAlerts()), this, SLOT(closeAlerts()));
|
||||
panel_layout->addWidget(alerts_widget);
|
||||
|
||||
sidebar_alert_widget = new QPushButton("");//Should get text when it is visible
|
||||
QObject::connect(sidebar_alert_widget, SIGNAL(released()), this, SLOT(openAlerts()));
|
||||
sidebar_layout->addWidget(sidebar_alert_widget);
|
||||
|
||||
// setup panels
|
||||
panels = {
|
||||
{"developer", developer_panel()},
|
||||
|
@ -263,11 +254,6 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QWidget(parent) {
|
|||
QObject::connect(btn, SIGNAL(released()), this, SLOT(setActivePanel()));
|
||||
}
|
||||
|
||||
// We either show the alerts, or the developer panel
|
||||
if (alerts_widget->show_alert){
|
||||
panel_layout->setCurrentWidget(alerts_widget);
|
||||
}
|
||||
|
||||
QHBoxLayout *settings_layout = new QHBoxLayout();
|
||||
settings_layout->addSpacing(45);
|
||||
|
||||
|
@ -288,55 +274,6 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QWidget(parent) {
|
|||
)");
|
||||
}
|
||||
|
||||
// Refreshes the offroad alerts from the params folder and sets up the sidebar alerts widget.
|
||||
// The function gets called every time a user opens the settings page
|
||||
void SettingsWindow::refreshParams() {
|
||||
alerts_widget->refresh();
|
||||
if (!alerts_widget->show_alert){
|
||||
sidebar_alert_widget->setFixedHeight(0);
|
||||
panel_layout->setCurrentIndex(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Panel 0 contains the alerts or release notes.
|
||||
panel_layout->setCurrentIndex(0);
|
||||
sidebar_alert_widget->setFixedHeight(100);
|
||||
sidebar_alert_widget->setStyleSheet(R"(
|
||||
background-color: #114267;
|
||||
)"); // light blue
|
||||
|
||||
// Check for alerts
|
||||
int alerts = alerts_widget->alerts.size();
|
||||
if (!alerts){
|
||||
// There is a new release
|
||||
sidebar_alert_widget->setText("UPDATE");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there is an important alert
|
||||
bool existsImportantAlert = false;
|
||||
for (auto alert : alerts_widget->alerts){
|
||||
if (alert.severity){
|
||||
existsImportantAlert = true;
|
||||
}
|
||||
}
|
||||
|
||||
sidebar_alert_widget->setText(QString::number(alerts) + " ALERT" + (alerts == 1 ? "" : "S"));
|
||||
if (existsImportantAlert){
|
||||
sidebar_alert_widget->setStyleSheet(R"(
|
||||
background-color: #661111;
|
||||
)"); //dark red
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsWindow::closeAlerts() {
|
||||
panel_layout->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
void SettingsWindow::openAlerts() {
|
||||
panel_layout->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void SettingsWindow::closeSidebar() {
|
||||
sidebar_widget->setVisible(false);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <QStackedLayout>
|
||||
|
||||
#include "wifi.hpp"
|
||||
#include "widgets/offroad_alerts.hpp"
|
||||
|
||||
// *** settings widgets ***
|
||||
|
||||
|
@ -33,7 +32,6 @@ class SettingsWindow : public QWidget {
|
|||
|
||||
public:
|
||||
explicit SettingsWindow(QWidget *parent = 0);
|
||||
void refreshParams();
|
||||
|
||||
signals:
|
||||
void closeSettings();
|
||||
|
@ -41,14 +39,11 @@ signals:
|
|||
private:
|
||||
QPushButton *sidebar_alert_widget;
|
||||
QWidget *sidebar_widget;
|
||||
OffroadAlert *alerts_widget;
|
||||
std::map<QString, QWidget *> panels;
|
||||
QStackedLayout *panel_layout;
|
||||
|
||||
public slots:
|
||||
void setActivePanel();
|
||||
void closeAlerts();
|
||||
void openAlerts();
|
||||
void closeSidebar();
|
||||
void openSidebar();
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QPushButton>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QDebug>
|
||||
|
||||
#include "offroad_alerts.hpp"
|
||||
|
@ -32,110 +32,99 @@ OffroadAlert::OffroadAlert(QWidget* parent){
|
|||
setLayout(vlayout);
|
||||
}
|
||||
|
||||
void OffroadAlert::refresh(){
|
||||
void OffroadAlert::refresh() {
|
||||
cleanLayout(vlayout);
|
||||
parse_alerts();
|
||||
|
||||
bool updateAvailable = false;
|
||||
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
|
||||
|
||||
if (updateAvailable) {
|
||||
// If there is an update available, don't show alerts
|
||||
alerts.clear();
|
||||
|
||||
QFrame *f = new QFrame();
|
||||
|
||||
QVBoxLayout *update_layout = new QVBoxLayout;
|
||||
update_layout->addWidget(new QLabel("Update available"));
|
||||
update_layout->setMargin(10);
|
||||
update_layout->setSpacing(20);
|
||||
|
||||
std::vector<char> release_notes_bytes = Params().read_db_bytes("ReleaseNotes");
|
||||
QString releaseNotes = vectorToQString(release_notes_bytes);
|
||||
QLabel *notes_label = new QLabel(releaseNotes);
|
||||
QLabel *title = new QLabel("Update available");
|
||||
title->setStyleSheet(R"(
|
||||
font-size: 55px;
|
||||
font-weight: bold;
|
||||
)");
|
||||
update_layout->addWidget(title, 0, Qt::AlignTop);
|
||||
|
||||
QString release_notes = QString::fromStdString(Params().get("ReleaseNotes"));
|
||||
QLabel *notes_label = new QLabel(release_notes);
|
||||
notes_label->setStyleSheet(R"(font-size: 40px;)");
|
||||
notes_label->setWordWrap(true);
|
||||
update_layout->addSpacing(20);
|
||||
update_layout->addWidget(notes_label);
|
||||
update_layout->addSpacing(20);
|
||||
update_layout->addWidget(notes_label, 1, Qt::AlignTop);
|
||||
|
||||
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");});
|
||||
QObject::connect(update_button, &QPushButton::released, [=]() {std::system("sudo reboot");});
|
||||
#endif
|
||||
|
||||
f->setLayout(update_layout);
|
||||
f->setStyleSheet(R"(
|
||||
.QFrame{
|
||||
border-radius: 30px;
|
||||
border-radius: 20px;
|
||||
border: 2px solid white;
|
||||
background-color: #114267;
|
||||
}
|
||||
QLabel{
|
||||
font-size: 60px;
|
||||
background-color: #114267;
|
||||
QPushButton {
|
||||
padding: 20px;
|
||||
font-size: 35px;
|
||||
color: white;
|
||||
background-color: blue;
|
||||
}
|
||||
)");
|
||||
|
||||
vlayout->addWidget(f);
|
||||
vlayout->addSpacing(60);
|
||||
}else{
|
||||
} 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
|
||||
}
|
||||
|
||||
QString style = R"(
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
border-radius: 30px;
|
||||
border: 2px solid;
|
||||
border-color: white;
|
||||
)";
|
||||
style.append("background-color: " + QString(alert.severity ? "#971b1c" : "#114267"));
|
||||
|
||||
l->setStyleSheet(style);
|
||||
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()));
|
||||
QPushButton *hide_btn = new QPushButton(updateAvailable ? "Later" : "Hide alerts");
|
||||
hide_btn->setStyleSheet(R"(
|
||||
padding: 20px;
|
||||
font-size: 35px;
|
||||
color: white;
|
||||
background-color: blue;
|
||||
)");
|
||||
vlayout->addWidget(hide_btn);
|
||||
QObject::connect(hide_btn, SIGNAL(released()), this, SIGNAL(closeAlerts()));
|
||||
}
|
||||
|
||||
void OffroadAlert::parse_alerts(){
|
||||
alerts.clear();
|
||||
//We launch in selfdrive/ui
|
||||
// We launch in selfdrive/ui
|
||||
QFile inFile("../controls/lib/alerts_offroad.json");
|
||||
inFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QByteArray data = inFile.readAll();
|
||||
|
@ -145,11 +134,11 @@ void OffroadAlert::parse_alerts(){
|
|||
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();
|
||||
|
|
|
@ -1,25 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include <QWidget>
|
||||
#include <QFrame>
|
||||
#include <QTimer>
|
||||
#include <QCheckBox>
|
||||
#include <QStackedLayout>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
struct Alert{
|
||||
struct Alert {
|
||||
QString text;
|
||||
int severity;
|
||||
};
|
||||
|
||||
class OffroadAlert : public QWidget{
|
||||
class OffroadAlert : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OffroadAlert(QWidget *parent = 0);
|
||||
bool show_alert;
|
||||
QVector<Alert> alerts;
|
||||
bool updateAvailable;
|
||||
|
||||
private:
|
||||
QVBoxLayout *vlayout;
|
||||
|
|
|
@ -32,7 +32,6 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
|
|||
|
||||
void MainWindow::openSettings() {
|
||||
main_layout->setCurrentWidget(settingsWindow);
|
||||
settingsWindow->refreshParams();
|
||||
}
|
||||
|
||||
void MainWindow::closeSettings() {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import json
|
||||
|
||||
from common.basedir import BASEDIR
|
||||
from common.params import Params
|
||||
from selfdrive.controls.lib.alertmanager import set_offroad_alert
|
||||
|
||||
if __name__ == "__main__":
|
||||
params = Params()
|
||||
|
||||
with open(os.path.join(BASEDIR, "selfdrive/controls/lib/alerts_offroad.json")) as f:
|
||||
offroad_alerts = json.load(f)
|
||||
|
||||
t = 10 if len(sys.argv) < 2 else int(sys.argv[1])
|
||||
while True:
|
||||
print("setting alert update")
|
||||
params.put("UpdateAvailable", "1")
|
||||
params.put("ReleaseNotes", "this is a new version")
|
||||
time.sleep(t)
|
||||
params.put("UpdateAvailable", "0")
|
||||
|
||||
# cycle through normal alerts
|
||||
for a in offroad_alerts:
|
||||
print("setting alert:", a)
|
||||
set_offroad_alert(a, True)
|
||||
time.sleep(t)
|
||||
set_offroad_alert(a, False)
|
||||
|
||||
print("no alert")
|
||||
time.sleep(t)
|
Loading…
Reference in New Issue