mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-08 15:12:10 +08:00
ui: offroad experimental mode button (#26498)
* draft * draft * before qpushbutton * icon, clean up button, clicked goes to toggles * fix icon * add imgs * img * make square * works with layouts! * fix gradient * this looks good * clean up * clean up * remove padding around couch * use scene's experimental_model, new onroad design * rename widget * def want 3 * update translations * add img * add 25px of padding! * make 300px (no change) * clean up old images * 5 px smaller * add white img * fix from merge * no style sheets * see how this looks on device * aliased vertical line (clean up) * clean up * imgs * couch * delete * bye bye * expand toggle support * clean up * fix dynamic icon * make exp icon dynamic * order * move to offroad old-commit-hash: 58b84fb401a804967aa0dd5ee66fafa90194fd30
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:64708889e701acf7f2f43fd9c3696eb7f2c849ae67693ce581ad8f92433b3b24
|
||||
size 204140
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ea87cc840ba1b0b96351bbde97af171c3cda462559459e186a5689f9f4aba82e
|
||||
size 2311
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c26afadff128244567a7cf98f1c998f97056b19209301ff7fc8851eb807fb748
|
||||
size 2193
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5ae28a53171567c8a0d52eec75cc49004cb8dd19dcab9a360784718ab8ec7c02
|
||||
size 1931
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:99be696be983700d7eb1768bd1c840198a4eb9525b71e28efea49f13c358e519
|
||||
size 1891
|
||||
@@ -58,7 +58,7 @@ qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs)
|
||||
qt_src = ["main.cc", "qt/sidebar.cc", "qt/onroad.cc", "qt/body.cc",
|
||||
"qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc",
|
||||
"qt/offroad/software_settings.cc", "qt/offroad/onboarding.cc",
|
||||
"qt/offroad/driverview.cc"]
|
||||
"qt/offroad/driverview.cc", "qt/offroad/experimental_mode.cc"]
|
||||
qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs)
|
||||
if GetOption('test'):
|
||||
qt_src.remove("main.cc") # replaced by test_runner
|
||||
|
||||
+17
-2
@@ -4,6 +4,7 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/widgets/drive_stats.h"
|
||||
#include "selfdrive/ui/qt/widgets/prime.h"
|
||||
@@ -22,7 +23,8 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
|
||||
slayout = new QStackedLayout();
|
||||
main_layout->addLayout(slayout);
|
||||
|
||||
home = new OffroadHome();
|
||||
home = new OffroadHome(this);
|
||||
QObject::connect(home, &OffroadHome::openSettings, this, &HomeWindow::openSettings);
|
||||
slayout->addWidget(home);
|
||||
|
||||
onroad = new OnroadWindow(this);
|
||||
@@ -128,11 +130,24 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
|
||||
main_layout->addSpacing(25);
|
||||
center_layout = new QStackedLayout();
|
||||
|
||||
// Vertical experimental button and drive stats layout
|
||||
QWidget* statsAndExperimentalModeButtonWidget = new QWidget(this);
|
||||
QVBoxLayout* statsAndExperimentalModeButton = new QVBoxLayout(statsAndExperimentalModeButtonWidget);
|
||||
statsAndExperimentalModeButton->setSpacing(30);
|
||||
statsAndExperimentalModeButton->setMargin(0);
|
||||
|
||||
ExperimentalModeButton *experimental_mode = new ExperimentalModeButton(this);
|
||||
QObject::connect(experimental_mode, &ExperimentalModeButton::openSettings, this, &OffroadHome::openSettings);
|
||||
|
||||
statsAndExperimentalModeButton->addWidget(experimental_mode, 1);
|
||||
statsAndExperimentalModeButton->addWidget(new DriveStats, 1);
|
||||
|
||||
// Horizontal experimental + drive stats and setup widget
|
||||
QWidget* statsAndSetupWidget = new QWidget(this);
|
||||
QHBoxLayout* statsAndSetup = new QHBoxLayout(statsAndSetupWidget);
|
||||
statsAndSetup->setMargin(0);
|
||||
statsAndSetup->setSpacing(30);
|
||||
statsAndSetup->addWidget(new DriveStats, 1);
|
||||
statsAndSetup->addWidget(statsAndExperimentalModeButtonWidget, 1);
|
||||
statsAndSetup->addWidget(new SetupWidget);
|
||||
|
||||
center_layout->addWidget(statsAndSetupWidget);
|
||||
|
||||
@@ -22,6 +22,9 @@ class OffroadHome : public QFrame {
|
||||
public:
|
||||
explicit OffroadHome(QWidget* parent = 0);
|
||||
|
||||
signals:
|
||||
void openSettings(int index = 0, const QString ¶m = "");
|
||||
|
||||
private:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void hideEvent(QHideEvent *event) override;
|
||||
@@ -45,7 +48,7 @@ public:
|
||||
explicit HomeWindow(QWidget* parent = 0);
|
||||
|
||||
signals:
|
||||
void openSettings();
|
||||
void openSettings(int index = 0, const QString ¶m = "");
|
||||
void closeSettings();
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
ExperimentalModeButton::ExperimentalModeButton(QWidget *parent) : QPushButton(parent) {
|
||||
chill_pixmap = QPixmap("../assets/img_couch.svg").scaledToWidth(img_width, Qt::SmoothTransformation);
|
||||
experimental_pixmap = QPixmap("../assets/img_experimental_grey.svg").scaledToWidth(img_width, Qt::SmoothTransformation);
|
||||
|
||||
// go to toggles and expand experimental mode description
|
||||
connect(this, &QPushButton::clicked, [=]() { emit openSettings(2, "ExperimentalMode"); });
|
||||
|
||||
setFixedHeight(125);
|
||||
QHBoxLayout *main_layout = new QHBoxLayout;
|
||||
main_layout->setContentsMargins(horizontal_padding, 0, horizontal_padding, 0);
|
||||
|
||||
mode_label = new QLabel;
|
||||
mode_icon = new QLabel;
|
||||
mode_icon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
|
||||
main_layout->addWidget(mode_label, 1, Qt::AlignLeft);
|
||||
main_layout->addWidget(mode_icon, 0, Qt::AlignRight);
|
||||
|
||||
setLayout(main_layout);
|
||||
|
||||
setStyleSheet(R"(
|
||||
QPushButton {
|
||||
border: none;
|
||||
}
|
||||
|
||||
QLabel {
|
||||
font-size: 45px;
|
||||
font-weight: 300;
|
||||
text-align: left;
|
||||
font-family: JetBrainsMono;
|
||||
color: #000000;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
void ExperimentalModeButton::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(rect(), 10, 10);
|
||||
|
||||
// gradient
|
||||
bool pressed = isDown();
|
||||
QLinearGradient gradient(rect().left(), 0, rect().right(), 0);
|
||||
if (experimental_mode) {
|
||||
gradient.setColorAt(0, QColor(255, 155, 63, pressed ? 0xcc : 0xff));
|
||||
gradient.setColorAt(1, QColor(219, 56, 34, pressed ? 0xcc : 0xff));
|
||||
} else {
|
||||
gradient.setColorAt(0, QColor(20, 255, 171, pressed ? 0xcc : 0xff));
|
||||
gradient.setColorAt(1, QColor(35, 149, 255, pressed ? 0xcc : 0xff));
|
||||
}
|
||||
p.fillPath(path, gradient);
|
||||
|
||||
// vertical line
|
||||
p.setPen(QPen(QColor(0, 0, 0, 0x4d), 3, Qt::SolidLine));
|
||||
int line_x = rect().right() - img_width - (2 * horizontal_padding);
|
||||
p.drawLine(line_x, rect().bottom(), line_x, rect().top());
|
||||
}
|
||||
|
||||
void ExperimentalModeButton::showEvent(QShowEvent *event) {
|
||||
experimental_mode = params.getBool("ExperimentalMode");
|
||||
mode_icon->setPixmap(experimental_mode ? experimental_pixmap : chill_pixmap);
|
||||
mode_label->setText(experimental_mode ? tr("EXPERIMENTAL MODE ON") : tr("CHILL MODE ON"));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "common/params.h"
|
||||
|
||||
class ExperimentalModeButton : public QPushButton {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExperimentalModeButton(QWidget* parent = 0);
|
||||
|
||||
signals:
|
||||
void openSettings(int index = 0, const QString &toggle = "");
|
||||
|
||||
private:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
Params params;
|
||||
bool experimental_mode;
|
||||
int img_width = 100;
|
||||
int horizontal_padding = 30;
|
||||
QPixmap experimental_pixmap;
|
||||
QPixmap chill_pixmap;
|
||||
QLabel *mode_label;
|
||||
QLabel *mode_icon;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
};
|
||||
@@ -39,7 +39,7 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
"ExperimentalMode",
|
||||
tr("Experimental Mode"),
|
||||
"",
|
||||
"../assets/offroad/icon_road.png",
|
||||
"../assets/img_experimental_white.svg",
|
||||
},
|
||||
{
|
||||
"ExperimentalLongitudinalEnabled",
|
||||
@@ -100,6 +100,7 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
}
|
||||
|
||||
// Toggles with confirmation dialogs
|
||||
toggles["ExperimentalMode"]->setActiveIcon("../assets/img_experimental.svg");
|
||||
toggles["ExperimentalMode"]->setConfirmation(true, true);
|
||||
toggles["ExperimentalLongitudinalEnabled"]->setConfirmation(true, false);
|
||||
|
||||
@@ -108,6 +109,10 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
});
|
||||
}
|
||||
|
||||
void TogglesPanel::expandToggleDescription(const QString ¶m) {
|
||||
toggles[param.toStdString()]->showDescription();
|
||||
}
|
||||
|
||||
void TogglesPanel::showEvent(QShowEvent *event) {
|
||||
updateToggles();
|
||||
}
|
||||
@@ -299,8 +304,15 @@ void DevicePanel::poweroff() {
|
||||
}
|
||||
|
||||
void SettingsWindow::showEvent(QShowEvent *event) {
|
||||
panel_widget->setCurrentIndex(0);
|
||||
nav_btns->buttons()[0]->setChecked(true);
|
||||
setCurrentPanel(0);
|
||||
}
|
||||
|
||||
void SettingsWindow::setCurrentPanel(int index, const QString ¶m) {
|
||||
panel_widget->setCurrentIndex(index);
|
||||
nav_btns->buttons()[index]->setChecked(true);
|
||||
if (!param.isEmpty()) {
|
||||
emit expandToggleDescription(param);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
@@ -341,10 +353,13 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
QObject::connect(device, &DevicePanel::reviewTrainingGuide, this, &SettingsWindow::reviewTrainingGuide);
|
||||
QObject::connect(device, &DevicePanel::showDriverView, this, &SettingsWindow::showDriverView);
|
||||
|
||||
TogglesPanel *toggles = new TogglesPanel(this);
|
||||
QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription);
|
||||
|
||||
QList<QPair<QString, QWidget *>> panels = {
|
||||
{tr("Device"), device},
|
||||
{tr("Network"), new Networking(this)},
|
||||
{tr("Toggles"), new TogglesPanel(this)},
|
||||
{tr("Toggles"), toggles},
|
||||
{tr("Software"), new SoftwarePanel(this)},
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ class SettingsWindow : public QFrame {
|
||||
|
||||
public:
|
||||
explicit SettingsWindow(QWidget *parent = 0);
|
||||
void setCurrentPanel(int index, const QString ¶m = "");
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
@@ -25,6 +26,7 @@ signals:
|
||||
void closeSettings();
|
||||
void reviewTrainingGuide();
|
||||
void showDriverView();
|
||||
void expandToggleDescription(const QString ¶m);
|
||||
|
||||
private:
|
||||
QPushButton *sidebar_alert_widget;
|
||||
@@ -56,6 +58,9 @@ public:
|
||||
explicit TogglesPanel(SettingsWindow *parent);
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void expandToggleDescription(const QString ¶m);
|
||||
|
||||
private:
|
||||
Params params;
|
||||
std::map<std::string, ParamControl*> toggles;
|
||||
|
||||
@@ -174,6 +174,7 @@ AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* par
|
||||
pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"uiDebug"});
|
||||
|
||||
engage_img = loadPixmap("../assets/img_chffr_wheel.png", {img_size, img_size});
|
||||
experimental_img = loadPixmap("../assets/img_experimental.svg", {img_size - 5, img_size - 5});
|
||||
dm_img = loadPixmap("../assets/img_driver_face.png", {img_size, img_size});
|
||||
}
|
||||
|
||||
@@ -378,8 +379,9 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
|
||||
|
||||
// engage-ability icon
|
||||
if (engageable) {
|
||||
SubMaster &sm = *(uiState()->sm);
|
||||
drawIcon(p, rect().right() - radius / 2 - bdr_s * 2, radius / 2 + int(bdr_s * 1.5),
|
||||
engage_img, bg_colors[status], 1.0);
|
||||
sm["controlsState"].getControlsState().getExperimentalMode() ? experimental_img : engage_img, blackColor(166), 1.0);
|
||||
}
|
||||
|
||||
// dm icon
|
||||
@@ -409,7 +411,7 @@ void AnnotatedCameraWidget::drawIcon(QPainter &p, int x, int y, QPixmap &img, QB
|
||||
p.setBrush(bg);
|
||||
p.drawEllipse(x - radius / 2, y - radius / 2, radius, radius);
|
||||
p.setOpacity(opacity);
|
||||
p.drawPixmap(x - img_size / 2, y - img_size / 2, img);
|
||||
p.drawPixmap(x - img.size().width() / 2, y - img.size().height() / 2, img);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255);
|
||||
|
||||
QPixmap engage_img;
|
||||
QPixmap experimental_img;
|
||||
QPixmap dm_img;
|
||||
const int radius = 192;
|
||||
const int img_size = (radius / 2) * 1.5;
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
explicit Sidebar(QWidget* parent = 0);
|
||||
|
||||
signals:
|
||||
void openSettings();
|
||||
void openSettings(int index = 0, const QString ¶m = "");
|
||||
void valueChanged();
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -53,6 +53,7 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
|
||||
QFontDatabase::addApplicationFont("../assets/fonts/Inter-Regular.ttf");
|
||||
QFontDatabase::addApplicationFont("../assets/fonts/Inter-SemiBold.ttf");
|
||||
QFontDatabase::addApplicationFont("../assets/fonts/Inter-Thin.ttf");
|
||||
QFontDatabase::addApplicationFont("../assets/fonts/JetBrainsMono-Medium.ttf");
|
||||
|
||||
// no outline to prevent the focus rectangle
|
||||
setStyleSheet(R"(
|
||||
@@ -64,8 +65,9 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
}
|
||||
|
||||
void MainWindow::openSettings() {
|
||||
void MainWindow::openSettings(int index, const QString ¶m) {
|
||||
main_layout->setCurrentWidget(settingsWindow);
|
||||
settingsWindow->setCurrentPanel(index, param);
|
||||
}
|
||||
|
||||
void MainWindow::closeSettings() {
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
void openSettings();
|
||||
void openSettings(int index = 0, const QString ¶m = "");
|
||||
void closeSettings();
|
||||
|
||||
Device device;
|
||||
|
||||
@@ -281,6 +281,17 @@
|
||||
<translation>カメラを起動しています</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExperimentalModeButton</name>
|
||||
<message>
|
||||
<source>EXPERIMENTAL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CHILL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InputDialog</name>
|
||||
<message>
|
||||
|
||||
@@ -281,6 +281,17 @@
|
||||
<translation>카메라 시작중</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExperimentalModeButton</name>
|
||||
<message>
|
||||
<source>EXPERIMENTAL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CHILL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InputDialog</name>
|
||||
<message>
|
||||
|
||||
@@ -281,6 +281,17 @@
|
||||
<translation>câmera iniciando</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExperimentalModeButton</name>
|
||||
<message>
|
||||
<source>EXPERIMENTAL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CHILL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InputDialog</name>
|
||||
<message>
|
||||
|
||||
@@ -281,6 +281,17 @@
|
||||
<translation>正在启动相机</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExperimentalModeButton</name>
|
||||
<message>
|
||||
<source>EXPERIMENTAL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CHILL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InputDialog</name>
|
||||
<message>
|
||||
|
||||
@@ -281,6 +281,17 @@
|
||||
<translation>開啟相機中</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExperimentalModeButton</name>
|
||||
<message>
|
||||
<source>EXPERIMENTAL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CHILL MODE ON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InputDialog</name>
|
||||
<message>
|
||||
|
||||
Reference in New Issue
Block a user