123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #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;
- if (cs.getAlertStatus() == cereal::ControlsState::AlertStatus::USER_PROMPT) {
- status = STATUS_WARNING;
- } else if (cs.getAlertStatus() == cereal::ControlsState::AlertStatus::CRITICAL) {
- status = STATUS_ALERT;
- }
- auto lp = sm["lateralPlan"].getLateralPlan();
- if (lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::PRE_LANE_CHANGE || status == STATUS_ALERT) {
- 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();
- }
|