mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-08-05 08:16:06 +08:00
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: 91a1f1a91e
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 ¶m, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr) : ToggleControl(title, desc, icon, false, parent) {
|
||||
ParamControl(const QString ¶m, 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user