From 2fefa32476a91f10b7292c1d04d2f3a96d19e7cd Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 20 Sep 2021 06:14:54 +0800 Subject: [PATCH] UI: new class ListWidget (#21273) * ListWidget * continue * remove function horizontal_line * cleanup * default spacing 25 * fix networkpanel margin on EON * solid expanding * 0 width * cleanup * apply reviews * remove function addLayout,make it looks like QLIstWidget * rename addWidget to addItem * rebase master * rebase master * merge master * cleanup * fixed title bar position * no flash while folding * cleanup Co-authored-by: Adeeb Shihadeh old-commit-hash: abffc8b2ade75eb9365552cb25a1885442d7e011 --- selfdrive/ui/qt/offroad/networking.cc | 31 +++++------ selfdrive/ui/qt/offroad/settings.cc | 75 +++++++++++---------------- selfdrive/ui/qt/offroad/settings.h | 6 +-- selfdrive/ui/qt/widgets/controls.cc | 6 ++- selfdrive/ui/qt/widgets/controls.h | 36 ++++++++++--- 5 files changed, 80 insertions(+), 74 deletions(-) diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc index e317b25b9a..fa257587fc 100644 --- a/selfdrive/ui/qt/offroad/networking.cc +++ b/selfdrive/ui/qt/offroad/networking.cc @@ -10,6 +10,7 @@ #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" +#include "selfdrive/ui/qt/widgets/controls.h" #include "selfdrive/ui/qt/widgets/scrollview.h" @@ -123,11 +124,11 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid connect(back, &QPushButton::clicked, [=]() { emit backPress(); }); main_layout->addWidget(back, 0, Qt::AlignLeft); + ListWidget *list = new ListWidget(this); // Enable tethering layout tetheringToggle = new ToggleControl("Enable Tethering", "", "", wifi->isTetheringEnabled()); - main_layout->addWidget(tetheringToggle); + list->addItem(tetheringToggle); QObject::connect(tetheringToggle, &ToggleControl::toggleFlipped, this, &AdvancedNetworking::toggleTethering); - main_layout->addWidget(horizontal_line(), 0); // Change tethering password ButtonControl *editPasswordButton = new ButtonControl("Tethering Password", "EDIT"); @@ -137,19 +138,15 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid wifi->changeTetheringPassword(pass); } }); - main_layout->addWidget(editPasswordButton, 0); - main_layout->addWidget(horizontal_line(), 0); + list->addItem(editPasswordButton); // IP address ipLabel = new LabelControl("IP Address", wifi->ipv4_address); - main_layout->addWidget(ipLabel, 0); - main_layout->addWidget(horizontal_line(), 0); + list->addItem(ipLabel); // SSH keys - main_layout->addWidget(new SshToggle()); - main_layout->addWidget(horizontal_line(), 0); - main_layout->addWidget(new SshControl()); - main_layout->addWidget(horizontal_line(), 0); + list->addItem(new SshToggle()); + list->addItem(new SshControl()); // Roaming toggle const bool roamingEnabled = params.getBool("GsmRoaming"); @@ -159,8 +156,9 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid params.putBool("GsmRoaming", state); wifi->setRoamingEnabled(state); }); - main_layout->addWidget(roamingToggle); + list->addItem(roamingToggle); + main_layout->addWidget(list); main_layout->addStretch(1); } @@ -253,7 +251,7 @@ void WifiUI::refresh() { std::sort(sortedNetworks.begin(), sortedNetworks.end(), compare_by_strength); // add networks - int i = 0; + ListWidget *list = new ListWidget(this); for (Network &network : sortedNetworks) { QHBoxLayout *hlayout = new QHBoxLayout; hlayout->setContentsMargins(44, 0, 73, 0); @@ -309,13 +307,8 @@ void WifiUI::refresh() { strength->setPixmap(strengths[std::clamp((int)round(network.strength / 33.), 0, 3)]); hlayout->addWidget(strength, 0, Qt::AlignRight); - main_layout->addLayout(hlayout); - - // Don't add the last horizontal line - if (i+1 < wifi->seenNetworks.size()) { - main_layout->addWidget(horizontal_line(), 0); - } - i++; + list->addItem(hlayout); } + main_layout->addWidget(list); main_layout->addStretch(1); } diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index c0fa98f326..1a5d823312 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -25,38 +25,34 @@ #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" -TogglesPanel::TogglesPanel(QWidget *parent) : QWidget(parent) { - QVBoxLayout *main_layout = new QVBoxLayout(this); - - QList toggles; - - toggles.append(new ParamControl("OpenpilotEnabledToggle", +TogglesPanel::TogglesPanel(QWidget *parent) : ListWidget(parent) { + addItem(new ParamControl("OpenpilotEnabledToggle", "Enable openpilot", "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", this)); - toggles.append(new ParamControl("IsLdwEnabled", + addItem(new ParamControl("IsLdwEnabled", "Enable Lane Departure Warnings", "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 31mph (50kph).", "../assets/offroad/icon_warning.png", this)); - toggles.append(new ParamControl("IsRHD", + addItem(new ParamControl("IsRHD", "Enable Right-Hand Drive", "Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat.", "../assets/offroad/icon_openpilot_mirrored.png", this)); - toggles.append(new ParamControl("IsMetric", + addItem(new ParamControl("IsMetric", "Use Metric System", "Display speed in km/h instead of mp/h.", "../assets/offroad/icon_metric.png", this)); - toggles.append(new ParamControl("CommunityFeaturesToggle", + addItem(new ParamControl("CommunityFeaturesToggle", "Enable Community Features", "Use features from the open source community that are not maintained or supported by comma.ai and have not been confirmed to meet the standard safety model. These features include community supported cars and community supported hardware. Be extra cautious when using these features", "../assets/offroad/icon_shell.png", this)); - toggles.append(new ParamControl("UploadRaw", + addItem(new ParamControl("UploadRaw", "Upload Raw Logs", "Upload full logs and full resolution video by default while on WiFi. If not enabled, individual logs can be marked for upload at my.comma.ai/useradmin.", "../assets/offroad/icon_network.png", @@ -67,15 +63,15 @@ TogglesPanel::TogglesPanel(QWidget *parent) : QWidget(parent) { "Upload data from the driver facing camera and help improve the driver monitoring algorithm.", "../assets/offroad/icon_monitoring.png", this); - toggles.append(record_toggle); - toggles.append(new ParamControl("EndToEndToggle", + addItem(record_toggle); + addItem(new ParamControl("EndToEndToggle", "\U0001f96c Disable use of lanelines (Alpha) \U0001f96c", "In this mode openpilot will ignore lanelines and just drive how it thinks a human would.", "../assets/offroad/icon_road.png", this)); #ifdef ENABLE_MAPS - toggles.append(new ParamControl("NavSettingTime24h", + addItem(new ParamControl("NavSettingTime24h", "Show ETA in 24h format", "Use 24h format instead of am/pm", "../assets/offroad/icon_metric.png", @@ -84,23 +80,15 @@ TogglesPanel::TogglesPanel(QWidget *parent) : QWidget(parent) { bool record_lock = Params().getBool("RecordFrontLock"); record_toggle->setEnabled(!record_lock); - - for(ParamControl *toggle : toggles) { - if(main_layout->count() != 0) { - main_layout->addWidget(horizontal_line()); - } - main_layout->addWidget(toggle); - } } -DevicePanel::DevicePanel(QWidget* parent) : QWidget(parent) { - QVBoxLayout *main_layout = new QVBoxLayout(this); +DevicePanel::DevicePanel(QWidget* parent) : ListWidget(parent) { + setSpacing(50); Params params = Params(); - main_layout->addWidget(new LabelControl("Dongle ID", getDongleId().value_or("N/A"))); - main_layout->addWidget(horizontal_line()); + addItem(new LabelControl("Dongle ID", getDongleId().value_or("N/A"))); QString serial = QString::fromStdString(params.get("HardwareSerial", false)); - main_layout->addWidget(new LabelControl("Serial", serial)); + addItem(new LabelControl("Serial", serial)); // offroad-only buttons @@ -158,9 +146,8 @@ DevicePanel::DevicePanel(QWidget* parent) : QWidget(parent) { for (auto btn : {dcamBtn, resetCalibBtn, retrainingBtn, regulatoryBtn}) { if (btn) { - main_layout->addWidget(horizontal_line()); connect(parent, SIGNAL(offroadTransition(bool)), btn, SLOT(setEnabled(bool))); - main_layout->addWidget(btn); + addItem(btn); } } @@ -196,10 +183,10 @@ DevicePanel::DevicePanel(QWidget* parent) : QWidget(parent) { #poweroff_btn { background-color: #E22C2C; } #poweroff_btn:pressed { background-color: #FF2424; } )"); - main_layout->addLayout(power_layout); + addItem(power_layout); } -SoftwarePanel::SoftwarePanel(QWidget* parent) : QWidget(parent) { +SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) { gitBranchLbl = new LabelControl("Git Branch"); gitCommitLbl = new LabelControl("Git Commit"); osVersionLbl = new LabelControl("OS Version"); @@ -216,12 +203,6 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : QWidget(parent) { std::system("pkill -1 -f selfdrive.updated"); }); - QVBoxLayout *main_layout = new QVBoxLayout(this); - QWidget *widgets[] = {versionLbl, lastUpdateLbl, updateBtn, gitBranchLbl, gitCommitLbl, osVersionLbl}; - for (int i = 0; i < std::size(widgets); ++i) { - main_layout->addWidget(widgets[i]); - main_layout->addWidget(horizontal_line()); - } auto uninstallBtn = new ButtonControl("Uninstall " + getBrand(), "UNINSTALL"); connect(uninstallBtn, &ButtonControl::clicked, [=]() { @@ -230,7 +211,11 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : QWidget(parent) { } }); connect(parent, SIGNAL(offroadTransition(bool)), uninstallBtn, SLOT(setEnabled(bool))); - main_layout->addWidget(uninstallBtn); + + QWidget *widgets[] = {versionLbl, lastUpdateLbl, updateBtn, gitBranchLbl, gitCommitLbl, osVersionLbl, uninstallBtn}; + for (QWidget* w : widgets) { + addItem(w); + } fs_watch = new QFileSystemWatcher(this); QObject::connect(fs_watch, &QFileSystemWatcher::fileChanged, [=](const QString path) { @@ -269,24 +254,24 @@ QWidget * network_panel(QWidget * parent) { #ifdef QCOM QWidget *w = new QWidget(parent); QVBoxLayout *layout = new QVBoxLayout(w); - layout->setSpacing(30); + layout->setContentsMargins(50, 0, 50, 0); + ListWidget *list = new ListWidget(); + list->setSpacing(30); // wifi + tethering buttons auto wifiBtn = new ButtonControl("WiFi Settings", "OPEN"); QObject::connect(wifiBtn, &ButtonControl::clicked, [=]() { HardwareEon::launch_wifi(); }); - layout->addWidget(wifiBtn); - layout->addWidget(horizontal_line()); + list->addItem(wifiBtn); auto tetheringBtn = new ButtonControl("Tethering Settings", "OPEN"); QObject::connect(tetheringBtn, &ButtonControl::clicked, [=]() { HardwareEon::launch_tethering(); }); - layout->addWidget(tetheringBtn); - layout->addWidget(horizontal_line()); + list->addItem(tetheringBtn); // SSH key management - layout->addWidget(new SshToggle()); - layout->addWidget(horizontal_line()); - layout->addWidget(new SshControl()); + list->addItem(new SshToggle()); + list->addItem(new SshControl()); + layout->addWidget(list); layout->addStretch(1); #else Networking *w = new Networking(parent); diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index 9670d8d907..f922463366 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -13,7 +13,7 @@ // ********** settings window + top-level panels ********** -class DevicePanel : public QWidget { +class DevicePanel : public ListWidget { Q_OBJECT public: explicit DevicePanel(QWidget* parent = nullptr); @@ -22,13 +22,13 @@ signals: void showDriverView(); }; -class TogglesPanel : public QWidget { +class TogglesPanel : public ListWidget { Q_OBJECT public: explicit TogglesPanel(QWidget *parent = nullptr); }; -class SoftwarePanel : public QWidget { +class SoftwarePanel : public ListWidget { Q_OBJECT public: explicit SoftwarePanel(QWidget* parent = nullptr); diff --git a/selfdrive/ui/qt/widgets/controls.cc b/selfdrive/ui/qt/widgets/controls.cc index 2cc68be8b7..d103db40d9 100644 --- a/selfdrive/ui/qt/widgets/controls.cc +++ b/selfdrive/ui/qt/widgets/controls.cc @@ -18,6 +18,8 @@ QFrame *horizontal_line(QWidget *parent) { } AbstractControl::AbstractControl(const QString &title, const QString &desc, const QString &icon, QWidget *parent) : QFrame(parent) { + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setMargin(0); @@ -36,7 +38,8 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons // title title_label = new QPushButton(title); - title_label->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left;"); + title_label->setFixedHeight(120); + title_label->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left"); hlayout->addWidget(title_label); main_layout->addLayout(hlayout); @@ -57,6 +60,7 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons description->setVisible(!description->isVisible()); }); } + main_layout->addStretch(); } void AbstractControl::hideEvent(QHideEvent *e) { diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index bfa25ce83c..b793326056 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "selfdrive/common/params.h" @@ -47,12 +48,6 @@ protected: AbstractControl(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr); void hideEvent(QHideEvent *e) override; - QSize minimumSizeHint() const override { - QSize size = QFrame::minimumSizeHint(); - size.setHeight(120); - return size; - }; - QHBoxLayout *hlayout; QPushButton *title_label; QLabel *description = nullptr; @@ -137,3 +132,32 @@ private: std::string key; Params params; }; + +class ListWidget : public QWidget { + Q_OBJECT + public: + explicit ListWidget(QWidget *parent = 0) : QWidget(parent), outer_layout(this) { + outer_layout.setMargin(0); + outer_layout.setSpacing(0); + outer_layout.addLayout(&inner_layout); + inner_layout.setMargin(0); + inner_layout.setSpacing(25); // default spacing is 25 + outer_layout.addStretch(); + } + inline void addItem(QWidget *w) { inner_layout.addWidget(w); } + inline void addItem(QLayout *layout) { inner_layout.addLayout(layout); } + inline void setSpacing(int spacing) { inner_layout.setSpacing(spacing); } + +private: + void paintEvent(QPaintEvent *) override { + QPainter p(this); + p.setPen(Qt::gray); + for (int i = 0; i < inner_layout.count() - 1; ++i) { + QRect r = inner_layout.itemAt(i)->geometry(); + int bottom = r.bottom() + inner_layout.spacing() / 2; + p.drawLine(r.left() + 40, bottom, r.right() - 40, bottom); + } + } + QVBoxLayout outer_layout; + QVBoxLayout inner_layout; +};