diff --git a/selfdrive/ui/qt/widgets/drive_stats.cc b/selfdrive/ui/qt/widgets/drive_stats.cc index c48aa1310a..357184d7f3 100644 --- a/selfdrive/ui/qt/widgets/drive_stats.cc +++ b/selfdrive/ui/qt/widgets/drive_stats.cc @@ -1,7 +1,7 @@ #include "selfdrive/ui/qt/widgets/drive_stats.h" #include -#include +#include #include #include @@ -10,60 +10,79 @@ const double MILE_TO_KM = 1.60934; -static QLayout* build_stat_layout(QLabel** metric, const QString& name) { - QVBoxLayout* layout = new QVBoxLayout; - layout->setMargin(0); - *metric = new QLabel("0"); - (*metric)->setStyleSheet("font-size: 80px; font-weight: 600;"); - layout->addWidget(*metric, 0, Qt::AlignLeft); +namespace { +QLabel* numberLabel() { + QLabel* label = new QLabel("0"); + label->setStyleSheet("font-size: 80px; font-weight: 600;"); + return label; +} + +QLabel* unitLabel(const QString& name) { QLabel* label = new QLabel(name); label->setStyleSheet("font-size: 45px; font-weight: 500;"); - layout->addWidget(label, 0, Qt::AlignLeft); - return layout; + return label; } -void DriveStats::parseResponse(const QString& response) { - QJsonDocument doc = QJsonDocument::fromJson(response.trimmed().toUtf8()); - if (doc.isNull()) { - qDebug() << "JSON Parse failed on getting past drives statistics"; - return; - } - - auto update = [](const QJsonObject &obj, StatsLabels& labels, bool metric) { - labels.routes->setText(QString::number((int)obj["routes"].toDouble())); - labels.distance->setText(QString::number(int(obj["distance"].toDouble() * (metric ? MILE_TO_KM : 1)))); - labels.hours->setText(QString::number((int)(obj["minutes"].toDouble() / 60))); - }; - - QJsonObject json = doc.object(); - update(json["all"].toObject(), all_, metric); - update(json["week"].toObject(), week_, metric); -} +} // namespace DriveStats::DriveStats(QWidget* parent) : QWidget(parent) { - metric = Params().getBool("IsMetric"); - QString distance_unit = metric ? "KM" : "MILES"; + metric_ = Params().getBool("IsMetric"); - 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); - }; + QGridLayout* main_layout = new QGridLayout(this); + main_layout->setMargin(0); - QGridLayout* gl = new QGridLayout(this); - gl->setMargin(0); + auto add_stats_layouts = [=](const QString &title, StatsLabels& labels) { + int row = main_layout->rowCount(); + main_layout->addWidget(new QLabel(title), row++, 0, 1, 3); - gl->addWidget(new QLabel("ALL TIME"), 0, 0, 1, 3); - add_stats_layouts(gl, all_, 1, distance_unit); + main_layout->addWidget(labels.routes = numberLabel(), row, 0, Qt::AlignLeft); + main_layout->addWidget(labels.distance = numberLabel(), row, 1, Qt::AlignLeft); + main_layout->addWidget(labels.hours = numberLabel(), row, 2, Qt::AlignLeft); + + main_layout->addWidget(unitLabel("DRIVES"), row + 1, 0, Qt::AlignLeft); + main_layout->addWidget(labels.distance_unit = unitLabel(getDistanceUnit()), row + 1, 1, Qt::AlignLeft); + main_layout->addWidget(unitLabel("HOURS"), row + 1, 2, Qt::AlignLeft); + }; - gl->addWidget(new QLabel("PAST WEEK"), 6, 0, 1, 3); - add_stats_layouts(gl, week_, 7, distance_unit); + add_stats_layouts("ALL TIME", all_); + add_stats_layouts("PAST WEEK", week_); 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", 30); + RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_DriveStats", 30); QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &DriveStats::parseResponse); setStyleSheet(R"(QLabel {font-size: 48px; font-weight: 500;})"); } + +void DriveStats::updateStats() { + auto update = [=](const QJsonObject& obj, StatsLabels& labels) { + labels.routes->setText(QString::number((int)obj["routes"].toDouble())); + labels.distance->setText(QString::number(int(obj["distance"].toDouble() * (metric_ ? MILE_TO_KM : 1)))); + labels.distance_unit->setText(getDistanceUnit()); + labels.hours->setText(QString::number((int)(obj["minutes"].toDouble() / 60))); + }; + + QJsonObject json = stats_.object(); + update(json["all"].toObject(), all_); + update(json["week"].toObject(), week_); +} + +void DriveStats::parseResponse(const QString& response) { + QJsonDocument doc = QJsonDocument::fromJson(response.trimmed().toUtf8()); + if (doc.isNull()) { + qDebug() << "JSON Parse failed on getting past drives statistics"; + return; + } + stats_ = doc; + updateStats(); +} + +void DriveStats::showEvent(QShowEvent* event) { + bool metric = Params().getBool("IsMetric"); + if (metric_ != metric) { + metric_ = metric; + updateStats(); + } +} diff --git a/selfdrive/ui/qt/widgets/drive_stats.h b/selfdrive/ui/qt/widgets/drive_stats.h index deeb80f65f..2747487ffa 100644 --- a/selfdrive/ui/qt/widgets/drive_stats.h +++ b/selfdrive/ui/qt/widgets/drive_stats.h @@ -1,5 +1,6 @@ #pragma once +#include #include class DriveStats : public QWidget { @@ -9,9 +10,14 @@ public: explicit DriveStats(QWidget* parent = 0); private: - bool metric; + void showEvent(QShowEvent *event) override; + void updateStats(); + inline QString getDistanceUnit() const { return metric_ ? "KM" : "MILES"; } + + bool metric_; + QJsonDocument stats_; struct StatsLabels { - QLabel *routes, *distance, *hours; + QLabel *routes, *distance, *distance_unit, *hours; } all_, week_; private slots: