diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index 3813f09..c9522f0 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -11,13 +11,12 @@ #include "selfdrive/ui/qt/widgets/prime.h" #include "system/hardware/hw.h" +#include + #ifdef ENABLE_MAPS #include "selfdrive/ui/qt/maps/map_settings.h" #endif -#include // pybind11 header to control Python embedding -namespace py = pybind11; - // HomeWindow: the container for the offroad and onroad UIs HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) { @@ -191,15 +190,13 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) { QHBoxLayout *home_layout = new QHBoxLayout(home_widget); home_layout->setContentsMargins(0, 0, 0, 0); home_layout->setSpacing(30); - - // Clearpilot: removed home ui widgets - py::scoped_interpreter guard{}; // Start the Python interpreter - auto python_module = py::module_::import("/data/openpilot/webviewtest.py"); - auto WebViewWidget = python_module.attr("WebViewWidget"); - - auto python_widget_instance = WebViewWidget(); - auto* python_widget_embedded = python_widget_instance.cast(); - home_layout->addWidget(python_widget_embedded); + + // Create a QWebEngineView + QWebEngineView *web_view = new QWebEngineView(); + web_view->load(QUrl("http://fark.com")); + + // Add the QWebEngineView to the layout + home_layout->addWidget(web_view); } center_layout->addWidget(home_widget); diff --git a/selfdrive/ui/qt/home.test b/selfdrive/ui/qt/home.test new file mode 100644 index 0000000..aae5229 --- /dev/null +++ b/selfdrive/ui/qt/home.test @@ -0,0 +1,283 @@ +#include "selfdrive/ui/qt/home.h" + +#include +#include +#include +#include + +#include "selfdrive/ui/qt/offroad/experimental_mode.h" +#include "selfdrive/ui/qt/util.h" +#include "selfdrive/ui/qt/widgets/drive_stats.h" +#include "selfdrive/ui/qt/widgets/prime.h" +#include "system/hardware/hw.h" + +#ifdef ENABLE_MAPS +#include "selfdrive/ui/qt/maps/map_settings.h" +#endif + +#include // pybind11 header to control Python embedding +namespace py = pybind11; + +// HomeWindow: the container for the offroad and onroad UIs + +HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) { + // CLEARPILOT Sidebar set to invisible in drive view. + params.putBool("Sidebar", false); + + QHBoxLayout *main_layout = new QHBoxLayout(this); + main_layout->setMargin(0); + main_layout->setSpacing(0); + + sidebar = new Sidebar(this); + main_layout->addWidget(sidebar); + QObject::connect(sidebar, &Sidebar::openSettings, this, &HomeWindow::openSettings); + + slayout = new QStackedLayout(); + main_layout->addLayout(slayout); + + home = new OffroadHome(this); + QObject::connect(home, &OffroadHome::openSettings, this, &HomeWindow::openSettings); + slayout->addWidget(home); + + onroad = new OnroadWindow(this); + QObject::connect(onroad, &OnroadWindow::mapPanelRequested, this, [=] { sidebar->hide(); }); + slayout->addWidget(onroad); + + body = new BodyWindow(this); + slayout->addWidget(body); + + // CLEARPILOT + ready = new ReadyWindow(this); + slayout->addWidget(ready); + + 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); + QObject::connect(uiState(), &UIState::offroadTransition, sidebar, &Sidebar::offroadTransition); +} + +void HomeWindow::showSidebar(bool show) { + sidebar->setVisible(show); +} + +void HomeWindow::showMapPanel(bool show) { + onroad->showMapPanel(show); +} + +void HomeWindow::updateState(const UIState &s) { + // const SubMaster &sm = *(s.sm); + + // CLEARPILOT + // switch to the generic robot UI + // if (onroad->isVisible() && !body->isEnabled() && sm["carParams"].getCarParams().getNotCar()) { + // body->setEnabled(true); + // slayout->setCurrentWidget(body); + // } + + if (s.scene.started) { + showDriverView(s.scene.driver_camera_timer >= 10, true); + } +} + +void HomeWindow::offroadTransition(bool offroad) { + body->setEnabled(false); + if (offroad) { + sidebar->setVisible(false); + slayout->setCurrentWidget(ready); + // this->showDriverView(true, true); // Temp + } else { + sidebar->setVisible(false); + slayout->setCurrentWidget(onroad); + uiState()->scene.map_open = onroad->isMapVisible(); + } +} + +void HomeWindow::showDriverView(bool show, bool started) { + if (show) { + emit closeSettings(); + slayout->setCurrentWidget(driver_view); + sidebar->setVisible(show == false); + } else { + if (started) { + slayout->setCurrentWidget(onroad); + sidebar->setVisible(params.getBool("Sidebar")); + } else { + slayout->setCurrentWidget(home); + sidebar->setVisible(show == false); + } + } +} + +void HomeWindow::mousePressEvent(QMouseEvent* e) { + // CLEARPILOT todo - tap on main goes straight to settings + // Unless we click a debug widget. + + // Handle sidebar collapsing + // if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) { + // sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible()); + // uiState()->scene.map_open = onroad->isMapVisible(); + // params.putBool("Sidebar", sidebar->isVisible()); + // } + + // CLEARPILOT - click ready shows home + if (!onroad->isVisible() && ready->isVisible()) { + sidebar->setVisible(true); + slayout->setCurrentWidget(home); + } + + // Todo: widgets + if (onroad->isVisible()) { + emit openSettings(); + } +} + +void HomeWindow::mouseDoubleClickEvent(QMouseEvent* e) { + HomeWindow::mousePressEvent(e); + const SubMaster &sm = *(uiState()->sm); + if (sm["carParams"].getCarParams().getNotCar()) { + if (onroad->isVisible()) { + slayout->setCurrentWidget(body); + } else if (body->isVisible()) { + slayout->setCurrentWidget(onroad); + } + showSidebar(false); + } +} + +// OffroadHome: the offroad home page + +OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) { + QVBoxLayout* main_layout = new QVBoxLayout(this); + main_layout->setContentsMargins(40, 40, 40, 40); + + // top header + QHBoxLayout* header_layout = new QHBoxLayout(); + header_layout->setContentsMargins(0, 0, 0, 0); + header_layout->setSpacing(16); + + update_notif = new QPushButton(tr("UPDATE")); + update_notif->setVisible(false); + update_notif->setStyleSheet("background-color: #364DEF;"); + QObject::connect(update_notif, &QPushButton::clicked, [=]() { center_layout->setCurrentIndex(1); }); + header_layout->addWidget(update_notif, 0, Qt::AlignHCenter | Qt::AlignLeft); + + alert_notif = new QPushButton(); + alert_notif->setVisible(false); + alert_notif->setStyleSheet("background-color: #E22C2C;"); + QObject::connect(alert_notif, &QPushButton::clicked, [=] { center_layout->setCurrentIndex(2); }); + header_layout->addWidget(alert_notif, 0, Qt::AlignHCenter | Qt::AlignLeft); + + date = new ElidedLabel(); + header_layout->addWidget(date, 0, Qt::AlignHCenter | Qt::AlignLeft); + + version = new ElidedLabel(); + header_layout->addWidget(version, 0, Qt::AlignHCenter | Qt::AlignRight); + + main_layout->addLayout(header_layout); + + // main content + main_layout->addSpacing(25); + center_layout = new QStackedLayout(); + + QWidget *home_widget = new QWidget(this); + { + QHBoxLayout *home_layout = new QHBoxLayout(home_widget); + home_layout->setContentsMargins(0, 0, 0, 0); + home_layout->setSpacing(30); + + // Clearpilot: removed home ui widgets + py::scoped_interpreter guard{}; // Start the Python interpreter + auto python_module = py::module_::import("/data/openpilot/webviewtest.py"); + auto WebViewWidget = python_module.attr("WebViewWidget"); + + auto python_widget_instance = WebViewWidget(); + auto* python_widget_embedded = python_widget_instance.cast(); + home_layout->addWidget(python_widget_embedded); + } + center_layout->addWidget(home_widget); + + // add update & alerts widgets + update_widget = new UpdateAlert(); + QObject::connect(update_widget, &UpdateAlert::dismiss, [=]() { center_layout->setCurrentIndex(0); }); + center_layout->addWidget(update_widget); + alerts_widget = new OffroadAlert(); + QObject::connect(alerts_widget, &OffroadAlert::dismiss, [=]() { center_layout->setCurrentIndex(0); }); + center_layout->addWidget(alerts_widget); + + main_layout->addLayout(center_layout, 1); + + // set up refresh timer + timer = new QTimer(this); + timer->callOnTimeout(this, &OffroadHome::refresh); + + setStyleSheet(R"( + * { + color: white; + } + OffroadHome { + background-color: black; + } + OffroadHome > QPushButton { + padding: 15px 30px; + border-radius: 5px; + font-size: 40px; + font-weight: 500; + } + OffroadHome > QLabel { + font-size: 55px; + } + )"); +} + +/* Refresh data on screen every 5 seconds. */ +void OffroadHome::showEvent(QShowEvent *event) { + refresh(); + timer->start(5 * 1000); +} + +void OffroadHome::hideEvent(QHideEvent *event) { + timer->stop(); +} + +void OffroadHome::refresh() { + QString model = QString::fromStdString(params.get("ModelName")); + + date->setText(QLocale(uiState()->language.mid(5)).toString(QDateTime::currentDateTime(), "dddd, MMMM d")); + version->setText(getBrand() + " v" + getVersion().left(14).trimmed() + " - " + model); + + bool updateAvailable = update_widget->refresh(); + int alerts = alerts_widget->refresh(); + if (alerts > 0 && !alerts_widget->isVisible()) { + alerts_widget->setVisible(true); + } else if (alerts == 0 && alerts_widget->isVisible()) { + alerts_widget->setVisible(false); + } + + // pop-up new notification + // CLEARPILOT temp disabled update notifications + int idx = center_layout->currentIndex(); + if (!updateAvailable && !alerts && false) { + idx = 0; + } else if (updateAvailable && (!update_notif->isVisible() || (!alerts && idx == 2))) { + idx = 1; + } else if (alerts && (!alert_notif->isVisible() || (!updateAvailable && idx == 1))) { + idx = 2; + } + center_layout->setCurrentIndex(idx); + + // CLEARPILOT temp disabled update notifications +// update_notif->setVisible(updateAvailable); +// alert_notif->setVisible(alerts); + update_notif->setVisible(false); + alert_notif->setVisible(false); + if (alerts) { + alert_notif->setText(QString::number(alerts) + (alerts > 1 ? tr(" ALERTS") : tr(" ALERT"))); + } +} diff --git a/system/clearpilot/configure/provision.sh b/system/clearpilot/configure/provision.sh index 41b1367..2ba7772 100644 --- a/system/clearpilot/configure/provision.sh +++ b/system/clearpilot/configure/provision.sh @@ -19,7 +19,7 @@ # Todo: Detect if provisioned for current version. If not, start qt_shell subshell for provision. apt-get update -apt-get install -y nodejs npm python3-pyqt5 pywayland imagemagick +apt-get install -y nodejs npm python3-pyqt5 pywayland imagemagick python3-dev python3-pyqt5.qtwebengine pybind11-dev # apt-get install -y python3-pyqt5.qtwebengine # Detect if libyuv is installed. If it is, nothing to do.