subpanel within subpanel

This commit is contained in:
nayan8teen
2025-06-01 22:28:41 -04:00
parent b5084ab97d
commit a0463f2c1a
9 changed files with 243 additions and 176 deletions
+2 -1
View File
@@ -58,7 +58,8 @@ osm_panel_qt_src = [
slc_panel_qt_src = [
"sunnypilot/qt/offroad/settings/slc/speed_limit_control.cc",
"sunnypilot/qt/offroad/settings/slc/speed_limit_control_source.cc",
"sunnypilot/qt/offroad/settings/slc/speed_limit_control_policy.cc",
"sunnypilot/qt/offroad/settings/slc/speed_limit_control_subpanel.cc",
"sunnypilot/qt/offroad/settings/slc/speed_limit_control_warning.cc",
]
@@ -6,6 +6,7 @@
*/
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/longitudinal_panel.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_subpanel.h"
LongitudinalPanel::LongitudinalPanel(QWidget *parent) : QWidget(parent) {
setStyleSheet(R"(
@@ -41,31 +42,20 @@ LongitudinalPanel::LongitudinalPanel(QWidget *parent) : QWidget(parent) {
"",
this);
list->addItem(slcControl);
connect(slcControl, &SpeedLimitControl::toggleFlipped, this, &LongitudinalPanel::refresh);
connect(slcControl, &SpeedLimitControl::slcWarningButtonClicked, this, &LongitudinalPanel::handleSlcWarningButtonClick);
connect(slcControl, &SpeedLimitControl::slcSourceButtonClicked, this, &LongitudinalPanel::handleSLCSourceButtonClick);
slcWarningScreen = new SpeedLimitControlWarning(this);
connect(slcWarningScreen, &SpeedLimitControlWarning::backPress, this, &LongitudinalPanel::handleSLCBackButtonClick);
slcSourceScreen = new SpeedLimitControlSource(this);
connect(slcSourceScreen, &SpeedLimitControlSource::backPress, this, &LongitudinalPanel::handleSLCBackButtonClick);
connect(slcControl, &SpeedLimitControl::slcSettingsButtonClicked, [=]() {
cruisePanelScroller->setLastScrollPosition();
main_layout->setCurrentWidget(slcScreen);
});
slcScreen = new SpeedLimitControlSubpanel(this);
connect(slcScreen, &SpeedLimitControlSubpanel::backPress, [=]() {
cruisePanelScroller->restoreScrollPosition();
main_layout->setCurrentWidget(cruisePanelScreen);
});
main_layout->addWidget(cruisePanelScreen);
main_layout->addWidget(slcWarningScreen);
main_layout->addWidget(slcSourceScreen);
main_layout->setCurrentWidget(cruisePanelScreen);
}
void LongitudinalPanel::handleSlcWarningButtonClick() {
main_layout->setCurrentWidget(slcWarningScreen);
}
void LongitudinalPanel::handleSLCSourceButtonClick() {
main_layout->setCurrentWidget(slcSourceScreen);
}
void LongitudinalPanel::handleSLCBackButtonClick() {
main_layout->addWidget(slcScreen);
main_layout->setCurrentWidget(cruisePanelScreen);
}
@@ -75,5 +65,4 @@ void LongitudinalPanel::showEvent(QShowEvent *event) {
}
void LongitudinalPanel::refresh() {
slcControl->refresh();
}
@@ -10,8 +10,7 @@
#include "selfdrive/ui/sunnypilot/ui.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_warning.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_source.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_subpanel.h"
#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h"
class LongitudinalPanel : public QWidget {
@@ -22,18 +21,12 @@ public:
void showEvent(QShowEvent *event) override;
void refresh();
private slots:
void handleSlcWarningButtonClick();
void handleSLCSourceButtonClick();
void handleSLCBackButtonClick();
private:
Params params;
QStackedLayout *main_layout = nullptr;
ScrollViewSP *cruisePanelScroller = nullptr;
QWidget *cruisePanelScreen = nullptr;
SpeedLimitControlSubpanel *slcScreen;
SpeedLimitControl *slcControl;
SpeedLimitControlWarning *slcWarningScreen;
SpeedLimitControlSource *slcSourceScreen;
};
@@ -15,95 +15,11 @@ SpeedLimitControl::SpeedLimitControl(const QString &param, const QString &title,
slcFrame->setLayout(slcFrameLayout);
slcFrameLayout->setSpacing(0);
auto *slcBtnFrame = new QFrame(this);
auto *slcBtnFrameLayout = new QGridLayout();
slcBtnFrame->setLayout(slcBtnFrameLayout);
slcBtnFrameLayout->setSpacing(0);
slcWarningControl = new PushButtonSP(tr("Customize Warning"));
connect(slcWarningControl, &QPushButton::clicked, this, &SpeedLimitControl::slcWarningButtonClicked);
slcSourceControl = new PushButtonSP(tr("Customize Source"));
connect(slcSourceControl, &QPushButton::clicked, this, &SpeedLimitControl::slcSourceButtonClicked);
slcWarningControl->setFixedWidth(650);
slcSourceControl->setFixedWidth(650);
slcBtnFrameLayout->addWidget(slcWarningControl, 0, 0, Qt::AlignLeft);
slcBtnFrameLayout->addWidget(slcSourceControl, 0, 1, Qt::AlignRight);
slcFrameLayout->addWidget(slcBtnFrame);
std::vector<QString> slc_engage_texts{
SLCEngageTypeText[static_cast<int>(SLCEngageType::AUTO)],
SLCEngageTypeText[static_cast<int>(SLCEngageType::USER_CONFIRM)]};
slc_engage_setting = new ButtonParamControlSP(
"SpeedLimitEngageType",
tr("Engage Mode"),
"",
"",
slc_engage_texts,
300);
slcFrameLayout->addWidget(slc_engage_setting);
QFrame *offsetFrame = new QFrame(this);
QVBoxLayout *offsetLayout = new QVBoxLayout(offsetFrame);
std::vector<QString> slc_offset_texts{
SLCOffsetTypeText[static_cast<int>(SLCOffsetType::NONE)],
SLCOffsetTypeText[static_cast<int>(SLCOffsetType::FIXED)],
SLCOffsetTypeText[static_cast<int>(SLCOffsetType::PERCENT)]};
slc_offset_setting = new ButtonParamControlSP(
"SpeedLimitOffsetType",
tr("Speed Limit Offset"),
"",
"",
slc_offset_texts,
300);
offsetLayout->addWidget(slc_offset_setting);
slc_offset = new OptionControlSP(
"SpeedLimitValueOffset",
"",
"",
"",
{-30, 30}
);
slc_offset->setFixedWidth(100);
offsetLayout->addWidget(slc_offset);
slcFrameLayout->addWidget(offsetFrame);
connect(slc_offset, &OptionControlSP::updateLabels, this, &SpeedLimitControl::refresh);
connect(slc_offset_setting, &ButtonParamControlSP::showDescriptionEvent, slc_offset, &OptionControlSP::showDescription);
connect(slc_engage_setting, &ButtonParamControlSP::buttonClicked, this, &SpeedLimitControl::refresh);
connect(slc_offset_setting, &ButtonParamControlSP::buttonClicked, this, &SpeedLimitControl::refresh);
refresh();
slcSettings = new PushButtonSP(tr("Customize SLC"));
slcFrameLayout->addWidget(slcSettings);
connect(slcSettings, &QPushButton::clicked, [&]() {
emit slcSettingsButtonClicked();
});
addItem(slcFrame);
}
void SpeedLimitControl::refresh() {
slc_engage_setting->setDescription(engageModeDescription(static_cast<SLCEngageType>(std::stoi(params.get("SpeedLimitEngageType")))));
slc_offset->setDescription(offsetDescription(static_cast<SLCOffsetType>(std::stoi(params.get("SpeedLimitOffsetType")))));
QString offsetLabel = QString::fromStdString(params.get("SpeedLimitValueOffset"));
if (static_cast<SLCOffsetType>(std::stoi(params.get("SpeedLimitOffsetType"))) == SLCOffsetType::PERCENT) {
offsetLabel += "%";
}
if (static_cast<SLCOffsetType>(std::stoi(params.get("SpeedLimitOffsetType"))) == SLCOffsetType::NONE) {
slc_offset->setDisabled(true);
slc_offset->setLabel(tr("N/A"));
} else {
slc_offset->setDisabled(false);
slc_offset->setLabel(offsetLabel);
}
slc_engage_setting->showDescription();
slc_offset->showDescription();
}
void SpeedLimitControl::showEvent(QShowEvent *event) {
refresh();
}
@@ -67,52 +67,11 @@ class SpeedLimitControl : public ExpandableToggleRow {
public:
SpeedLimitControl(const QString &param, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr);
void refresh();
void showEvent(QShowEvent *event) override;
signals:
void slcWarningButtonClicked();
void slcSourceButtonClicked();
void slcSettingsButtonClicked();
private:
Params params;
PushButtonSP *slcWarningControl;
PushButtonSP *slcSourceControl;
ButtonParamControlSP *slc_offset_setting;
OptionControlSP *slc_offset;
ButtonParamControlSP *slc_engage_setting;
static QString engageModeDescription(SLCEngageType type = SLCEngageType::AUTO) {
QString auto_str = tr("⦿ Auto: Automatic speed adjustment based on speed limit data");
QString user_str = tr("⦿ User Confirm: Asks driver to confirm speed adjustment based on speed limit data");
if (type == SLCEngageType::USER_CONFIRM) {
user_str = "<font color='white'><b>" + user_str + "</b></font>";
} else {
auto_str = "<font color='white'><b>" + auto_str + "</b></font>";
}
return QString("%1<br>%2")
.arg(auto_str)
.arg(user_str);
}
static QString offsetDescription(SLCOffsetType type = SLCOffsetType::NONE) {
QString none_str = tr("⦿ None: No Offset");
QString fixed_str = tr("⦿ Fixed: Adds a fixed offset [Speed Limit + Offset]");
QString percent_str = tr("⦿ Percent: Adds a percent offset [Speed Limit + (Offset % Speed Limit)]");
if (type == SLCOffsetType::FIXED) {
fixed_str = "<font color='white'><b>" + fixed_str + "</b></font>";
} else if (type == SLCOffsetType::PERCENT) {
percent_str = "<font color='white'><b>" + percent_str + "</b></font>";
} else {
none_str = "<font color='white'><b>" + none_str + "</b></font>";
}
return QString("%1<br>%2<br>%3")
.arg(none_str)
.arg(fixed_str)
.arg(percent_str);
}
PushButtonSP *slcSettings;
};
@@ -5,9 +5,9 @@
* See the LICENSE.md file in the root directory for more details.
*/
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_source.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_policy.h"
SpeedLimitControlSource::SpeedLimitControlSource(QWidget *parent) : QWidget(parent) {
SpeedLimitControlPolicy::SpeedLimitControlPolicy(QWidget *parent) : QWidget(parent) {
QVBoxLayout* main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(50, 20, 50, 20);
main_layout->setSpacing(20);
@@ -33,17 +33,17 @@ SpeedLimitControlSource::SpeedLimitControlSource(QWidget *parent) : QWidget(pare
slc_policy_texts,
250);
list->addItem(slc_policy);
connect(slc_policy, &ButtonParamControlSP::buttonClicked, this, &SpeedLimitControlSource::refresh);
connect(slc_policy, &ButtonParamControlSP::buttonClicked, this, &SpeedLimitControlPolicy::refresh);
refresh();
main_layout->addWidget(list);
};
void SpeedLimitControlSource::refresh() {
void SpeedLimitControlPolicy::refresh() {
slc_policy->setDescription(sourceDescription(static_cast<SLCSourcePolicy>(std::stoi(params.get("SpeedLimitControlPolicy")))));
slc_policy->showDescription();
}
void SpeedLimitControlSource::showEvent(QShowEvent *event) {
void SpeedLimitControlPolicy::showEvent(QShowEvent *event) {
refresh();
}
@@ -14,11 +14,11 @@
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control.h"
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
class SpeedLimitControlSource : public QWidget {
class SpeedLimitControlPolicy : public QWidget {
Q_OBJECT
public:
explicit SpeedLimitControlSource(QWidget *parent = nullptr);
explicit SpeedLimitControlPolicy(QWidget *parent = nullptr);
void refresh();
void showEvent(QShowEvent *event) override;
@@ -30,11 +30,11 @@ private:
ButtonParamControlSP *slc_policy;
static QString sourceDescription(SLCSourcePolicy type = SLCSourcePolicy::CAR_ONLY) {
QString car_only = tr("⦿ Car Only: ");
QString map_only = tr("⦿ Map Only: ");
QString car_first = tr("⦿ Car First: ");
QString map_first = tr("⦿ Map First: ");
QString combined = tr("⦿ Combined: ");
QString car_only = tr("⦿ Car Only: Use Speed Limit data only from Car");
QString map_only = tr("⦿ Map Only: Use Speed Limit data only from OpenStreetMaps");
QString car_first = tr("⦿ Car First: Use Speed Limit data from Car if available, else use from OpenStreetMaps");
QString map_first = tr("⦿ Map First: Use Speed Limit data from OpenStreetMaps if available, else use from Car");
QString combined = tr("⦿ Combined: Use combined Speed Limit data from Car & OpenStreetMaps");
if (type == SLCSourcePolicy::CAR_ONLY) {
car_only = "<font color='white'><b>" + car_only + "</b></font>";
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
*
* This file is part of sunnypilot and is licensed under the MIT License.
* See the LICENSE.md file in the root directory for more details.
*/
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_subpanel.h"
SpeedLimitControlSubpanel::SpeedLimitControlSubpanel(QWidget *parent) : QStackedWidget(parent) {
subPanelFrame = new QFrame();
QVBoxLayout *subPanelLayout = new QVBoxLayout(subPanelFrame);
subPanelLayout->setContentsMargins(50, 20, 50, 20);
subPanelLayout->setSpacing(20);
// Back button
PanelBackButton* back = new PanelBackButton(tr("Back"));
connect(back, &QPushButton::clicked, [=]() { emit backPress(); });
subPanelLayout->addWidget(back, 0, Qt::AlignLeft);
ListWidgetSP *list = new ListWidgetSP(this, true);
auto *slcBtnFrame = new QFrame(this);
auto *slcBtnFrameLayout = new QGridLayout();
slcBtnFrame->setLayout(slcBtnFrameLayout);
slcBtnFrameLayout->setSpacing(0);
slcWarningScreen = new SpeedLimitControlWarning(this);
slcPolicyScreen = new SpeedLimitControlPolicy(this);
slcWarningControl = new PushButtonSP(tr("Customize Warning"));
connect(slcWarningControl, &QPushButton::clicked, [&]() {
setCurrentWidget(slcWarningScreen);
slcWarningScreen->refresh();
});
connect(slcWarningScreen, &SpeedLimitControlWarning::backPress, [&]() {
setCurrentWidget(subPanelFrame);
refresh();
});
slcSourceControl = new PushButtonSP(tr("Customize Source"));
connect(slcSourceControl, &QPushButton::clicked, [&]() {
setCurrentWidget(slcPolicyScreen);
slcPolicyScreen->refresh();
});
connect(slcPolicyScreen, &SpeedLimitControlPolicy::backPress, [&]() {
setCurrentWidget(subPanelFrame);
refresh();
});
slcWarningControl->setFixedWidth(650);
slcSourceControl->setFixedWidth(650);
slcBtnFrameLayout->addWidget(slcWarningControl, 0, 0, Qt::AlignLeft);
slcBtnFrameLayout->addWidget(slcSourceControl, 0, 1, Qt::AlignRight);
list->addItem(slcBtnFrame);
std::vector<QString> slc_engage_texts{
SLCEngageTypeText[static_cast<int>(SLCEngageType::AUTO)],
SLCEngageTypeText[static_cast<int>(SLCEngageType::USER_CONFIRM)]};
slc_engage_setting = new ButtonParamControlSP(
"SpeedLimitEngageType",
tr("Engage Mode"),
"",
"",
slc_engage_texts,
300);
list->addItem(slc_engage_setting);
QFrame *offsetFrame = new QFrame(this);
QVBoxLayout *offsetLayout = new QVBoxLayout(offsetFrame);
std::vector<QString> slc_offset_texts{
SLCOffsetTypeText[static_cast<int>(SLCOffsetType::NONE)],
SLCOffsetTypeText[static_cast<int>(SLCOffsetType::FIXED)],
SLCOffsetTypeText[static_cast<int>(SLCOffsetType::PERCENT)]};
slc_offset_setting = new ButtonParamControlSP(
"SpeedLimitOffsetType",
tr("Speed Limit Offset"),
"",
"",
slc_offset_texts,
300);
offsetLayout->addWidget(slc_offset_setting);
slc_offset = new OptionControlSP(
"SpeedLimitValueOffset",
"",
"",
"",
{-30, 30}
);
slc_offset->setFixedWidth(100);
offsetLayout->addWidget(slc_offset);
list->addItem(offsetFrame);
connect(slc_offset, &OptionControlSP::updateLabels, this, &SpeedLimitControlSubpanel::refresh);
connect(slc_offset_setting, &ButtonParamControlSP::showDescriptionEvent, slc_offset, &OptionControlSP::showDescription);
connect(slc_engage_setting, &ButtonParamControlSP::buttonClicked, this, &SpeedLimitControlSubpanel::refresh);
connect(slc_offset_setting, &ButtonParamControlSP::buttonClicked, this, &SpeedLimitControlSubpanel::refresh);
refresh();
subPanelLayout->addWidget(list);
addWidget(subPanelFrame);
addWidget(slcWarningScreen);
addWidget(slcPolicyScreen);
setCurrentWidget(subPanelFrame);
};
void SpeedLimitControlSubpanel::refresh() {
slc_engage_setting->setDescription(engageModeDescription(static_cast<SLCEngageType>(std::stoi(params.get("SpeedLimitEngageType")))));
slc_offset->setDescription(offsetDescription(static_cast<SLCOffsetType>(std::stoi(params.get("SpeedLimitOffsetType")))));
QString offsetLabel = QString::fromStdString(params.get("SpeedLimitValueOffset"));
if (static_cast<SLCOffsetType>(std::stoi(params.get("SpeedLimitOffsetType"))) == SLCOffsetType::PERCENT) {
offsetLabel += "%";
}
if (static_cast<SLCOffsetType>(std::stoi(params.get("SpeedLimitOffsetType"))) == SLCOffsetType::NONE) {
slc_offset->setDisabled(true);
slc_offset->setLabel(tr("N/A"));
} else {
slc_offset->setDisabled(false);
slc_offset->setLabel(offsetLabel);
}
slc_engage_setting->showDescription();
slc_offset->showDescription();
}
void SpeedLimitControlSubpanel::showEvent(QShowEvent *event) {
refresh();
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
*
* This file is part of sunnypilot and is licensed under the MIT License.
* See the LICENSE.md file in the root directory for more details.
*/
#pragma once
#include <QStackedWidget>
#include "selfdrive/ui/sunnypilot/ui.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_policy.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/slc/speed_limit_control_warning.h"
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
class SpeedLimitControlSubpanel : public QStackedWidget {
Q_OBJECT
public:
SpeedLimitControlSubpanel(QWidget *parent = nullptr);
void refresh();
void showEvent(QShowEvent *event) override;
signals:
void backPress();
private:
Params params;
QFrame *subPanelFrame;
PushButtonSP *slcWarningControl;
PushButtonSP *slcSourceControl;
ButtonParamControlSP *slc_offset_setting;
OptionControlSP *slc_offset;
ButtonParamControlSP *slc_engage_setting;
SpeedLimitControlWarning *slcWarningScreen;
SpeedLimitControlPolicy *slcPolicyScreen;
static QString engageModeDescription(SLCEngageType type = SLCEngageType::AUTO) {
QString auto_str = tr("⦿ Auto: Automatic speed adjustment based on speed limit data");
QString user_str = tr("⦿ User Confirm: Asks driver to confirm speed adjustment based on speed limit data");
if (type == SLCEngageType::USER_CONFIRM) {
user_str = "<font color='white'><b>" + user_str + "</b></font>";
} else {
auto_str = "<font color='white'><b>" + auto_str + "</b></font>";
}
return QString("%1<br>%2")
.arg(auto_str)
.arg(user_str);
}
static QString offsetDescription(SLCOffsetType type = SLCOffsetType::NONE) {
QString none_str = tr("⦿ None: No Offset");
QString fixed_str = tr("⦿ Fixed: Adds a fixed offset [Speed Limit + Offset]");
QString percent_str = tr("⦿ Percent: Adds a percent offset [Speed Limit + (Offset % Speed Limit)]");
if (type == SLCOffsetType::FIXED) {
fixed_str = "<font color='white'><b>" + fixed_str + "</b></font>";
} else if (type == SLCOffsetType::PERCENT) {
percent_str = "<font color='white'><b>" + percent_str + "</b></font>";
} else {
none_str = "<font color='white'><b>" + none_str + "</b></font>";
}
return QString("%1<br>%2<br>%3")
.arg(none_str)
.arg(fixed_str)
.arg(percent_str);
}
};