From 3bfc92bafc10b14d951ee1691a0a1ebcb559e2b7 Mon Sep 17 00:00:00 2001 From: grekiki Date: Fri, 27 Nov 2020 17:55:07 +0100 Subject: [PATCH] Qt ui: improve toggle buttons (#2639) * works, but is still a bit ugly * works * looks much better now * fix compile error * reduce diff * write to params * cleanup old-commit-hash: 61884d2c502930c95a612ba3966dd77ec2749f61 --- selfdrive/ui/SConscript | 3 +- selfdrive/ui/qt/offroad/settings.cc | 35 +++++++++------ selfdrive/ui/qt/offroad/toggle.cc | 66 +++++++++++++++++++++++++++++ selfdrive/ui/qt/offroad/toggle.hpp | 34 +++++++++++++++ 4 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 selfdrive/ui/qt/offroad/toggle.cc create mode 100644 selfdrive/ui/qt/offroad/toggle.hpp diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index ff8693fe40..519b1919fd 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -71,9 +71,10 @@ else: else: qt_libs += [f"Qt5{m}" for m in qt_modules] + qt_env.Library("qt_widgets", ["qt/qt_window.cc", "qt/qt_sound.cc", "qt/offroad/keyboard.cc", "qt/offroad/input_field.cc", - "qt/offroad/wifi.cc", "qt/offroad/wifiManager.cc"], + "qt/offroad/wifi.cc", "qt/offroad/wifiManager.cc", "qt/offroad/toggle.cc"], LIBS=qt_libs) qt_libs.append("qt_widgets") diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index c0dba8f247..550fdb4aea 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -13,6 +13,7 @@ #include "wifi.hpp" #include "settings.hpp" #include "input_field.hpp" +#include "toggle.hpp" #include "common/params.h" #include "common/utilpp.h" @@ -21,8 +22,8 @@ const int SIDEBAR_WIDTH = 400; ParamsToggle::ParamsToggle(QString param, QString title, QString description, QString icon_path, QWidget *parent): QFrame(parent) , param(param) { QHBoxLayout *hlayout = new QHBoxLayout; - QVBoxLayout *vlayout = new QVBoxLayout; - + + //Parameter image hlayout->addSpacing(25); if (icon_path.length()){ QPixmap pix(icon_path); @@ -34,21 +35,29 @@ ParamsToggle::ParamsToggle(QString param, QString title, QString description, QS hlayout->addSpacing(100); } hlayout->addSpacing(25); - - checkbox = new QCheckBox(title); - QLabel *label = new QLabel(description); + + //Name of the parameter + QLabel *label = new QLabel(title); label->setWordWrap(true); + //toggle switch + Toggle* toggle_switch = new Toggle(this); + QSizePolicy switch_policy(QSizePolicy::Preferred, QSizePolicy::Preferred); + switch_policy.setHorizontalStretch(1); + toggle_switch->setSizePolicy(switch_policy); + toggle_switch->setFixedWidth(120); + toggle_switch->setFixedHeight(50); + // TODO: show descriptions on tap - //vlayout->addSpacing(50); - vlayout->addWidget(checkbox); - //vlayout->addWidget(label); - //vlayout->addSpacing(50); - hlayout->addLayout(vlayout); + hlayout->addWidget(label); + hlayout->addSpacing(50); + hlayout->addWidget(toggle_switch); + hlayout->addSpacing(50); setLayout(hlayout); - - checkbox->setChecked(Params().read_db_bool(param.toStdString().c_str())); + if(Params().read_db_bool(param.toStdString().c_str())){ + toggle_switch->togglePosition(); + } setStyleSheet(R"( QCheckBox { @@ -70,7 +79,7 @@ ParamsToggle::ParamsToggle(QString param, QString title, QString description, QS } )"); - QObject::connect(checkbox, SIGNAL(stateChanged(int)), this, SLOT(checkboxClicked(int))); + QObject::connect(toggle_switch, SIGNAL(stateChanged(int)), this, SLOT(checkboxClicked(int))); } void ParamsToggle::checkboxClicked(int state){ diff --git a/selfdrive/ui/qt/offroad/toggle.cc b/selfdrive/ui/qt/offroad/toggle.cc new file mode 100644 index 0000000000..5257645693 --- /dev/null +++ b/selfdrive/ui/qt/offroad/toggle.cc @@ -0,0 +1,66 @@ +#include "toggle.hpp" + +#include +#include +#include +#include +#include "common/params.h" + +Toggle::Toggle(QWidget *parent) : QAbstractButton(parent), +_height(60), +_height_rect(45), +_on(false), +_anim(new QPropertyAnimation(this, "offset_circle", this)) +{ + _radius = _height / 2; + _x_circle = _radius; + _y_circle = _radius; + _y_rect = (_height - _height_rect)/2; +} + + +void Toggle::paintEvent(QPaintEvent *e) { + this->setFixedHeight(_height); + QPainter p(this); + p.setPen(Qt::NoPen); + p.setRenderHint(QPainter::Antialiasing, true); + + // Draw toggle background left + p.setBrush(QColor("#33ab4c")); + p.drawRoundedRect(QRect(0, _y_rect, _x_circle + _radius, _height_rect), _height_rect/2, _height_rect/2); + // Draw toggle background right + p.setBrush(QColor("#0a1a26")); + p.drawRoundedRect(QRect(_x_circle - _radius, _y_rect, width() -(_x_circle - _radius), _height_rect), _height_rect/2, _height_rect/2); + + // Draw toggle circle + p.setBrush(QColor("#fafafa")); + p.drawEllipse(QRectF(_x_circle - _radius, _y_circle - _radius, 2 * _radius, 2 * _radius)); +} + +void Toggle::mouseReleaseEvent(QMouseEvent *e) { + if (e->button() & Qt::LeftButton) { + togglePosition(); + emit stateChanged(_on); + } + +} + +void Toggle::togglePosition(){ + _on = !_on; + if (_on) { + _anim->setStartValue(_radius); + _anim->setEndValue(width() - _radius); + _anim->setDuration(120); + _anim->start(); + } else { + _anim->setStartValue(width() - _radius); + _anim->setEndValue(_radius); + _anim->setDuration(120); + _anim->start(); + } +} + +void Toggle::enterEvent(QEvent *e) { + setCursor(Qt::PointingHandCursor); + QAbstractButton::enterEvent(e); +} diff --git a/selfdrive/ui/qt/offroad/toggle.hpp b/selfdrive/ui/qt/offroad/toggle.hpp new file mode 100644 index 0000000000..9d4f3eceff --- /dev/null +++ b/selfdrive/ui/qt/offroad/toggle.hpp @@ -0,0 +1,34 @@ +#pragma once +#include + +class Toggle : public QAbstractButton { + Q_OBJECT + Q_PROPERTY(int offset_circle READ offset_circle WRITE set_offset_circle) + +public: + Toggle(QWidget* parent = nullptr); + void togglePosition();//Toggles the toggle + + int offset_circle() const { + return _x_circle; + } + void set_offset_circle(int o) { + _x_circle = o; + update(); + } + +protected: + void paintEvent(QPaintEvent*) override; + void mouseReleaseEvent(QMouseEvent*) override; + void enterEvent(QEvent*) override; + +private: + bool _on; + int _x_circle, _y_circle; + int _height, _radius; + int _height_rect, _y_rect; + QPropertyAnimation *_anim = nullptr; + +signals: + void stateChanged(int new_state); +};