#include "selfdrive/ui/qt/offroad/settings.h" #include #include #include #include #include #include #include #include "selfdrive/ui/qt/network/networking.h" #include "common/params.h" #include "common/watchdog.h" #include "common/util.h" #include "system/hardware/hw.h" #include "selfdrive/ui/qt/widgets/controls.h" #include "selfdrive/ui/qt/widgets/input.h" #include "selfdrive/ui/qt/widgets/scrollview.h" #include "selfdrive/ui/qt/widgets/ssh_keys.h" #include "selfdrive/ui/qt/widgets/toggle.h" #include "selfdrive/ui/ui.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/frogpilot/navigation/ui/navigation_settings.h" #include "selfdrive/frogpilot/ui/control_settings.h" #include "selfdrive/oscarpilot/settings/basic.h" #include "selfdrive/frogpilot/ui/visual_settings.h" #include "selfdrive/oscarpilot/settings/settings.h" void OscarSettingsWindow::showEvent(QShowEvent *event) { setCurrentPanel(0); } void OscarSettingsWindow::setCurrentPanel(int index, const QString ¶m) { panel_widget->setCurrentIndex(index); nav_btns->buttons()[index]->setChecked(true); if (!param.isEmpty()) { emit expandToggleDescription(param); } } OscarSettingsWindow::OscarSettingsWindow(QWidget *parent) : QFrame(parent) { // setup two main layouts sidebar_widget = new QWidget; QVBoxLayout *sidebar_layout = new QVBoxLayout(sidebar_widget); sidebar_layout->setMargin(0); panel_widget = new QStackedWidget(); // close button QPushButton *close_btn = new QPushButton(tr("← Back")); close_btn->setStyleSheet(R"( QPushButton { font-size: 50px; padding-bottom: 0px; border 1px grey solid; border-radius: 25px; background-color: #292929; font-weight: 500; } QPushButton:pressed { background-color: #3B3B3B; } )"); close_btn->setFixedSize(300, 125); sidebar_layout->addSpacing(10); sidebar_layout->addWidget(close_btn, 0, Qt::AlignRight); QObject::connect(close_btn, &QPushButton::clicked, [this]() { if (frogPilotTogglesOpen) { frogPilotTogglesOpen = false; this->closeParentToggle(); } else { this->closeSettings(); } }); FrogPilotControlsPanel *frogpilotControls = new FrogPilotControlsPanel(this); QObject::connect(frogpilotControls, &FrogPilotControlsPanel::closeParentToggle, this, [this]() {frogPilotTogglesOpen = false;}); QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openParentToggle, this, [this]() {frogPilotTogglesOpen = true;}); // DevicePanel *device = new DevicePanel(this); // QObject::connect(device, &DevicePanel::reviewTrainingGuide, this, &SettingsWindow::reviewTrainingGuide); // QObject::connect(device, &DevicePanel::showDriverView, this, &SettingsWindow::showDriverView); QList> panels = { {tr("Basic"), new OscarPilotBasicPanel(this)}, {tr("Advanced"), frogpilotControls}, {tr("Network"), new Networking(this)}, {tr("Software"), new SoftwarePanel(this)}, // {tr("Device"), new DevicePanel(this)}, // FrogPilotControlsPanel // {tr("OscarCloud"), basic}, // {tr("Logging"), basic}, // Log / Upload driver cam, Routes // {tr("System"), new OscarPilotBasicPanel(this)}, // Debugging // {tr("Status"), basic}, // Report on stuff like connectivity, free space, detected features // {tr("Extra"), basic}, // Custom cloud services, QOL automations }; nav_btns = new QButtonGroup(this); for (auto &[name, panel] : panels) { QPushButton *btn = new QPushButton(name); btn->setCheckable(true); btn->setChecked(nav_btns->buttons().size() == 0); btn->setStyleSheet(R"( QPushButton { color: grey; border: none; background: none; font-size: 65px; font-weight: 500; } QPushButton:checked { color: white; } QPushButton:pressed { color: #ADADAD; } )"); btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); nav_btns->addButton(btn); sidebar_layout->addWidget(btn, 0, Qt::AlignRight); const int lr_margin = name != tr("Network") ? 50 : 0; // Network panel handles its own margins panel->setContentsMargins(lr_margin, 25, lr_margin, 25); ScrollView *panel_frame = new ScrollView(panel, this); panel_widget->addWidget(panel_frame); if (name == tr("Controls") || name == tr("Visuals")) { QScrollBar *scrollbar = panel_frame->verticalScrollBar(); QObject::connect(scrollbar, &QScrollBar::valueChanged, this, [this](int value) { if (!frogPilotTogglesOpen) { previousScrollPosition = value; } }); QObject::connect(scrollbar, &QScrollBar::rangeChanged, this, [this, panel_frame]() { panel_frame->restorePosition(previousScrollPosition); }); } QObject::connect(btn, &QPushButton::clicked, [=, w = panel_frame]() { previousScrollPosition = 0; btn->setChecked(true); panel_widget->setCurrentWidget(w); }); } sidebar_layout->setContentsMargins(50, 50, 100, 50); // main settings layout, sidebar + main panel QHBoxLayout *main_layout = new QHBoxLayout(this); sidebar_widget->setFixedWidth(500); main_layout->addWidget(sidebar_widget); main_layout->addWidget(panel_widget); setStyleSheet(R"( * { color: white; font-size: 50px; } OscarSettingsWindow { background-color: black; } QStackedWidget, ScrollView { background-color: #292929; border-radius: 30px; } )"); }