diff --git a/selfdrive/assets/.gitignore b/selfdrive/assets/.gitignore new file mode 100644 index 0000000000..283034ca8b --- /dev/null +++ b/selfdrive/assets/.gitignore @@ -0,0 +1 @@ +*.cc diff --git a/selfdrive/assets/assets.qrc b/selfdrive/assets/assets.qrc new file mode 100644 index 0000000000..5d6a8eae18 --- /dev/null +++ b/selfdrive/assets/assets.qrc @@ -0,0 +1,14 @@ + + + img_continue_triangle.svg + img_circled_check.svg + img_eye_open.svg + img_eye_closed.svg + offroad/icon_lock_closed.svg + offroad/icon_checkmark.svg + offroad/icon_wifi_strength_low.svg + offroad/icon_wifi_strength_medium.svg + offroad/icon_wifi_strength_high.svg + offroad/icon_wifi_strength_full.svg + + diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index df607ec7fc..ffa34c3eee 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -19,8 +19,7 @@ if arch == "Darwin": del base_libs[base_libs.index('OpenCL')] qt_env['FRAMEWORKS'] += ['OpenCL'] -widgets_src = ["qt/util.cc", - "qt/widgets/input.cc", "qt/widgets/drive_stats.cc", +widgets_src = ["qt/util.cc", "qt/widgets/input.cc", "qt/widgets/drive_stats.cc", "qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/setup.cc", "qt/widgets/keyboard.cc", "qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#phonelibs/qrcode/QrCode.cc", "qt/api.cc", @@ -29,10 +28,13 @@ widgets_src = ["qt/util.cc", if arch != 'aarch64': widgets_src += ["qt/offroad/networking.cc", "qt/offroad/wifiManager.cc"] -if maps: +qt_env['CPPDEFINES'] = [] +if GetOption('setup'): + qt_env['CPPDEFINES'] += ["USE_QRC"] +elif maps: base_libs += ['qmapboxgl'] widgets_src += ["qt/maps/map_helpers.cc", "qt/maps/map_settings.cc", "qt/maps/map.cc"] - qt_env['CPPDEFINES'] = ["ENABLE_MAPS"] + qt_env['CPPDEFINES'] += ["ENABLE_MAPS"] widgets = qt_env.Library("qt_widgets", widgets_src, LIBS=base_libs) qt_libs = [widgets] + base_libs @@ -51,9 +53,16 @@ qt_env.Program("_ui", qt_src, LIBS=qt_libs) # setup, factory resetter, and installer if arch != 'aarch64' and GetOption('setup'): qt_env.Program("qt/setup/reset", ["qt/setup/reset.cc"], LIBS=qt_libs) - qt_env.Program("qt/setup/setup", ["qt/setup/setup.cc"], LIBS=qt_libs + ['curl', 'common', 'json11']) qt_env.Program("qt/setup/wifi", ["qt/setup/wifi.cc"], LIBS=qt_libs + ['common', 'json11']) + # TODO: do this for all resources once NEOS has rcc + assets = "#selfdrive/assets/assets.cc" + assets_src = "#selfdrive/assets/assets.qrc" + qt_env.Command(assets, assets_src, f"rcc $SOURCES -o $TARGET") + qt_env.Depends(assets, Glob('#selfdrive/assets/*', exclude=[assets, assets_src, "#selfdrive/assets/assets.o"])) + qt_env.Program("qt/setup/setup", ["qt/setup/setup.cc", assets], + LIBS=qt_libs + ['curl', 'common', 'json11']) + senv = qt_env.Clone() senv['LINKFLAGS'].append('-Wl,-strip-debug') installers = [ diff --git a/selfdrive/ui/qt/api.cc b/selfdrive/ui/qt/api.cc index 330a436a68..72095fef7e 100644 --- a/selfdrive/ui/qt/api.cc +++ b/selfdrive/ui/qt/api.cc @@ -123,6 +123,8 @@ void HttpRequest::requestFinished() { emit failedResponse(reply->errorString()); } } else { + networkAccessManager->clearAccessCache(); + networkAccessManager->clearConnectionCache(); emit timeoutResponse("timeout"); } emit requestDone(success); diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc index 4a7d9e8655..d3fdeb89c2 100644 --- a/selfdrive/ui/qt/offroad/networking.cc +++ b/selfdrive/ui/qt/offroad/networking.cc @@ -6,14 +6,15 @@ #include #include -#include "selfdrive/ui/qt/widgets/scrollview.h" #include "selfdrive/ui/qt/util.h" +#include "selfdrive/ui/qt/qt_window.h" +#include "selfdrive/ui/qt/widgets/scrollview.h" QLabel *networkStrengthWidget(const unsigned int strength_) { QLabel *strength = new QLabel(); QVector imgs({"low", "medium", "high", "full"}); - QPixmap pix("../assets/offroad/icon_wifi_strength_" + imgs.at(strength_) + ".svg"); + QPixmap pix(ASSET_PATH + "/offroad/icon_wifi_strength_" + imgs.at(strength_) + ".svg"); strength->setPixmap(pix.scaledToHeight(68, Qt::SmoothTransformation)); strength->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); strength->setStyleSheet("padding: 0px; margin-left: 50px; margin-right: 80px "); @@ -56,6 +57,11 @@ Networking::Networking(QWidget* parent, bool show_advanced) : QFrame(parent) { connect(an, &AdvancedNetworking::backPress, [=]() { main_layout->setCurrentWidget(wifiScreen); }); main_layout->addWidget(an); + QPalette pal = palette(); + pal.setColor(QPalette::Background, QColor(0x29, 0x29, 0x29)); + setAutoFillBackground(true); + setPalette(pal); + // TODO: revisit pressed colors setStyleSheet(R"( Networking { @@ -251,7 +257,7 @@ void WifiUI::refresh() { // Status icon if (network.connected == ConnectedType::CONNECTED) { QLabel *connectIcon = new QLabel(); - QPixmap pix("../assets/offroad/icon_checkmark.svg"); + QPixmap pix(ASSET_PATH + "offroad/icon_checkmark.svg"); connectIcon->setPixmap(pix.scaledToWidth(49, Qt::SmoothTransformation)); connectIcon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); @@ -260,7 +266,7 @@ void WifiUI::refresh() { } else if (network.connected == ConnectedType::CONNECTING) { QLabel *connectIcon = new QLabel(); // TODO replace connecting icon with proper widget/icon - QPixmap pix(network.connected == ConnectedType::CONNECTED ? "../assets/offroad/icon_checkmark.svg" : "../assets/navigation/direction_rotary.png"); + QPixmap pix(ASSET_PATH + (network.connected == ConnectedType::CONNECTED ? "offroad/icon_checkmark.svg" : "navigation/direction_rotary.png")); connectIcon->setPixmap(pix.scaledToWidth(49, Qt::SmoothTransformation)); connectIcon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); @@ -268,7 +274,7 @@ void WifiUI::refresh() { hlayout->addWidget(connectIcon, 0, Qt::AlignRight); } else if (network.security_type == SecurityType::WPA) { QLabel *lockIcon = new QLabel(); - QPixmap pix("../assets/offroad/icon_lock_closed.svg"); + QPixmap pix(ASSET_PATH + "offroad/icon_lock_closed.svg"); lockIcon->setPixmap(pix.scaledToHeight(49, Qt::SmoothTransformation)); lockIcon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); diff --git a/selfdrive/ui/qt/qt_window.h b/selfdrive/ui/qt/qt_window.h index 307de6b29f..d17b01462d 100644 --- a/selfdrive/ui/qt/qt_window.h +++ b/selfdrive/ui/qt/qt_window.h @@ -13,6 +13,12 @@ #include "selfdrive/hardware/hw.h" +#ifdef USE_QRC +const QString ASSET_PATH = ":/"; +#else +const QString ASSET_PATH = "../assets/"; +#endif + const int vwp_w = (Hardware::TICI() || (getenv("WIDE_UI") != NULL)) ? 2160 : 1920; const int vwp_h = 1080; diff --git a/selfdrive/ui/qt/setup/setup.cc b/selfdrive/ui/qt/setup/setup.cc index 5f1f2f3e40..b9392612b0 100644 --- a/selfdrive/ui/qt/setup/setup.cc +++ b/selfdrive/ui/qt/setup/setup.cc @@ -72,7 +72,7 @@ QWidget * Setup::getting_started() { vlayout->addStretch(); QPushButton *btn = new QPushButton(); - btn->setIcon(QIcon("../../../assets/img_continue_triangle.svg")); + btn->setIcon(QIcon(":/img_continue_triangle.svg")); btn->setIconSize(QSize(54, 106)); btn->setFixedSize(310, 1080); btn->setProperty("primary", true); @@ -155,7 +155,7 @@ QWidget * radio_button(QString title, QButtonGroup *group) { )"); // checkmark icon - QPixmap pix("../../../assets/img_circled_check.svg"); + QPixmap pix(":/img_circled_check.svg"); btn->setIcon(pix); btn->setIconSize(QSize(0, 0)); btn->setLayoutDirection(Qt::RightToLeft); @@ -208,15 +208,20 @@ QWidget * Setup::software_selection() { blayout->addWidget(cont); QObject::connect(cont, &QPushButton::clicked, [=]() { + auto w = currentWidget(); QString url = DASHCAM_URL; if (group->checkedButton() != dashcam) { - url = InputDialog::getText("Enter URL", this); + QTimer::singleShot(0, [=]() { + setCurrentWidget(downloading_widget); + }); + url = InputDialog::getText("Enter URL", this, "for Custom Software"); } if (!url.isEmpty()) { - setCurrentWidget(downloading_widget); QTimer::singleShot(100, this, [=]() { download(url); }); + } else { + setCurrentWidget(w); } }); diff --git a/selfdrive/ui/qt/widgets/input.cc b/selfdrive/ui/qt/widgets/input.cc index 75e418e1bb..97dc69ef1c 100644 --- a/selfdrive/ui/qt/widgets/input.cc +++ b/selfdrive/ui/qt/widgets/input.cc @@ -64,11 +64,11 @@ InputDialog::InputDialog(const QString &title, QWidget *parent, const QString &s #textbox { margin-left: 50px; margin-right: 50px; - border: none; border-radius: 0; border-bottom: 3px solid #BDBDBD; } * { + border: none; font-size: 80px; font-weight: light; background-color: transparent; @@ -81,13 +81,14 @@ InputDialog::InputDialog(const QString &title, QWidget *parent, const QString &s if (secret) { eye_btn = new QPushButton(); eye_btn->setCheckable(true); + eye_btn->setFixedSize(150, 120); QObject::connect(eye_btn, &QPushButton::toggled, [=](bool checked) { if (checked) { - eye_btn->setIcon(QIcon("../assets/img_eye_closed.svg")); + eye_btn->setIcon(QIcon(ASSET_PATH + "img_eye_closed.svg")); eye_btn->setIconSize(QSize(81, 54)); line->setEchoMode(QLineEdit::PasswordEchoOnEdit); } else { - eye_btn->setIcon(QIcon("../assets/img_eye_open.svg")); + eye_btn->setIcon(QIcon(ASSET_PATH + "img_eye_open.svg")); eye_btn->setIconSize(QSize(81, 44)); line->setEchoMode(QLineEdit::Normal); }