diff --git a/release/files_common b/release/files_common index a68f8d1f55..ec0b8370c0 100644 --- a/release/files_common +++ b/release/files_common @@ -446,6 +446,7 @@ selfdrive/assets/.gitignore selfdrive/assets/assets.qrc selfdrive/assets/*.png selfdrive/assets/*.svg +selfdrive/assets/body/* selfdrive/assets/fonts/*.ttf selfdrive/assets/icons/* selfdrive/assets/images/* diff --git a/selfdrive/assets/body/awake.gif b/selfdrive/assets/body/awake.gif new file mode 100644 index 0000000000..7ec67055dd Binary files /dev/null and b/selfdrive/assets/body/awake.gif differ diff --git a/selfdrive/assets/body/sleep.gif b/selfdrive/assets/body/sleep.gif new file mode 100644 index 0000000000..469cc80338 Binary files /dev/null and b/selfdrive/assets/body/sleep.gif differ diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 00d528e63d..7526de685a 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -56,7 +56,7 @@ qt_env.Program("qt/text", ["qt/text.cc"], LIBS=qt_libs) qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs) # build main UI -qt_src = ["main.cc", "ui.cc", "qt/sidebar.cc", "qt/onroad.cc", +qt_src = ["main.cc", "ui.cc", "qt/sidebar.cc", "qt/onroad.cc", "qt/body.cc", "qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc", "qt/offroad/driverview.cc"] qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs) diff --git a/selfdrive/ui/qt/body.cc b/selfdrive/ui/qt/body.cc new file mode 100644 index 0000000000..7e87361916 --- /dev/null +++ b/selfdrive/ui/qt/body.cc @@ -0,0 +1,34 @@ +#include "selfdrive/ui/qt/body.h" + +#include + +BodyWindow::BodyWindow(QWidget *parent) : QLabel(parent) { + awake = new QMovie("../assets/body/awake.gif"); + awake->setCacheMode(QMovie::CacheAll); + sleep = new QMovie("../assets/body/sleep.gif"); + sleep->setCacheMode(QMovie::CacheAll); + + QPalette p(Qt::black); + setPalette(p); + setAutoFillBackground(true); + + setAlignment(Qt::AlignCenter); + + QObject::connect(uiState(), &UIState::uiUpdate, this, &BodyWindow::updateState); +} + +void BodyWindow::updateState(const UIState &s) { + if (!isVisible()) { + return; + } + + const SubMaster &sm = *(s.sm); + + // TODO: use carState.standstill when that's fixed + const bool standstill = std::abs(sm["carState"].getCarState().getVEgo()) < 0.01; + QMovie *m = standstill ? sleep : awake; + if (m != movie()) { + setMovie(m); + movie()->start(); + } +} diff --git a/selfdrive/ui/qt/body.h b/selfdrive/ui/qt/body.h new file mode 100644 index 0000000000..7f352715df --- /dev/null +++ b/selfdrive/ui/qt/body.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#include "selfdrive/ui/ui.h" + +class BodyWindow : public QLabel { + Q_OBJECT + +public: + BodyWindow(QWidget* parent = 0); + +private: + QMovie *awake, *sleep; + +private slots: + void updateState(const UIState &s); +}; diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index df4f474943..1a10eca445 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -30,12 +30,16 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) { onroad = new OnroadWindow(this); slayout->addWidget(onroad); + body = new BodyWindow(this); + slayout->addWidget(body); + driver_view = new DriverViewWindow(this); connect(driver_view, &DriverViewWindow::done, [=] { showDriverView(false); }); slayout->addWidget(driver_view); setAttribute(Qt::WA_NoSystemBackground); + QObject::connect(uiState(), &UIState::uiUpdate, this, &HomeWindow::updateState); QObject::connect(uiState(), &UIState::offroadTransition, this, &HomeWindow::offroadTransition); } @@ -43,6 +47,15 @@ void HomeWindow::showSidebar(bool show) { sidebar->setVisible(show); } +void HomeWindow::updateState(const UIState &s) { + const SubMaster &sm = *(s.sm); + + // switch to the body UI + if (onroad->isVisible() && sm["carParams"].getCarParams().getCarName() == "body") { + slayout->setCurrentWidget(body); + } +} + void HomeWindow::offroadTransition(bool offroad) { sidebar->setVisible(offroad); if (offroad) { @@ -64,7 +77,7 @@ void HomeWindow::showDriverView(bool show) { void HomeWindow::mousePressEvent(QMouseEvent* e) { // Handle sidebar collapsing - if (onroad->isVisible() && (!sidebar->isVisible() || e->x() > sidebar->width())) { + if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) { sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible()); } } diff --git a/selfdrive/ui/qt/home.h b/selfdrive/ui/qt/home.h index 732071c153..7c043908e4 100644 --- a/selfdrive/ui/qt/home.h +++ b/selfdrive/ui/qt/home.h @@ -8,6 +8,7 @@ #include #include "selfdrive/ui/qt/offroad/driverview.h" +#include "selfdrive/ui/qt/body.h" #include "selfdrive/ui/qt/onroad.h" #include "selfdrive/ui/qt/sidebar.h" #include "selfdrive/ui/qt/widgets/offroad_alerts.h" @@ -55,6 +56,10 @@ private: Sidebar *sidebar; OffroadHome *home; OnroadWindow *onroad; + BodyWindow *body; DriverViewWindow *driver_view; QStackedLayout *slayout; + +private slots: + void updateState(const UIState &s); };