ui: toggle confirmation and dialog redesign (#26331)

* toggle confirmation

* change text

* not for e2e

* get current description

* remove are you sure

* merge rich text and confirmation dialogs

* add some line breaks

* font colour

* fix padding a little

* revert

* updated toggle design
old-commit-hash: 91a1f1a91e8ac321ad2a69c3a44f41464147fc19
This commit is contained in:
Cameron Clough
2022-11-04 15:37:41 -07:00
committed by GitHub
parent cfa80ee10c
commit f46b6ed70a
9 changed files with 97 additions and 91 deletions
+14 -6
View File
@@ -27,49 +27,56 @@
#include "selfdrive/ui/qt/widgets/input.h"
TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
// param, title, desc, icon
std::vector<std::tuple<QString, QString, QString, QString>> toggle_defs{
// param, title, desc, icon, confirm
std::vector<std::tuple<QString, QString, QString, QString, bool>> toggle_defs{
{
"OpenpilotEnabledToggle",
tr("Enable openpilot"),
tr("Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off."),
"../assets/offroad/icon_openpilot.png",
false,
},
{
"IsLdwEnabled",
tr("Enable Lane Departure Warnings"),
tr("Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h)."),
"../assets/offroad/icon_warning.png",
false,
},
{
"IsMetric",
tr("Use Metric System"),
tr("Display speed in km/h instead of mph."),
"../assets/offroad/icon_metric.png",
false,
},
{
"RecordFront",
tr("Record and Upload Driver Camera"),
tr("Upload data from the driver facing camera and help improve the driver monitoring algorithm."),
"../assets/offroad/icon_monitoring.png",
false,
},
{
"DisengageOnAccelerator",
tr("Disengage On Accelerator Pedal"),
tr("When enabled, pressing the accelerator pedal will disengage openpilot."),
"../assets/offroad/icon_disengage_on_accelerator.svg",
false,
},
{
"EndToEndLong",
tr("🌮 End-to-end longitudinal (extremely alpha) 🌮"),
"",
"../assets/offroad/icon_road.png",
false,
},
{
"ExperimentalLongitudinalEnabled",
tr("Experimental openpilot longitudinal control"),
tr("<b>WARNING: openpilot longitudinal control is experimental for this car and will disable AEB.</b>"),
"../assets/offroad/icon_speed_limit.png",
true,
},
#ifdef ENABLE_MAPS
{
@@ -77,19 +84,20 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
tr("Show ETA in 24h Format"),
tr("Use 24h format instead of am/pm"),
"../assets/offroad/icon_metric.png",
false,
},
{
"NavSettingLeftSide",
tr("Show Map on Left Side of UI"),
tr("Show map on left side when in split screen view."),
"../assets/offroad/icon_road.png",
false,
},
#endif
};
for (auto &[param, title, desc, icon] : toggle_defs) {
auto toggle = new ParamControl(param, title, desc, icon, this);
for (auto &[param, title, desc, icon, confirm] : toggle_defs) {
auto toggle = new ParamControl(param, title, desc, icon, confirm, this);
bool locked = params.getBool((param + "Lock").toStdString());
toggle->setEnabled(!locked);
@@ -181,7 +189,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
auto regulatoryBtn = new ButtonControl(tr("Regulatory"), tr("VIEW"), "");
connect(regulatoryBtn, &ButtonControl::clicked, [=]() {
const std::string txt = util::read_file("../assets/offroad/fcc.html");
RichTextDialog::alert(QString::fromStdString(txt), this);
ConfirmationDialog::rich(QString::fromStdString(txt), this);
});
addItem(regulatoryBtn);
}
+14 -2
View File
@@ -7,6 +7,7 @@
#include <QPushButton>
#include "common/params.h"
#include "selfdrive/ui/qt/widgets/input.h"
#include "selfdrive/ui/qt/widgets/toggle.h"
QFrame *horizontal_line(QWidget *parent = nullptr);
@@ -49,6 +50,10 @@ public:
value->setText(val);
}
const QString getDescription() {
return description->text();
}
public slots:
void showDescription() {
description->setVisible(true);
@@ -134,10 +139,17 @@ class ParamControl : public ToggleControl {
Q_OBJECT
public:
ParamControl(const QString &param, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr) : ToggleControl(title, desc, icon, false, parent) {
ParamControl(const QString &param, const QString &title, const QString &desc, const QString &icon, const bool confirm, QWidget *parent = nullptr) : ToggleControl(title, desc, icon, false, parent) {
key = param.toStdString();
QObject::connect(this, &ParamControl::toggleFlipped, [=](bool state) {
params.putBool(key, state);
QString content("<body><h2>" + title + "</h2><br><br>"
"<p style=\"text-align: center; margin: 0 128px;\">" + getDescription() + "</p></body>");
ConfirmationDialog dialog(content, tr("Ok"), tr("Cancel"), true, this);
if (!confirm || !state || dialog.exec()) {
params.putBool(key, state);
} else {
toggle.togglePosition();
}
});
}
+12 -38
View File
@@ -183,17 +183,17 @@ void InputDialog::setMinLength(int length) {
// ConfirmationDialog
ConfirmationDialog::ConfirmationDialog(const QString &prompt_text, const QString &confirm_text, const QString &cancel_text,
QWidget *parent) : QDialogBase(parent) {
const bool rich, QWidget *parent) : QDialogBase(parent) {
QFrame *container = new QFrame(this);
container->setStyleSheet("QFrame { border-radius: 0; background-color: #ECECEC; }");
container->setStyleSheet("QFrame { background-color: #1B1B1B; color: #C9C9C9; }");
QVBoxLayout *main_layout = new QVBoxLayout(container);
main_layout->setContentsMargins(32, 120, 32, 32);
main_layout->setContentsMargins(32, rich ? 32 : 120, 32, 32);
QLabel *prompt = new QLabel(prompt_text, this);
prompt->setWordWrap(true);
prompt->setAlignment(Qt::AlignHCenter);
prompt->setStyleSheet("font-size: 70px; font-weight: bold; color: black;");
main_layout->addWidget(prompt, 1, Qt::AlignTop | Qt::AlignHCenter);
prompt->setAlignment(rich ? Qt::AlignLeft : Qt::AlignHCenter);
prompt->setStyleSheet((rich ? "font-size: 42px; font-weight: light;" : "font-size: 70px; font-weight: bold;") + QString(" margin: 45px;"));
main_layout->addWidget(rich ? (QWidget*)new ScrollView(prompt, this) : (QWidget*)prompt, 1, Qt::AlignTop);
// cancel + confirm buttons
QHBoxLayout *btn_layout = new QHBoxLayout();
@@ -213,49 +213,23 @@ ConfirmationDialog::ConfirmationDialog(const QString &prompt_text, const QString
}
QVBoxLayout *outer_layout = new QVBoxLayout(this);
outer_layout->setContentsMargins(210, 170, 210, 170);
int margin = rich ? 100 : 200;
outer_layout->setContentsMargins(margin, margin, margin, margin);
outer_layout->addWidget(container);
}
bool ConfirmationDialog::alert(const QString &prompt_text, QWidget *parent) {
ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Ok"), "", parent);
ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Ok"), "", false, parent);
return d.exec();
}
bool ConfirmationDialog::confirm(const QString &prompt_text, QWidget *parent) {
ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Ok"), tr("Cancel"), parent);
ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Ok"), tr("Cancel"), false, parent);
return d.exec();
}
// RichTextDialog
RichTextDialog::RichTextDialog(const QString &prompt_text, const QString &btn_text,
QWidget *parent) : QDialogBase(parent) {
QFrame *container = new QFrame(this);
container->setStyleSheet("QFrame { background-color: #1B1B1B; }");
QVBoxLayout *main_layout = new QVBoxLayout(container);
main_layout->setContentsMargins(32, 32, 32, 32);
QLabel *prompt = new QLabel(prompt_text, this);
prompt->setWordWrap(true);
prompt->setAlignment(Qt::AlignLeft);
prompt->setTextFormat(Qt::RichText);
prompt->setStyleSheet("font-size: 42px; font-weight: light; color: #C9C9C9; margin: 45px;");
main_layout->addWidget(new ScrollView(prompt, this), 1, Qt::AlignTop);
// confirm button
QPushButton* confirm_btn = new QPushButton(btn_text);
main_layout->addWidget(confirm_btn);
QObject::connect(confirm_btn, &QPushButton::clicked, this, &QDialog::accept);
QVBoxLayout *outer_layout = new QVBoxLayout(this);
outer_layout->setContentsMargins(100, 100, 100, 100);
outer_layout->addWidget(container);
}
bool RichTextDialog::alert(const QString &prompt_text, QWidget *parent) {
auto d = RichTextDialog(prompt_text, tr("Ok"), parent);
bool ConfirmationDialog::rich(const QString &prompt_text, QWidget *parent) {
ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Ok"), "", true, parent);
return d.exec();
}
+2 -10
View File
@@ -55,18 +55,10 @@ class ConfirmationDialog : public QDialogBase {
public:
explicit ConfirmationDialog(const QString &prompt_text, const QString &confirm_text,
const QString &cancel_text, QWidget* parent);
const QString &cancel_text, const bool rich, QWidget* parent);
static bool alert(const QString &prompt_text, QWidget *parent);
static bool confirm(const QString &prompt_text, QWidget *parent);
};
// larger ConfirmationDialog for rich text
class RichTextDialog : public QDialogBase {
Q_OBJECT
public:
explicit RichTextDialog(const QString &prompt_text, const QString &btn_text, QWidget* parent);
static bool alert(const QString &prompt_text, QWidget *parent);
static bool rich(const QString &prompt_text, QWidget *parent);
};
class MultiOptionDialog : public QDialogBase {
+11 -7
View File
@@ -463,6 +463,17 @@ location set</source>
<translation>「connect.comma.ai」をホーム画面に追加して、アプリのように使うことができます。</translation>
</message>
</context>
<context>
<name>ParamControl</name>
<message>
<source>Ok</source>
<translation type="unfinished">OK</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">キャンセル</translation>
</message>
</context>
<context>
<name>PrimeAdWidget</name>
<message>
@@ -585,13 +596,6 @@ location set</source>
<translation>「data」パーティションをマウントできません。「確認」ボタンを押すとデバイスが初期化されます。</translation>
</message>
</context>
<context>
<name>RichTextDialog</name>
<message>
<source>Ok</source>
<translation>OK</translation>
</message>
</context>
<context>
<name>SettingsWindow</name>
<message>
+11 -7
View File
@@ -463,6 +463,17 @@ location set</source>
<translation>connect.comma.ai을 앱처럼 사용하려면 홈 화면에 바로가기를 만드십시오</translation>
</message>
</context>
<context>
<name>ParamControl</name>
<message>
<source>Ok</source>
<translation type="unfinished">확인</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">취소</translation>
</message>
</context>
<context>
<name>PrimeAdWidget</name>
<message>
@@ -585,13 +596,6 @@ location set</source>
<translation>데이터 파티션을 마운트할 수 없습니다. 확인 버튼을 눌러 장치를 리셋합니다.</translation>
</message>
</context>
<context>
<name>RichTextDialog</name>
<message>
<source>Ok</source>
<translation>확인</translation>
</message>
</context>
<context>
<name>SettingsWindow</name>
<message>
+11 -7
View File
@@ -464,6 +464,17 @@ trabalho definido</translation>
<translation>Salve connect.comma.ai como sua página inicial para utilizar como um app</translation>
</message>
</context>
<context>
<name>ParamControl</name>
<message>
<source>Ok</source>
<translation type="unfinished">OK</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">Cancelar</translation>
</message>
</context>
<context>
<name>PrimeAdWidget</name>
<message>
@@ -589,13 +600,6 @@ trabalho definido</translation>
<translation>Não foi possível montar a partição de dados. Pressione confirmar para resetar seu dispositivo.</translation>
</message>
</context>
<context>
<name>RichTextDialog</name>
<message>
<source>Ok</source>
<translation>Ok</translation>
</message>
</context>
<context>
<name>SettingsWindow</name>
<message>
+11 -7
View File
@@ -461,6 +461,17 @@ location set</source>
<translation>将 connect.comma.ai 收藏到您的主屏幕,以便像应用程序一样使用它</translation>
</message>
</context>
<context>
<name>ParamControl</name>
<message>
<source>Ok</source>
<translation type="unfinished">好的</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">取消</translation>
</message>
</context>
<context>
<name>PrimeAdWidget</name>
<message>
@@ -583,13 +594,6 @@ location set</source>
<translation>无法挂载数据分区。 确认以重置您的设备。</translation>
</message>
</context>
<context>
<name>RichTextDialog</name>
<message>
<source>Ok</source>
<translation>好的</translation>
</message>
</context>
<context>
<name>SettingsWindow</name>
<message>
+11 -7
View File
@@ -463,6 +463,17 @@ location set</source>
<translation>將 connect.comma.ai 加入您的主屏幕,以便像手機 App 一樣使用它</translation>
</message>
</context>
<context>
<name>ParamControl</name>
<message>
<source>Ok</source>
<translation type="unfinished">確定</translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">取消</translation>
</message>
</context>
<context>
<name>PrimeAdWidget</name>
<message>
@@ -585,13 +596,6 @@ location set</source>
<translation>無法掛載數據分區。請按確認重置您的設備。</translation>
</message>
</context>
<context>
<name>RichTextDialog</name>
<message>
<source>Ok</source>
<translation>確定</translation>
</message>
</context>
<context>
<name>SettingsWindow</name>
<message>