Skip to content

Commit

Permalink
ui: offroad experimental mode button (#26498)
Browse files Browse the repository at this point in the history
* 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: 58b84fb
  • Loading branch information
sshane authored Nov 16, 2022
1 parent ac00553 commit dcd22dd
Show file tree
Hide file tree
Showing 22 changed files with 232 additions and 13 deletions.
3 changes: 3 additions & 0 deletions selfdrive/assets/fonts/JetBrainsMono-Medium.ttf
Git LFS file not shown
3 changes: 3 additions & 0 deletions selfdrive/assets/img_couch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions selfdrive/assets/img_experimental.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions selfdrive/assets/img_experimental_grey.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions selfdrive/assets/img_experimental_white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion selfdrive/ui/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 17 additions & 2 deletions selfdrive/ui/qt/home.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion selfdrive/ui/qt/home.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class OffroadHome : public QFrame {
public:
explicit OffroadHome(QWidget* parent = 0);

signals:
void openSettings(int index = 0, const QString &param = "");

private:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
Expand All @@ -45,7 +48,7 @@ class HomeWindow : public QWidget {
explicit HomeWindow(QWidget* parent = 0);

signals:
void openSettings();
void openSettings(int index = 0, const QString &param = "");
void closeSettings();

public slots:
Expand Down
75 changes: 75 additions & 0 deletions selfdrive/ui/qt/offroad/experimental_mode.cc
Original file line number Diff line number Diff line change
@@ -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"));
}
31 changes: 31 additions & 0 deletions selfdrive/ui/qt/offroad/experimental_mode.h
Original file line number Diff line number Diff line change
@@ -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;
};
23 changes: 19 additions & 4 deletions selfdrive/ui/qt/offroad/settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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);

Expand All @@ -108,6 +109,10 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
});
}

void TogglesPanel::expandToggleDescription(const QString &param) {
toggles[param.toStdString()]->showDescription();
}

void TogglesPanel::showEvent(QShowEvent *event) {
updateToggles();
}
Expand Down Expand Up @@ -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 &param) {
panel_widget->setCurrentIndex(index);
nav_btns->buttons()[index]->setChecked(true);
if (!param.isEmpty()) {
emit expandToggleDescription(param);
}
}

SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
Expand Down Expand Up @@ -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)},
};

Expand Down
5 changes: 5 additions & 0 deletions selfdrive/ui/qt/offroad/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class SettingsWindow : public QFrame {

public:
explicit SettingsWindow(QWidget *parent = 0);
void setCurrentPanel(int index, const QString &param = "");

protected:
void showEvent(QShowEvent *event) override;
Expand All @@ -25,6 +26,7 @@ class SettingsWindow : public QFrame {
void closeSettings();
void reviewTrainingGuide();
void showDriverView();
void expandToggleDescription(const QString &param);

private:
QPushButton *sidebar_alert_widget;
Expand Down Expand Up @@ -56,6 +58,9 @@ class TogglesPanel : public ListWidget {
explicit TogglesPanel(SettingsWindow *parent);
void showEvent(QShowEvent *event) override;

public slots:
void expandToggleDescription(const QString &param);

private:
Params params;
std::map<std::string, ParamControl*> toggles;
Expand Down
6 changes: 4 additions & 2 deletions selfdrive/ui/qt/onroad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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});
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}


Expand Down
1 change: 1 addition & 0 deletions selfdrive/ui/qt/onroad.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class AnnotatedCameraWidget : public CameraWidget {
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;
Expand Down
2 changes: 1 addition & 1 deletion selfdrive/ui/qt/sidebar.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Sidebar : public QFrame {
explicit Sidebar(QWidget* parent = 0);

signals:
void openSettings();
void openSettings(int index = 0, const QString &param = "");
void valueChanged();

public slots:
Expand Down
4 changes: 3 additions & 1 deletion selfdrive/ui/qt/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"(
Expand All @@ -64,8 +65,9 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
setAttribute(Qt::WA_NoSystemBackground);
}

void MainWindow::openSettings() {
void MainWindow::openSettings(int index, const QString &param) {
main_layout->setCurrentWidget(settingsWindow);
settingsWindow->setCurrentPanel(index, param);
}

void MainWindow::closeSettings() {
Expand Down
2 changes: 1 addition & 1 deletion selfdrive/ui/qt/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class MainWindow : public QWidget {

private:
bool eventFilter(QObject *obj, QEvent *event) override;
void openSettings();
void openSettings(int index = 0, const QString &param = "");
void closeSettings();

Device device;
Expand Down
11 changes: 11 additions & 0 deletions selfdrive/ui/translations/main_ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
11 changes: 11 additions & 0 deletions selfdrive/ui/translations/main_ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Loading

0 comments on commit dcd22dd

Please sign in to comment.