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.
		
		
		
		
		
			
		
			
				
					
					
						
							132 lines
						
					
					
						
							4.5 KiB
						
					
					
				
			
		
		
	
	
							132 lines
						
					
					
						
							4.5 KiB
						
					
					
				#include <QApplication>
 | 
						|
#include <QtWidgets>
 | 
						|
#include <QTimer>
 | 
						|
#include <QGraphicsScene>
 | 
						|
 | 
						|
#include "cereal/messaging/messaging.h"
 | 
						|
#include "selfdrive/ui/ui.h"
 | 
						|
#include "selfdrive/ui/qt/qt_window.h"
 | 
						|
 | 
						|
class StatusBar : public QGraphicsRectItem {
 | 
						|
  private:
 | 
						|
    QLinearGradient linear_gradient;
 | 
						|
    QRadialGradient radial_gradient;
 | 
						|
    QTimer animation_timer;
 | 
						|
    const int animation_length = 10;
 | 
						|
    int animation_index = 0;
 | 
						|
 | 
						|
  public:
 | 
						|
    StatusBar(double x, double y, double width, double height) : QGraphicsRectItem {x, y, width, height} {
 | 
						|
      linear_gradient = QLinearGradient(0, 0, 0, height/2);
 | 
						|
      linear_gradient.setSpread(QGradient::ReflectSpread);
 | 
						|
 | 
						|
      radial_gradient = QRadialGradient(width/2, height/2, width/8);
 | 
						|
      QObject::connect(&animation_timer, &QTimer::timeout, [=]() {
 | 
						|
        animation_index++;
 | 
						|
        animation_index %= animation_length;
 | 
						|
      });
 | 
						|
      animation_timer.start(50);
 | 
						|
    }
 | 
						|
 | 
						|
    void solidColor(QColor color) {
 | 
						|
      QColor dark_color = QColor(color);
 | 
						|
      dark_color.setAlphaF(0.5);
 | 
						|
 | 
						|
      linear_gradient.setColorAt(0, dark_color);
 | 
						|
      linear_gradient.setColorAt(1, color);
 | 
						|
      setBrush(QBrush(linear_gradient));
 | 
						|
    }
 | 
						|
 | 
						|
    // these need to be called continuously for the animations to work.
 | 
						|
    // can probably clean that up with some more abstractions
 | 
						|
    void blinkingColor(QColor color) {
 | 
						|
      QColor dark_color = QColor(color);
 | 
						|
      dark_color.setAlphaF(0.1);
 | 
						|
 | 
						|
      int radius = (rect().width() / animation_length) * animation_index;
 | 
						|
      QPoint center = QPoint(rect().width()/2, rect().height()/2);
 | 
						|
      radial_gradient.setCenter(center);
 | 
						|
      radial_gradient.setFocalPoint(center);
 | 
						|
      radial_gradient.setRadius(radius);
 | 
						|
 | 
						|
      radial_gradient.setColorAt(1, dark_color);
 | 
						|
      radial_gradient.setColorAt(0, color);
 | 
						|
      setBrush(QBrush(radial_gradient));
 | 
						|
    }
 | 
						|
 | 
						|
    void laneChange(cereal::LateralPlan::LaneChangeDirection direction) {
 | 
						|
      QColor dark_color = QColor(bg_colors[STATUS_ENGAGED]);
 | 
						|
      dark_color.setAlphaF(0.1);
 | 
						|
 | 
						|
      int x = (rect().width() / animation_length) * animation_index;
 | 
						|
      QPoint center = QPoint(((direction == cereal::LateralPlan::LaneChangeDirection::RIGHT) ? x : (rect().width() - x)), rect().height()/2);
 | 
						|
      radial_gradient.setCenter(center);
 | 
						|
      radial_gradient.setFocalPoint(center);
 | 
						|
      radial_gradient.setRadius(rect().width()/5);
 | 
						|
 | 
						|
      radial_gradient.setColorAt(1, dark_color);
 | 
						|
      radial_gradient.setColorAt(0, bg_colors[STATUS_ENGAGED]);
 | 
						|
      setBrush(QBrush(radial_gradient));
 | 
						|
    }
 | 
						|
 | 
						|
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override {
 | 
						|
      painter->setPen(QPen());
 | 
						|
      painter->setBrush(brush());
 | 
						|
 | 
						|
      double rounding_radius = rect().height()/2;
 | 
						|
      painter->drawRoundedRect(rect(), rounding_radius, rounding_radius);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
int main(int argc, char *argv[]) {
 | 
						|
  QApplication a(argc, argv);
 | 
						|
  QWidget w;
 | 
						|
  setMainWindow(&w);
 | 
						|
 | 
						|
  w.setStyleSheet("background-color: black;");
 | 
						|
 | 
						|
  // our beautiful UI
 | 
						|
  QVBoxLayout *layout = new QVBoxLayout(&w);
 | 
						|
 | 
						|
  QGraphicsScene *scene = new QGraphicsScene();
 | 
						|
  StatusBar *status_bar = new StatusBar(0, 0, 1000, 50);
 | 
						|
  scene->addItem(status_bar);
 | 
						|
 | 
						|
  QGraphicsView *graphics_view = new QGraphicsView(scene);
 | 
						|
  layout->insertSpacing(0, 400);
 | 
						|
  layout->addWidget(graphics_view, 0, Qt::AlignCenter);
 | 
						|
 | 
						|
  QTimer timer;
 | 
						|
  QObject::connect(&timer, &QTimer::timeout, [=]() {
 | 
						|
    static SubMaster sm({"deviceState", "controlsState", "lateralPlan"});
 | 
						|
 | 
						|
    bool onroad_prev = sm.allAliveAndValid({"deviceState"}) &&
 | 
						|
                       sm["deviceState"].getDeviceState().getStarted();
 | 
						|
    sm.update(0);
 | 
						|
 | 
						|
    bool onroad = sm.allAliveAndValid({"deviceState"}) &&
 | 
						|
                  sm["deviceState"].getDeviceState().getStarted();
 | 
						|
 | 
						|
    if (onroad) {
 | 
						|
      auto cs = sm["controlsState"].getControlsState();
 | 
						|
      UIStatus status = cs.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED;
 | 
						|
      auto lp = sm["lateralPlan"].getLateralPlan();
 | 
						|
      if (lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::PRE_LANE_CHANGE) {
 | 
						|
        status_bar->blinkingColor(bg_colors[status]);
 | 
						|
      } else if (lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::LANE_CHANGE_STARTING ||
 | 
						|
                 lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::LANE_CHANGE_FINISHING) {
 | 
						|
        status_bar->laneChange(lp.getLaneChangeDirection());
 | 
						|
      } else {
 | 
						|
        status_bar->solidColor(bg_colors[status]);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((onroad != onroad_prev) || sm.frame < 2) {
 | 
						|
      Hardware::set_brightness(50);
 | 
						|
      Hardware::set_display_power(onroad);
 | 
						|
    }
 | 
						|
  });
 | 
						|
  timer.start(50);
 | 
						|
 | 
						|
  return a.exec();
 | 
						|
}
 | 
						|
 |