You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
8.2 KiB
251 lines
8.2 KiB
#include "map_settings.h"
|
|
|
|
#include <QDebug>
|
|
|
|
#include "selfdrive/common/util.h"
|
|
#include "selfdrive/ui/qt/util.h"
|
|
#include "selfdrive/ui/qt/qt_window.h"
|
|
#include "selfdrive/ui/qt/request_repeater.h"
|
|
#include "selfdrive/ui/qt/widgets/controls.h"
|
|
#include "selfdrive/ui/qt/widgets/scrollview.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) {
|
|
stack = new QStackedWidget;
|
|
|
|
QWidget * main_widget = new QWidget;
|
|
QVBoxLayout *main_layout = new QVBoxLayout(main_widget);
|
|
const int icon_size = 200;
|
|
|
|
// Home
|
|
QHBoxLayout *home_layout = new QHBoxLayout;
|
|
home_button = new QPushButton;
|
|
home_button->setIconSize(QSize(icon_size, icon_size));
|
|
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(icon_size, icon_size));
|
|
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(20);
|
|
main_layout->addWidget(horizontal_line());
|
|
main_layout->addSpacing(20);
|
|
|
|
// Recents
|
|
recent_layout = new QVBoxLayout;
|
|
QWidget *recent_widget = new LayoutWidget(recent_layout, this);
|
|
ScrollView *recent_scroller = new ScrollView(recent_widget, this);
|
|
main_layout->addWidget(recent_scroller, 1);
|
|
|
|
QWidget * no_prime_widget = new QWidget;
|
|
QVBoxLayout *no_prime_layout = new QVBoxLayout(no_prime_widget);
|
|
QLabel *signup_header = new QLabel("Try the Navigation Beta");
|
|
signup_header->setStyleSheet(R"(font-size: 75px; color: white; font-weight:600;)");
|
|
signup_header->setAlignment(Qt::AlignCenter);
|
|
|
|
no_prime_layout->addWidget(signup_header);
|
|
no_prime_layout->addSpacing(50);
|
|
|
|
QLabel *screenshot = new QLabel;
|
|
QPixmap pm = QPixmap("../assets/navigation/screenshot.png");
|
|
screenshot->setPixmap(pm.scaledToWidth(vwp_w * 0.5, Qt::SmoothTransformation));
|
|
no_prime_layout->addWidget(screenshot, 0, Qt::AlignHCenter);
|
|
|
|
QLabel *signup = new QLabel("Get turn-by-turn directions displayed and more with a comma \nprime subscription. Sign up now: https://connect.comma.ai");
|
|
signup->setStyleSheet(R"(font-size: 45px; color: white; font-weight:300;)");
|
|
signup->setAlignment(Qt::AlignCenter);
|
|
|
|
no_prime_layout->addSpacing(50);
|
|
no_prime_layout->addWidget(signup);
|
|
|
|
no_prime_layout->addStretch();
|
|
|
|
stack->addWidget(main_widget);
|
|
stack->addWidget(no_prime_widget);
|
|
stack->setCurrentIndex(1);
|
|
|
|
QVBoxLayout *wrapper = new QVBoxLayout(this);
|
|
wrapper->addWidget(stack);
|
|
|
|
clear();
|
|
|
|
if (auto dongle_id = getDongleId()) {
|
|
// Fetch favorite and recent locations
|
|
{
|
|
QString url = "https://api.commadotai.com/v1/navigation/" + *dongle_id + "/locations";
|
|
RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_NavDestinations", 30, true);
|
|
QObject::connect(repeater, &RequestRepeater::receivedResponse, this, &MapPanel::parseResponse);
|
|
QObject::connect(repeater, &RequestRepeater::failedResponse, this, &MapPanel::failedResponse);
|
|
}
|
|
|
|
// Destination set while offline
|
|
{
|
|
QString url = "https://api.commadotai.com/v1/navigation/" + *dongle_id + "/next";
|
|
RequestRepeater* repeater = new RequestRepeater(this, url, "", 10, true);
|
|
HttpRequest* deleter = new HttpRequest(this);
|
|
|
|
QObject::connect(repeater, &RequestRepeater::receivedResponse, [=](QString resp) {
|
|
auto params = Params();
|
|
if (resp != "null") {
|
|
if (params.get("NavDestination").empty()) {
|
|
qWarning() << "Setting NavDestination from /next" << resp;
|
|
params.put("NavDestination", resp.toStdString());
|
|
} else {
|
|
qWarning() << "Got location from /next, but NavDestination already set";
|
|
}
|
|
|
|
// Send DELETE to clear destination server side
|
|
deleter->sendRequest(url, HttpRequest::Method::DELETE);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
clearLayout(recent_layout);
|
|
}
|
|
|
|
|
|
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();
|
|
|
|
bool has_recents = false;
|
|
for (auto &save_type: {"favorite", "recent"}) {
|
|
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 = obj["place_details"].toString();
|
|
|
|
if (type != save_type) continue;
|
|
|
|
if (type == "favorite" && 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 (type == "favorite" && 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();
|
|
});
|
|
} else {
|
|
ClickableWidget *widget = new ClickableWidget;
|
|
QHBoxLayout *layout = new QHBoxLayout(widget);
|
|
layout->setContentsMargins(15, 14, 40, 14);
|
|
|
|
QLabel *star = new QLabel("★");
|
|
auto sp = star->sizePolicy();
|
|
sp.setRetainSizeWhenHidden(true);
|
|
star->setSizePolicy(sp);
|
|
|
|
star->setVisible(type == "favorite");
|
|
star->setStyleSheet(R"(font-size: 60px;)");
|
|
layout->addWidget(star);
|
|
layout->addSpacing(10);
|
|
|
|
|
|
QLabel *recent_label = new QLabel(shorten(name + " " + details, 45));
|
|
recent_label->setStyleSheet(R"(font-size: 50px;)");
|
|
|
|
layout->addWidget(recent_label);
|
|
layout->addStretch();
|
|
|
|
QLabel *arrow = new QLabel("→");
|
|
arrow->setStyleSheet(R"(font-size: 60px;)");
|
|
layout->addWidget(arrow);
|
|
|
|
widget->setStyleSheet(R"(
|
|
.ClickableWidget {
|
|
border-radius: 10px;
|
|
border-width: 1px;
|
|
border-style: solid;
|
|
border-color: gray;
|
|
}
|
|
QWidget {
|
|
background-color: #393939;
|
|
color: #9c9c9c;
|
|
}
|
|
)");
|
|
|
|
QObject::connect(widget, &ClickableWidget::clicked, [=]() {
|
|
navigateTo(obj);
|
|
emit closeSettings();
|
|
});
|
|
|
|
recent_layout->addWidget(widget);
|
|
recent_layout->addSpacing(10);
|
|
has_recents = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (!has_recents) {
|
|
QLabel *no_recents = new QLabel("no recent destinations");
|
|
no_recents->setStyleSheet(R"(font-size: 50px; color: #9c9c9c)");
|
|
recent_layout->addWidget(no_recents);
|
|
}
|
|
|
|
recent_layout->addStretch();
|
|
stack->setCurrentIndex(0);
|
|
repaint();
|
|
}
|
|
|
|
void MapPanel::failedResponse(const QString &response) {
|
|
stack->setCurrentIndex(1);
|
|
}
|
|
|
|
void MapPanel::navigateTo(const QJsonObject &place) {
|
|
QJsonDocument doc(place);
|
|
params.put("NavDestination", doc.toJson().toStdString());
|
|
}
|
|
|