diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 025711510f..b1212a68c2 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -225,7 +225,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { // setup two main layouts QVBoxLayout *sidebar_layout = new QVBoxLayout(); sidebar_layout->setMargin(0); - panel_layout = new QStackedLayout(); + panel_widget = new QStackedWidget(); // close button QPushButton *close_btn = new QPushButton("X"); @@ -272,9 +272,9 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { nav_btns->addButton(btn); sidebar_layout->addWidget(btn, 0, Qt::AlignRight); - panel_layout->addWidget(panel); + panel_widget->addWidget(panel); QObject::connect(btn, &QPushButton::released, [=, w = panel]() { - panel_layout->setCurrentWidget(w); + panel_widget->setCurrentWidget(w); }); } qobject_cast(nav_btns->buttons()[0])->setChecked(true); @@ -288,20 +288,25 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { sidebar_widget->setFixedWidth(500); settings_layout->addWidget(sidebar_widget); - - panel_frame = new QFrame; - panel_frame->setLayout(panel_layout); + panel_frame = new QScrollArea; + panel_frame->setWidget(panel_widget); + panel_frame->setWidgetResizable(true); + panel_frame->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + panel_frame->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); panel_frame->setStyleSheet(R"( - QFrame { - border-radius: 30px; - background-color: #292929; - } - * { - background-color: none; - } + border-radius: 30px; + background-color: #292929; )"); settings_layout->addWidget(panel_frame); + // setup panel scrolling + QScroller *scroller = QScroller::scroller(panel_frame); + auto sp = scroller->scrollerProperties(); + sp.setScrollMetric(QScrollerProperties::FrameRate, QVariant::fromValue(QScrollerProperties::Fps30)); + sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); + scroller->setScrollerProperties(sp); + scroller->grabGesture(panel_frame->viewport(), QScroller::LeftMouseButtonGesture); + setLayout(settings_layout); setStyleSheet(R"( * { diff --git a/selfdrive/ui/qt/offroad/settings.hpp b/selfdrive/ui/qt/offroad/settings.hpp index 711b4548eb..9c6fe9840d 100644 --- a/selfdrive/ui/qt/offroad/settings.hpp +++ b/selfdrive/ui/qt/offroad/settings.hpp @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include "selfdrive/ui/qt/widgets/controls.hpp" @@ -41,6 +42,6 @@ private: QPushButton *sidebar_alert_widget; QWidget *sidebar_widget; QButtonGroup *nav_btns; - QStackedLayout *panel_layout; - QFrame* panel_frame; + QStackedWidget *panel_widget; + QScrollArea *panel_frame; }; diff --git a/selfdrive/ui/qt/widgets/controls.cc b/selfdrive/ui/qt/widgets/controls.cc index b702a6ec41..958cffb4bf 100644 --- a/selfdrive/ui/qt/widgets/controls.cc +++ b/selfdrive/ui/qt/widgets/controls.cc @@ -14,7 +14,9 @@ QFrame *horizontal_line(QWidget *parent) { return line; } -AbstractControl::AbstractControl(const QString &title, const QString &desc, const QString &icon) : QFrame() { +AbstractControl::AbstractControl(const QString &title, const QString &desc, const QString &icon, QWidget *parent) : QFrame(parent) { + QVBoxLayout *vlayout = new QVBoxLayout(); + hlayout = new QHBoxLayout; hlayout->setMargin(0); hlayout->setSpacing(50); @@ -29,9 +31,25 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons } // title - title_label = new QLabel(title); - title_label->setStyleSheet("font-size: 50px; font-weight: 400;"); + title_label = new QPushButton(title); + title_label->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left; background: none;"); hlayout->addWidget(title_label); - setLayout(hlayout); + vlayout->addLayout(hlayout); + + // description + if (!desc.isEmpty()) { + description = new QLabel(desc); + description->setContentsMargins(40, 20, 40, 20); + description->setStyleSheet("font-size: 40px; color:grey"); + description->setWordWrap(true); + description->setVisible(false); + vlayout->addWidget(description); + + connect(title_label, &QPushButton::clicked, [=]() { + description->setVisible(!description->isVisible()); + }); + } + + setLayout(vlayout); } diff --git a/selfdrive/ui/qt/widgets/controls.hpp b/selfdrive/ui/qt/widgets/controls.hpp index 3fe9251107..afc8754001 100644 --- a/selfdrive/ui/qt/widgets/controls.hpp +++ b/selfdrive/ui/qt/widgets/controls.hpp @@ -15,16 +15,17 @@ class AbstractControl : public QFrame { Q_OBJECT protected: - AbstractControl(const QString &title, const QString &desc = "", const QString &icon = ""); + AbstractControl(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr); QSize minimumSizeHint() const override { QSize size = QFrame::minimumSizeHint(); - size.setHeight(120); + size.setHeight(150); return size; }; QHBoxLayout *hlayout; - QLabel *title_label; + QPushButton *title_label; + QLabel *description = nullptr; }; // widget to display a value @@ -32,7 +33,7 @@ class LabelControl : public AbstractControl { Q_OBJECT public: - LabelControl(const QString &title, const QString &text, const QString &desc = "") : AbstractControl(title, desc, "") { + LabelControl(const QString &title, const QString &text, const QString &desc = "", QWidget *parent = nullptr) : AbstractControl(title, desc, "", parent) { label.setText(text); label.setAlignment(Qt::AlignRight | Qt::AlignVCenter); hlayout->addWidget(&label); @@ -49,7 +50,7 @@ class ButtonControl : public AbstractControl { public: template - ButtonControl(const QString &title, const QString &text, const QString &desc, Functor functor, const QString &icon = "") : AbstractControl(title, desc, icon) { + ButtonControl(const QString &title, const QString &text, const QString &desc, Functor functor, const QString &icon = "", QWidget *parent = nullptr) : AbstractControl(title, desc, icon, parent) { btn.setText(text); btn.setStyleSheet(R"( padding: 0; @@ -73,7 +74,7 @@ class ToggleControl : public AbstractControl { Q_OBJECT public: - ToggleControl(const QString &title, const QString &desc = "", const QString &icon = "", const bool state = false) : AbstractControl(title, desc, icon) { + ToggleControl(const QString &title, const QString &desc = "", const QString &icon = "", const bool state = false, QWidget *parent = nullptr) : AbstractControl(title, desc, icon, parent) { toggle.setFixedSize(150, 100); if (state) { toggle.togglePosition(); @@ -96,7 +97,7 @@ class ParamControl : public ToggleControl { Q_OBJECT public: - ParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon) : ToggleControl(title, desc, icon) { + ParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr) : ToggleControl(title, desc, icon, parent) { // set initial state from param if (Params().read_db_bool(param.toStdString().c_str())) { toggle.togglePosition();