diff --git a/selfdrive/assets/offroad/icon_plus.png b/selfdrive/assets/offroad/icon_plus.png new file mode 100644 index 000000000..92b448b0b Binary files /dev/null and b/selfdrive/assets/offroad/icon_plus.png differ diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index aebf934f2..936d27361 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -294,3 +294,136 @@ public: setLayout(l); } }; + +#include +class SpinBoxControl : public AbstractControl { + Q_OBJECT + +public: + SpinBoxControl(const QString &title, const QString &desc = "", const QString &icon = "", const int val = 0, QWidget *parent = nullptr) : AbstractControl(title, desc, icon, parent) { + spinbox.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + spinbox.setAlignment(Qt::AlignCenter); + spinbox.setStyleSheet(R"( + QSpinBox { + width: 300px; + height: 80px; + padding: 0px; + border-radius:40px; + font-size: 36px; + } + QSpinBox::up-button { + subcontrol-origin: margin; + subcontrol-position: center right; + image: url(../assets/offroad/icon_plus.png); + right: 1px; + height: 80px; + width: 80px; + } + QSpinBox::down-button { + subcontrol-origin: margin; + subcontrol-position: center left; + image: url(../assets/offroad/icon_minus.png); + left: 1px; + height: 80px; + width: 80px; + } + )"); + + hlayout->addWidget(&spinbox); + QObject::connect(&spinbox, QOverload::of(&QSpinBox::valueChanged), this, &SpinBoxControl::valChanged); + } + +signals: + void valChanged(int val); + +protected: + QSpinBox spinbox; +}; + +class ParamSpinBoxControl : public SpinBoxControl { + Q_OBJECT + +public: + ParamSpinBoxControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, const int minimum = 0, const int maximum = 100, const int step = 1, const QString suffix = "", const QString minText = "", QWidget *parent = nullptr) : SpinBoxControl(title, desc, icon, 0, parent) { + spinbox.setRange(minimum, maximum); + spinbox.setSingleStep(step); + spinbox.setSuffix(suffix); + spinbox.setSpecialValueText(minText); + + std::string str_val = Params().get(param.toStdString().c_str()); + if (str_val != "") { + int val = std::stoi(str_val); + spinbox.setValue(val); + QObject::connect(this, &SpinBoxControl::valChanged, [=](int val) { + Params().put(param.toStdString(), std::to_string(val)); + }); + } + } +}; + +class DoubleSpinBoxControl : public AbstractControl { + Q_OBJECT + +public: + DoubleSpinBoxControl(const QString &title, const QString &desc = "", const QString &icon = "", const double val = 0.0, QWidget *parent = nullptr) : AbstractControl(title, desc, icon, parent) { + spinbox.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + spinbox.setAlignment(Qt::AlignCenter); + spinbox.setStyleSheet(R"( + QDoubleSpinBox { + width: 300px; + height: 80px; + padding: 0px; + border-radius:40px; + font-size: 36px; + } + QDoubleSpinBox::up-button { + subcontrol-origin: margin; + subcontrol-position: center right; + image: url(../assets/offroad/icon_plus.png); + right: 1px; + height: 80px; + width: 80px; + } + QDoubleSpinBox::down-button { + subcontrol-origin: margin; + subcontrol-position: center left; + image: url(../assets/offroad/icon_minus.png); + left: 1px; + height: 80px; + width: 80px; + } + )"); + + hlayout->addWidget(&spinbox); + QObject::connect(&spinbox, QOverload::of(&QDoubleSpinBox::valueChanged), this, &DoubleSpinBoxControl::valChanged); + } + +signals: + void valChanged(double val); + +protected: + QDoubleSpinBox spinbox; +}; + +class ParamDoubleSpinBoxControl : public DoubleSpinBoxControl { + Q_OBJECT + +public: + ParamDoubleSpinBoxControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, const double minimum = 0.0, const double maximum = 100.0, const double step = 1.0, const QString suffix = "", const QString minText = "", QWidget *parent = nullptr) : DoubleSpinBoxControl(title, desc, icon, 0.0, parent) { + spinbox.setRange(minimum, maximum); + spinbox.setSingleStep(step); + spinbox.setSuffix(suffix); + spinbox.setSpecialValueText(minText); + + std::string str_val = Params().get(param.toStdString().c_str()); + if (str_val != "") { + double val = std::stod(str_val); + spinbox.setValue(val); + + QObject::connect(this, &DoubleSpinBoxControl::valChanged, [=](double val) { + Params().put(param.toStdString(), std::to_string(val)); + }); + } + } + void setValue(float v) { spinbox.setValue(v); } +};