diff --git a/selfdrive/assets/img_eye_closed.svg b/selfdrive/assets/img_eye_closed.svg
new file mode 100644
index 0000000000..91b229e911
--- /dev/null
+++ b/selfdrive/assets/img_eye_closed.svg
@@ -0,0 +1,5 @@
+
diff --git a/selfdrive/assets/img_eye_open.svg b/selfdrive/assets/img_eye_open.svg
new file mode 100644
index 0000000000..ea6e41ac54
--- /dev/null
+++ b/selfdrive/assets/img_eye_open.svg
@@ -0,0 +1,4 @@
+
diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc
index aa3e523da8..49998cd0b7 100644
--- a/selfdrive/ui/qt/offroad/networking.cc
+++ b/selfdrive/ui/qt/offroad/networking.cc
@@ -82,7 +82,7 @@ void Networking::connectToNetwork(const Network &n) {
} else if (n.security_type == SecurityType::OPEN) {
wifi->connect(n);
} else if (n.security_type == SecurityType::WPA) {
- QString pass = InputDialog::getText("Enter password for \"" + n.ssid + "\"", this, 8);
+ QString pass = InputDialog::getText("Enter password", this, "for \"" + n.ssid + "\"", true, 8);
if (!pass.isEmpty()) {
wifi->connect(n, pass);
}
@@ -92,7 +92,7 @@ void Networking::connectToNetwork(const Network &n) {
void Networking::wrongPassword(const QString &ssid) {
for (Network n : wifi->seen_networks) {
if (n.ssid == ssid) {
- QString pass = InputDialog::getText("Wrong password for \"" + n.ssid +"\"", this, 8);
+ QString pass = InputDialog::getText("Wrong password", this, "for \"" + n.ssid +"\"", true, 8);
if (!pass.isEmpty()) {
wifi->connect(n, pass);
}
@@ -135,7 +135,7 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
// Change tethering password
ButtonControl *editPasswordButton = new ButtonControl("Tethering Password", "EDIT");
connect(editPasswordButton, &ButtonControl::released, [=]() {
- QString pass = InputDialog::getText("Enter new tethering password", this, 8, wifi->getTetheringPassword());
+ QString pass = InputDialog::getText("Enter new tethering password", this, "", true, 8, wifi->getTetheringPassword());
if (!pass.isEmpty()) {
wifi->changeTetheringPassword(pass);
}
diff --git a/selfdrive/ui/qt/widgets/input.cc b/selfdrive/ui/qt/widgets/input.cc
index f3ef138eae..75e418e1bb 100644
--- a/selfdrive/ui/qt/widgets/input.cc
+++ b/selfdrive/ui/qt/widgets/input.cc
@@ -5,6 +5,7 @@
#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/hardware/hw.h"
+
QDialogBase::QDialogBase(QWidget *parent) : QDialog(parent) {
Q_ASSERT(parent != nullptr);
parent->installEventFilter(this);
@@ -17,25 +18,32 @@ bool QDialogBase::eventFilter(QObject *o, QEvent *e) {
return QDialog::eventFilter(o, e);
}
-InputDialog::InputDialog(const QString &prompt_text, QWidget *parent) : QDialogBase(parent) {
+InputDialog::InputDialog(const QString &title, QWidget *parent, const QString &subtitle, bool secret) : QDialogBase(parent) {
main_layout = new QVBoxLayout(this);
- main_layout->setContentsMargins(50, 50, 50, 50);
- main_layout->setSpacing(20);
+ main_layout->setContentsMargins(50, 55, 50, 50);
+ main_layout->setSpacing(0);
// build header
QHBoxLayout *header_layout = new QHBoxLayout();
- label = new QLabel(prompt_text, this);
- label->setStyleSheet(R"(font-size: 75px; font-weight: 500;)");
- header_layout->addWidget(label, 1, Qt::AlignLeft);
+ QVBoxLayout *vlayout = new QVBoxLayout;
+ header_layout->addLayout(vlayout);
+ label = new QLabel(title, this);
+ label->setStyleSheet("font-size: 90px; font-weight: bold;");
+ vlayout->addWidget(label, 1, Qt::AlignTop | Qt::AlignLeft);
+
+ if (!subtitle.isEmpty()) {
+ sublabel = new QLabel(subtitle, this);
+ sublabel->setStyleSheet("font-size: 55px; font-weight: light; color: #BDBDBD;");
+ vlayout->addWidget(sublabel, 1, Qt::AlignTop | Qt::AlignLeft);
+ }
QPushButton* cancel_btn = new QPushButton("Cancel");
+ cancel_btn->setFixedSize(386, 125);
cancel_btn->setStyleSheet(R"(
- padding: 30px;
- padding-right: 45px;
- padding-left: 45px;
- border-radius: 7px;
- font-size: 45px;
+ font-size: 48px;
+ border-radius: 10px;
+ color: #E4E4E4;
background-color: #444444;
)");
header_layout->addWidget(cancel_btn, 0, Qt::AlignRight);
@@ -45,17 +53,52 @@ InputDialog::InputDialog(const QString &prompt_text, QWidget *parent) : QDialogB
main_layout->addLayout(header_layout);
// text box
- main_layout->addSpacing(20);
- line = new QLineEdit();
- line->setStyleSheet(R"(
- border: none;
- background-color: #444444;
- font-size: 80px;
- font-weight: 500;
- padding: 10px;
+ main_layout->addStretch(2);
+
+ QWidget *textbox_widget = new QWidget;
+ textbox_widget->setObjectName("textbox");
+ QHBoxLayout *textbox_layout = new QHBoxLayout(textbox_widget);
+ textbox_layout->setContentsMargins(50, 0, 50, 0);
+
+ textbox_widget->setStyleSheet(R"(
+ #textbox {
+ margin-left: 50px;
+ margin-right: 50px;
+ border: none;
+ border-radius: 0;
+ border-bottom: 3px solid #BDBDBD;
+ }
+ * {
+ font-size: 80px;
+ font-weight: light;
+ background-color: transparent;
+ }
)");
- main_layout->addWidget(line, 1, Qt::AlignTop);
+ line = new QLineEdit();
+ textbox_layout->addWidget(line, 1);
+
+ if (secret) {
+ eye_btn = new QPushButton();
+ eye_btn->setCheckable(true);
+ QObject::connect(eye_btn, &QPushButton::toggled, [=](bool checked) {
+ if (checked) {
+ eye_btn->setIcon(QIcon("../assets/img_eye_closed.svg"));
+ eye_btn->setIconSize(QSize(81, 54));
+ line->setEchoMode(QLineEdit::PasswordEchoOnEdit);
+ } else {
+ eye_btn->setIcon(QIcon("../assets/img_eye_open.svg"));
+ eye_btn->setIconSize(QSize(81, 44));
+ line->setEchoMode(QLineEdit::Normal);
+ }
+ });
+ eye_btn->setChecked(true);
+ textbox_layout->addWidget(eye_btn);
+ }
+
+ main_layout->addWidget(textbox_widget, 0, Qt::AlignBottom);
+
+ main_layout->addSpacing(25);
k = new Keyboard(this);
QObject::connect(k, &Keyboard::emitButton, this, &InputDialog::handleInput);
main_layout->addWidget(k, 2, Qt::AlignBottom);
@@ -68,11 +111,11 @@ InputDialog::InputDialog(const QString &prompt_text, QWidget *parent) : QDialogB
background-color: black;
}
)");
-
}
-QString InputDialog::getText(const QString &prompt, QWidget *parent, int minLength, const QString &defaultText) {
- InputDialog d = InputDialog(prompt, parent);
+QString InputDialog::getText(const QString &prompt, QWidget *parent, const QString &subtitle,
+ bool secret, int minLength, const QString &defaultText) {
+ InputDialog d = InputDialog(prompt, parent, subtitle, secret);
d.line->setText(defaultText);
d.setMinLength(minLength);
const int ret = d.exec();
diff --git a/selfdrive/ui/qt/widgets/input.h b/selfdrive/ui/qt/widgets/input.h
index 287727b9f9..fbef7b7e60 100644
--- a/selfdrive/ui/qt/widgets/input.h
+++ b/selfdrive/ui/qt/widgets/input.h
@@ -9,20 +9,22 @@
#include "selfdrive/ui/qt/widgets/keyboard.h"
+
class QDialogBase : public QDialog {
Q_OBJECT
protected:
QDialogBase(QWidget *parent);
- bool eventFilter(QObject *o, QEvent *e) override;
+ bool eventFilter(QObject *o, QEvent *e) override;
};
class InputDialog : public QDialogBase {
Q_OBJECT
public:
- explicit InputDialog(const QString &prompt_text, QWidget *parent);
- static QString getText(const QString &prompt, QWidget *parent, int minLength = -1, const QString &defaultText = "");
+ explicit InputDialog(const QString &title, QWidget *parent, const QString &subtitle = "", bool secret = false);
+ static QString getText(const QString &title, QWidget *parent, const QString &substitle = "",
+ bool secret = false, int minLength = -1, const QString &defaultText = "");
QString text();
void setMessage(const QString &message, bool clearInputField = true);
void setMinLength(int length);
@@ -33,7 +35,9 @@ private:
QLineEdit *line;
Keyboard *k;
QLabel *label;
+ QLabel *sublabel;
QVBoxLayout *main_layout;
+ QPushButton *eye_btn;
public slots:
int exec() override;