mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-06-25 07:52:03 +08:00
nav: home/work shortcuts (#21276)
* add home/work widgets * remove todo * set contents from response * turn into buttons * add navigate button * fix includes * close settings on nav press * close sidebar when closing settings * use live api endpoint * larger fonts * more text fits * only place name * remove static response * properly clear
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="200"
|
||||
height="200"
|
||||
viewBox="0 0 200 200"
|
||||
id="home-15"
|
||||
sodipodi:docname="home.svg"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||
inkscape:export-filename="/home/batman/openpilot/selfdrive/assets/navigation/home_inactive.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<metadata
|
||||
id="metadata99">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs97" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1278"
|
||||
inkscape:window-height="1418"
|
||||
id="namedview95"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.810488"
|
||||
inkscape:cx="100.16296"
|
||||
inkscape:cy="24.659346"
|
||||
inkscape:window-x="2480"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="home-15" />
|
||||
<path
|
||||
d="m 58.038143,147.98997 c 0,1.11009 0.899932,2.01003 2.010031,2.01003 H 90.19059 v -24.12037 h 24.12035 V 150 h 30.14242 c 1.1101,0 2.01003,-0.89994 2.01003,-2.01003 V 101.76651 H 58.038143 c 0,0 0,46.22346 0,46.22346 z m 95.918637,-57.647675 -7.49259,-6.58406 v -30.22199 c 0,-4.44041 -3.59964,-8.04012 -8.04013,-8.04012 -4.44047,0 -8.04012,3.59971 -8.04012,8.04012 v 16.08023 l -26.67147,-23.39675 c -0.75981,-0.80642 -2.02886,-0.84597 -2.83737,-0.0884 l -0.0884,0.0884 -50.243521,43.92317 c -0.758989,0.81013 -0.717501,2.08216 0.09263,2.84115 0.365504,0.34242 0.84574,0.53603 1.346559,0.54295 l 14.095938,0.201011 h 86.405544 c 1.11011,0.004 2.01302,-0.893251 2.01672,-2.003361 8.4e-4,-0.51306 -0.19282,-1.00727 -0.54377,-1.38155 z"
|
||||
id="path92"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:8.04012012;fill:#ffffff;fill-opacity:1" />
|
||||
<circle
|
||||
style="fill:none;stroke:#ffffff;stroke-width:3.26192951;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path104"
|
||||
cx="100"
|
||||
cy="100"
|
||||
r="98.369034" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="200"
|
||||
height="200"
|
||||
viewBox="0 0 200 200"
|
||||
id="home-15"
|
||||
sodipodi:docname="work.svg"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||
inkscape:export-filename="/home/batman/openpilot/selfdrive/assets/navigation/work.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<metadata
|
||||
id="metadata99">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs97" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1278"
|
||||
inkscape:window-height="1418"
|
||||
id="namedview95"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.810488"
|
||||
inkscape:cx="13.441829"
|
||||
inkscape:cy="50.152652"
|
||||
inkscape:window-x="1200"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="home-15" />
|
||||
<ellipse
|
||||
style="fill:none;stroke:#ffffff;stroke-width:3.26200008;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path104"
|
||||
cx="100"
|
||||
cy="99.999969"
|
||||
rx="98.369003"
|
||||
ry="98.369034" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path17"
|
||||
d="M 130,74 V 58 c 0,-8 -8,-8 -8,-8 H 82.3976 c 0,0 -8.8312,0.016 -8.3976,8 V 74 H 58 c 0,0 -8,0 -8,8 v 56 c 0,8 8,8 8,8 h 88 c 0,0 8,0 8,-8 V 82 c 0,-8 -8,-8 -8,-8 z M 86,62 h 32 V 74 H 86 Z"
|
||||
style="fill:#ffffff;stroke-width:8;fill-opacity:1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
@@ -151,6 +151,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"ApiCache_DriveStats", PERSISTENT},
|
||||
{"ApiCache_Device", PERSISTENT},
|
||||
{"ApiCache_Owner", PERSISTENT},
|
||||
{"ApiCache_NavDestinations", PERSISTENT},
|
||||
{"AthenadPid", PERSISTENT},
|
||||
{"CalibrationParams", PERSISTENT},
|
||||
{"CarBatteryCapacity", PERSISTENT},
|
||||
|
||||
@@ -44,6 +44,10 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
|
||||
slayout->addWidget(driver_view);
|
||||
}
|
||||
|
||||
void HomeWindow::showSidebar(bool show) {
|
||||
sidebar->setVisible(show);
|
||||
}
|
||||
|
||||
void HomeWindow::offroadTransition(bool offroad) {
|
||||
if (offroad) {
|
||||
slayout->setCurrentWidget(home);
|
||||
|
||||
@@ -54,6 +54,7 @@ signals:
|
||||
public slots:
|
||||
void offroadTransition(bool offroad);
|
||||
void showDriverView(bool show);
|
||||
void showSidebar(bool show);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* e) override;
|
||||
|
||||
@@ -276,6 +276,7 @@ void MapWindow::recomputeRoute() {
|
||||
|
||||
if (*new_destination != nav_destination) {
|
||||
setVisible(true); // Show map on destination set/change
|
||||
// TODO: close sidebar
|
||||
should_recompute = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,124 @@
|
||||
#include "map_settings.h"
|
||||
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include "selfdrive/ui/qt/request_repeater.h"
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
#include "selfdrive/common/util.h"
|
||||
|
||||
static QString shorten(const QString &str, int max_len) {
|
||||
return str.size() > max_len ? str.left(max_len).trimmed() + "…" : str;
|
||||
}
|
||||
|
||||
MapPanel::MapPanel(QWidget* parent) : QWidget(parent) {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
||||
Params params = Params();
|
||||
|
||||
QString dongle = QString::fromStdString(params.get("DongleId", false));
|
||||
// TODO: Add buttons for home/work shortcuts
|
||||
// Home
|
||||
QHBoxLayout *home_layout = new QHBoxLayout;
|
||||
home_button = new QPushButton;
|
||||
home_button->setIconSize(QSize(200, 200));
|
||||
home_layout->addWidget(home_button);
|
||||
|
||||
home_address = new QLabel;
|
||||
home_address->setWordWrap(true);
|
||||
home_layout->addSpacing(30);
|
||||
home_layout->addWidget(home_address);
|
||||
home_layout->addStretch();
|
||||
|
||||
// Work
|
||||
QHBoxLayout *work_layout = new QHBoxLayout;
|
||||
work_button = new QPushButton;
|
||||
work_button->setIconSize(QSize(200, 200));
|
||||
work_layout->addWidget(work_button);
|
||||
|
||||
work_address = new QLabel;
|
||||
work_address->setWordWrap(true);
|
||||
work_layout->addSpacing(30);
|
||||
work_layout->addWidget(work_address);
|
||||
work_layout->addStretch();
|
||||
|
||||
// Home & Work layout
|
||||
QHBoxLayout *home_work_layout = new QHBoxLayout;
|
||||
home_work_layout->addLayout(home_layout, 1);
|
||||
home_work_layout->addSpacing(50);
|
||||
home_work_layout->addLayout(work_layout, 1);
|
||||
|
||||
main_layout->addLayout(home_work_layout);
|
||||
main_layout->addSpacing(50);
|
||||
main_layout->addWidget(horizontal_line());
|
||||
|
||||
// Settings
|
||||
main_layout->addWidget(new ParamControl("NavSettingTime24h",
|
||||
"Show ETA in 24h format",
|
||||
"Use 24h format instead of am/pm",
|
||||
"",
|
||||
this));
|
||||
main_layout->addStretch();
|
||||
|
||||
clear();
|
||||
|
||||
std::string dongle_id = Params().get("DongleId");
|
||||
if (util::is_valid_dongle_id(dongle_id)) {
|
||||
std::string url = "https://api.commadotai.com/v1/navigation/" + dongle_id + "/locations";
|
||||
RequestRepeater* repeater = new RequestRepeater(this, QString::fromStdString(url), "ApiCache_NavDestinations", 30);
|
||||
QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &MapPanel::parseResponse);
|
||||
}
|
||||
}
|
||||
|
||||
void MapPanel::clear() {
|
||||
home_button->setIcon(QPixmap("../assets/navigation/home_inactive.png"));
|
||||
home_address->setStyleSheet(R"(font-size: 50px; color: grey;)");
|
||||
home_address->setText("No home\nlocation set");
|
||||
home_button->disconnect();
|
||||
|
||||
work_button->setIcon(QPixmap("../assets/navigation/work_inactive.png"));
|
||||
work_address->setStyleSheet(R"(font-size: 50px; color: grey;)");
|
||||
work_address->setText("No work\nlocation set");
|
||||
work_button->disconnect();
|
||||
}
|
||||
|
||||
|
||||
void MapPanel::parseResponse(const QString &response) {
|
||||
QJsonDocument doc = QJsonDocument::fromJson(response.trimmed().toUtf8());
|
||||
if (doc.isNull()) {
|
||||
qDebug() << "JSON Parse failed on navigation locations";
|
||||
return;
|
||||
}
|
||||
|
||||
clear();
|
||||
|
||||
for (auto location : doc.array()) {
|
||||
auto obj = location.toObject();
|
||||
|
||||
auto type = obj["save_type"].toString();
|
||||
auto label = obj["label"].toString();
|
||||
auto name = obj["place_name"].toString();
|
||||
auto details = shorten(obj["place_details"].toString(), 30);
|
||||
|
||||
if (type == "favorite") {
|
||||
if (label == "home") {
|
||||
home_address->setText(name);
|
||||
home_address->setStyleSheet(R"(font-size: 50px; color: white;)");
|
||||
home_button->setIcon(QPixmap("../assets/navigation/home.png"));
|
||||
QObject::connect(home_button, &QPushButton::clicked, [=]() {
|
||||
navigateTo(obj);
|
||||
emit closeSettings();
|
||||
});
|
||||
} else if (label == "work") {
|
||||
work_address->setText(name);
|
||||
work_address->setStyleSheet(R"(font-size: 50px; color: white;)");
|
||||
work_button->setIcon(QPixmap("../assets/navigation/work.png"));
|
||||
QObject::connect(work_button, &QPushButton::clicked, [=]() {
|
||||
navigateTo(obj);
|
||||
emit closeSettings();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapPanel::navigateTo(const QJsonObject &place) {
|
||||
QJsonDocument doc(place);
|
||||
Params().put("NavDestination", doc.toJson().toStdString());
|
||||
}
|
||||
|
||||
@@ -1,8 +1,24 @@
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
class MapPanel : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MapPanel(QWidget* parent = nullptr);
|
||||
};
|
||||
|
||||
void navigateTo(const QJsonObject &place);
|
||||
void parseResponse(const QString &response);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
QPushButton *home_button, *work_button;
|
||||
QLabel *home_address, *work_address;
|
||||
|
||||
signals:
|
||||
void closeSettings();
|
||||
};
|
||||
|
||||
@@ -345,7 +345,9 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
|
||||
#ifdef ENABLE_MAPS
|
||||
if (!Params().get("MapboxToken").empty()) {
|
||||
panels.push_back({"Navigation", new MapPanel(this)});
|
||||
auto map_panel = new MapPanel(this);
|
||||
panels.push_back({"Navigation", map_panel});
|
||||
QObject::connect(map_panel, &MapPanel::closeSettings, this, &SettingsWindow::closeSettings);
|
||||
}
|
||||
#endif
|
||||
const int padding = panels.size() > 3 ? 25 : 35;
|
||||
|
||||
@@ -67,6 +67,10 @@ void MainWindow::openSettings() {
|
||||
|
||||
void MainWindow::closeSettings() {
|
||||
main_layout->setCurrentWidget(homeWindow);
|
||||
|
||||
if (QUIState::ui_state.scene.started) {
|
||||
emit homeWindow->showSidebar(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
|
||||
|
||||
Reference in New Issue
Block a user