You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							213 lines
						
					
					
						
							5.1 KiB
						
					
					
				
			
		
		
	
	
							213 lines
						
					
					
						
							5.1 KiB
						
					
					
				#pragma once
 | 
						|
 | 
						|
#include <QFrame>
 | 
						|
#include <QHBoxLayout>
 | 
						|
#include <QLabel>
 | 
						|
#include <QPainter>
 | 
						|
#include <QPushButton>
 | 
						|
 | 
						|
#include "common/params.h"
 | 
						|
#include "selfdrive/ui/qt/widgets/toggle.h"
 | 
						|
 | 
						|
QFrame *horizontal_line(QWidget *parent = nullptr);
 | 
						|
 | 
						|
class ElidedLabel : public QLabel {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  explicit ElidedLabel(QWidget *parent = 0);
 | 
						|
  explicit ElidedLabel(const QString &text, QWidget *parent = 0);
 | 
						|
 | 
						|
signals:
 | 
						|
  void clicked();
 | 
						|
 | 
						|
protected:
 | 
						|
  void paintEvent(QPaintEvent *event) override;
 | 
						|
  void resizeEvent(QResizeEvent* event) override;
 | 
						|
  void mouseReleaseEvent(QMouseEvent *event) override {
 | 
						|
    if (rect().contains(event->pos())) {
 | 
						|
      emit clicked();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  QString lastText_, elidedText_;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class AbstractControl : public QFrame {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  void setDescription(const QString &desc) {
 | 
						|
    if (description) description->setText(desc);
 | 
						|
  }
 | 
						|
 | 
						|
  void setTitle(const QString &title) {
 | 
						|
    title_label->setText(title);
 | 
						|
  }
 | 
						|
 | 
						|
  void setValue(const QString &val) {
 | 
						|
    value->setText(val);
 | 
						|
  }
 | 
						|
 | 
						|
public slots:
 | 
						|
  void showDescription() {
 | 
						|
    description->setVisible(true);
 | 
						|
  };
 | 
						|
 | 
						|
signals:
 | 
						|
  void showDescriptionEvent();
 | 
						|
 | 
						|
protected:
 | 
						|
  AbstractControl(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr);
 | 
						|
  void hideEvent(QHideEvent *e) override;
 | 
						|
 | 
						|
  QHBoxLayout *hlayout;
 | 
						|
  QPushButton *title_label;
 | 
						|
 | 
						|
private:
 | 
						|
  QLabel *value;
 | 
						|
  QLabel *description = nullptr;
 | 
						|
};
 | 
						|
 | 
						|
// widget to display a value
 | 
						|
class LabelControl : public AbstractControl {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  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);
 | 
						|
  }
 | 
						|
  void setText(const QString &text) { label.setText(text); }
 | 
						|
 | 
						|
private:
 | 
						|
  ElidedLabel label;
 | 
						|
};
 | 
						|
 | 
						|
// widget for a button with a label
 | 
						|
class ButtonControl : public AbstractControl {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  ButtonControl(const QString &title, const QString &text, const QString &desc = "", QWidget *parent = nullptr);
 | 
						|
  inline void setText(const QString &text) { btn.setText(text); }
 | 
						|
  inline QString text() const { return btn.text(); }
 | 
						|
 | 
						|
signals:
 | 
						|
  void clicked();
 | 
						|
 | 
						|
public slots:
 | 
						|
  void setEnabled(bool enabled) { btn.setEnabled(enabled); };
 | 
						|
 | 
						|
private:
 | 
						|
  QPushButton btn;
 | 
						|
};
 | 
						|
 | 
						|
class ToggleControl : public AbstractControl {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  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();
 | 
						|
    }
 | 
						|
    hlayout->addWidget(&toggle);
 | 
						|
    QObject::connect(&toggle, &Toggle::stateChanged, this, &ToggleControl::toggleFlipped);
 | 
						|
  }
 | 
						|
 | 
						|
  void setEnabled(bool enabled) {
 | 
						|
    toggle.setEnabled(enabled);
 | 
						|
    toggle.update();
 | 
						|
  }
 | 
						|
 | 
						|
signals:
 | 
						|
  void toggleFlipped(bool state);
 | 
						|
 | 
						|
protected:
 | 
						|
  Toggle toggle;
 | 
						|
};
 | 
						|
 | 
						|
// widget to toggle params
 | 
						|
class ParamControl : public ToggleControl {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  ParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr) : ToggleControl(title, desc, icon, false, parent) {
 | 
						|
    key = param.toStdString();
 | 
						|
    QObject::connect(this, &ParamControl::toggleFlipped, [=](bool state) {
 | 
						|
      params.putBool(key, state);
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  void refresh() {
 | 
						|
    if (params.getBool(key) != toggle.on) {
 | 
						|
      toggle.togglePosition();
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  void showEvent(QShowEvent *event) override {
 | 
						|
    refresh();
 | 
						|
  };
 | 
						|
 | 
						|
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) {
 | 
						|
      QWidget *widget = inner_layout.itemAt(i)->widget();
 | 
						|
      if (widget == nullptr || widget->isVisible()) {
 | 
						|
        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;
 | 
						|
};
 | 
						|
 | 
						|
// convenience class for wrapping layouts
 | 
						|
class LayoutWidget : public QWidget {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  LayoutWidget(QLayout *l, QWidget *parent = nullptr) : QWidget(parent) {
 | 
						|
    setLayout(l);
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
class ClickableWidget : public QWidget {
 | 
						|
  Q_OBJECT
 | 
						|
 | 
						|
public:
 | 
						|
  ClickableWidget(QWidget *parent = nullptr);
 | 
						|
 | 
						|
protected:
 | 
						|
  void mouseReleaseEvent(QMouseEvent *event) override;
 | 
						|
  void paintEvent(QPaintEvent *) override;
 | 
						|
 | 
						|
signals:
 | 
						|
  void clicked();
 | 
						|
};
 | 
						|
 |