476 lines
21 KiB
C++
476 lines
21 KiB
C++
#include <QRegularExpression>
|
|
#include <QTextStream>
|
|
|
|
#include "frogpilot/ui/qt/offroad/vehicle_settings.h"
|
|
|
|
QStringList getCarNames(const QString &carMake, QMap<QString, QString> &carModels) {
|
|
static QMap<QString, QString> makeMap = {
|
|
{"acura", "honda"},
|
|
{"audi", "volkswagen"},
|
|
{"buick", "gm"},
|
|
{"cadillac", "gm"},
|
|
{"chevrolet", "gm"},
|
|
{"chrysler", "chrysler"},
|
|
{"cupra", "volkswagen"},
|
|
{"dodge", "chrysler"},
|
|
{"ford", "ford"},
|
|
{"genesis", "hyundai"},
|
|
{"gmc", "gm"},
|
|
{"holden", "gm"},
|
|
{"honda", "honda"},
|
|
{"hyundai", "hyundai"},
|
|
{"jeep", "chrysler"},
|
|
{"kia", "hyundai"},
|
|
{"lexus", "toyota"},
|
|
{"lincoln", "ford"},
|
|
{"man", "volkswagen"},
|
|
{"mazda", "mazda"},
|
|
{"nissan", "nissan"},
|
|
{"ram", "chrysler"},
|
|
{"seat", "volkswagen"},
|
|
{"škoda", "volkswagen"},
|
|
{"subaru", "subaru"},
|
|
{"tesla", "tesla"},
|
|
{"toyota", "toyota"},
|
|
{"volkswagen", "volkswagen"}
|
|
};
|
|
|
|
QStringList carNameList;
|
|
|
|
QFile valuesFile(QString("../car/%1/values.py").arg(makeMap.value(carMake, carMake)));
|
|
if (!valuesFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
return carNameList;
|
|
}
|
|
|
|
QString fileContent = QTextStream(&valuesFile).readAll();
|
|
valuesFile.close();
|
|
|
|
fileContent.remove(QRegularExpression("#[^\n]*"));
|
|
fileContent.remove(QRegularExpression("footnotes=\\[[^\\]]*\\],\\s*"));
|
|
|
|
static QRegularExpression carNameRegex("CarDocs\\(\\s*\"([^\"]+)\"[^)]*\\)");
|
|
static QRegularExpression platformRegex("((\\w+)\\s*=\\s*\\w+\\s*\\(\\s*\\[([\\s\\S]*?)\\]\\s*,)");
|
|
static QRegularExpression validNameRegex("^[A-Za-z0-9 \u0160.()-]+$");
|
|
|
|
QRegularExpressionMatchIterator platformMatches = platformRegex.globalMatch(fileContent);
|
|
while (platformMatches.hasNext()) {
|
|
QRegularExpressionMatch platformMatch = platformMatches.next();
|
|
QString platformName = platformMatch.captured(2);
|
|
QString platformSection = platformMatch.captured(3);
|
|
|
|
QRegularExpressionMatchIterator carNameMatches = carNameRegex.globalMatch(platformSection);
|
|
while (carNameMatches.hasNext()) {
|
|
QString carName = carNameMatches.next().captured(1);
|
|
|
|
if (carName.contains(validNameRegex) && carName.count(" ") >= 1) {
|
|
QString firstWord = carName.section(" ", 0, 0);
|
|
|
|
if (firstWord.compare(carMake, Qt::CaseInsensitive) == 0) {
|
|
carModels[carName] = platformName;
|
|
carNameList.append(carName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
carNameList.sort();
|
|
return carNameList;
|
|
}
|
|
|
|
FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(FrogPilotSettingsWindow *parent) : FrogPilotListWidget(parent), parent(parent) {
|
|
QJsonObject shownDescriptions = QJsonDocument::fromJson(QString::fromStdString(params.get("ShownToggleDescriptions")).toUtf8()).object();
|
|
QString className = this->metaObject()->className();
|
|
|
|
if (!shownDescriptions.value(className).toBool(false)) {
|
|
forceOpenDescriptions = true;
|
|
shownDescriptions.insert(className, true);
|
|
params.put("ShownToggleDescriptions", QJsonDocument(shownDescriptions).toJson(QJsonDocument::Compact).toStdString());
|
|
}
|
|
|
|
QStackedLayout *vehiclesLayout = new QStackedLayout();
|
|
addItem(vehiclesLayout);
|
|
|
|
FrogPilotListWidget *settingsList = new FrogPilotListWidget(this);
|
|
|
|
ScrollView *vehiclesPanel = new ScrollView(settingsList, this);
|
|
|
|
vehiclesLayout->addWidget(vehiclesPanel);
|
|
|
|
QStringList makes = {
|
|
"Acura", "Audi", "Buick", "Cadillac", "Chevrolet", "Chrysler",
|
|
"CUPRA", "Dodge", "Ford", "Genesis", "GMC", "Holden", "Honda",
|
|
"Hyundai", "Jeep", "Kia", "Lexus", "Lincoln", "MAN", "Mazda",
|
|
"Nissan", "Ram", "SEAT", "Škoda", "Subaru", "Tesla", "Toyota",
|
|
"Volkswagen"
|
|
};
|
|
|
|
ButtonControl *selectMakeButton = new ButtonControl(tr("Car Make"), tr("SELECT"));
|
|
QObject::connect(selectMakeButton, &ButtonControl::clicked, [makes, selectMakeButton, this]() {
|
|
QString makeSelection = MultiOptionDialog::getSelection(tr("Choose your car make"), makes, "", this);
|
|
if (!makeSelection.isEmpty()) {
|
|
params.put("CarMake", makeSelection.toStdString());
|
|
selectMakeButton->setValue(makeSelection);
|
|
}
|
|
});
|
|
settingsList->addItem(selectMakeButton);
|
|
|
|
ButtonControl *selectModelButton = new ButtonControl(tr("Car Model"), tr("SELECT"));
|
|
QObject::connect(selectModelButton, &ButtonControl::clicked, [selectModelButton, this]() {
|
|
QString modelSelection = MultiOptionDialog::getSelection(tr("Choose your car model"), getCarNames(QString::fromStdString(params.get("CarMake")).toLower(), carModels), "", this);
|
|
if (!modelSelection.isEmpty()) {
|
|
params.put("CarModel", carModels.value(modelSelection).toStdString());
|
|
params.put("CarModelName", modelSelection.toStdString());
|
|
selectModelButton->setValue(modelSelection);
|
|
}
|
|
});
|
|
settingsList->addItem(selectModelButton);
|
|
|
|
forceFingerprint = new ParamControl("ForceFingerprint", tr("Disable Automatic Fingerprint Detection"), tr("<b>Force the selected fingerprint</b> and prevent it from ever changing."), "");
|
|
settingsList->addItem(forceFingerprint);
|
|
|
|
disableOpenpilotLong = new ParamControl("DisableOpenpilotLongitudinal", tr("Disable openpilot Longitudinal Control"), tr("<b>Disable openpilot longitudinal</b> and use the car's stock ACC instead."), "");
|
|
QObject::connect(disableOpenpilotLong, &ToggleControl::toggleFlipped, [parent, this](bool state) {
|
|
if (state) {
|
|
if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely disable openpilot longitudinal control?"), this)) {
|
|
if (started) {
|
|
if (FrogPilotConfirmationDialog::toggleReboot(this)) {
|
|
Hardware::reboot();
|
|
}
|
|
}
|
|
} else {
|
|
params.putBool("DisableOpenpilotLongitudinal", false);
|
|
disableOpenpilotLong->refresh();
|
|
}
|
|
}
|
|
|
|
parent->updateVariables();
|
|
updateToggles();
|
|
});
|
|
settingsList->addItem(disableOpenpilotLong);
|
|
|
|
FrogPilotListWidget *gmList = new FrogPilotListWidget(this);
|
|
FrogPilotListWidget *hkgList = new FrogPilotListWidget(this);
|
|
FrogPilotListWidget *hondaList = new FrogPilotListWidget(this);
|
|
FrogPilotListWidget *subaruList = new FrogPilotListWidget(this);
|
|
FrogPilotListWidget *toyotaList = new FrogPilotListWidget(this);
|
|
FrogPilotListWidget *vehicleInfoList = new FrogPilotListWidget(this);
|
|
|
|
ScrollView *gmPanel = new ScrollView(gmList, this);
|
|
ScrollView *hkgPanel = new ScrollView(hkgList, this);
|
|
ScrollView *hondaPanel = new ScrollView(hondaList, this);
|
|
ScrollView *subaruPanel = new ScrollView(subaruList, this);
|
|
ScrollView *toyotaPanel = new ScrollView(toyotaList, this);
|
|
ScrollView *vehicleInfoPanel = new ScrollView(vehicleInfoList, this);
|
|
|
|
vehiclesLayout->addWidget(gmPanel);
|
|
vehiclesLayout->addWidget(hkgPanel);
|
|
vehiclesLayout->addWidget(hondaPanel);
|
|
vehiclesLayout->addWidget(subaruPanel);
|
|
vehiclesLayout->addWidget(toyotaPanel);
|
|
vehiclesLayout->addWidget(vehicleInfoPanel);
|
|
|
|
std::vector<std::tuple<QString, QString, QString, QString>> vehicleToggles {
|
|
{"GMToggles", tr("General Motors Settings"), tr("<b>FrogPilot features for General Motors vehicles.</b>"), ""},
|
|
{"ExperimentalGMTune", tr("FrogsGoMoo's Experimental Tune"), tr("<b>Experimental GM tune by FrogsGoMoo</b> that attempts to smoothen stopping and takeoff control. Use at your own risk!"), ""},
|
|
{"LongPitch", tr("Smooth Pedal Response on Hills"), tr("<b>Smoothen acceleration and braking</b> when driving downhill/uphill."), ""},
|
|
{"VoltSNG", tr("Stop-and-Go Hack"), tr("<b>Force stop-and-go</b> on the 2017 Chevy Volt."), ""},
|
|
|
|
{"HKGToggles", tr("Hyundai/Kia/Genesis Settings"), tr("<b>FrogPilot features for Genesis, Hyundai, and Kia vehicles.</b>"), ""},
|
|
{"NewLongAPI", tr("comma's New Longitudinal API"), tr("<b>comma's new gas and brake control system</b> that improves acceleration and braking but may cause issues on some Genesis/Hyundai/Kia vehicles."), ""},
|
|
{"TacoTuneHacks", tr("\"Taco Bell Run\" Torque Hack"), tr("<b>The steering torque hack from comma's 2022 \"Taco Bell Run\".</b> Designed to increase steering torque at low speeds for left and right turns."), ""},
|
|
|
|
{"HondaToggles", tr("Acura/Honda Settings"), tr("<b>FrogPilot features for Acura and Honda vehicles.</b>"), ""},
|
|
{"HondaAltTune", tr("Gentle Following"), tr("<b>Reduces jerky acceleration and braking when following a lead vehicle.</b> Ideal for stop-and-go traffic."), ""},
|
|
{"HondaMaxBrake", tr("Increased Braking Force"), tr("<b>Increases the maximum braking force for improved stopping performance.</b>"), ""},
|
|
{"HondaLowSpeedPedal", tr("Responsive Pedal at Low Speeds"), tr("<b>Improves acceleration from a standstill for a more responsive throttle feel in city driving.</b>"), ""},
|
|
|
|
{"SubaruToggles", tr("Subaru Settings"), tr("<b>FrogPilot features for Subaru vehicles.</b>"), ""},
|
|
{"SubaruSNG", tr("Stop and Go"), tr("Stop and go for supported Subaru vehicles."), ""},
|
|
|
|
{"ToyotaToggles", tr("Toyota/Lexus Settings"), tr("<b>FrogPilot features for Lexus and Toyota vehicles.</b>"), ""},
|
|
{"ToyotaDoors", tr("Automatically Lock/Unlock Doors"), tr("<b>Automatically lock/unlock doors</b> when shifting in and out of drive."), ""},
|
|
{"ClusterOffset", tr("Dashboard Speed Offset"), tr("<b>The speed offset openpilot uses to match the speed on the dashboard display.</b>"), ""},
|
|
{"FrogsGoMoosTweak", tr("FrogsGoMoo's Personal Tweaks"), tr("<b>Personal tweaks by FrogsGoMoo for quicker acceleration and smoother braking.</b>"), ""},
|
|
{"LockDoorsTimer", tr("Lock Doors On Ignition Off After"), tr("<b>Automatically lock the doors on ignition off</b> when no one is detected in the front seats."), ""},
|
|
{"SNGHack", tr("Stop-and-Go Hack"), tr("<b>Force stop-and-go</b> on Lexus/Toyota vehicles without stock stop-and-go functionality."), ""},
|
|
|
|
{"VehicleInfo", tr("Vehicle Info"), tr("<b>Information about your vehicle in regards to openpilot support and functionality.</b>"), ""},
|
|
{"HardwareDetected", tr("3rd Party Hardware Detected"), tr("<b>Detected 3rd party hardware.</b>"), ""},
|
|
{"BlindSpotSupport", tr("Blind Spot Support"), tr("<b>Does openpilot use the vehicle's blind spot data?</b>"), ""},
|
|
{"PedalSupport", tr("comma Pedal Support"), tr("<b>Does your vehicle support the \"comma pedal\"?</b>"), ""},
|
|
{"OpenpilotLongitudinal", tr("openpilot Longitudinal Support"), tr("<b>Can openpilot control the vehicle's acceleration and braking?</b>"), ""},
|
|
{"RadarSupport", tr("Radar Support"), tr("<b>Does openpilot use the vehicle's radar data</b> alongside the device's camera for tracking lead vehicles?"), ""},
|
|
{"SDSUSupport", tr("SDSU Support"), tr("<b>Does your vehicle support \"SDSUs\"?</b>"), ""},
|
|
{"SNGSupport", tr("Stop-and-Go Support"), tr("<b>Does your vehicle support stop-and-go driving?</b>"), ""}
|
|
};
|
|
|
|
for (const auto &[param, title, desc, icon] : vehicleToggles) {
|
|
AbstractControl *vehicleToggle;
|
|
|
|
if (param == "GMToggles") {
|
|
ButtonControl *gmButton = new ButtonControl(title, tr("MANAGE"), desc);
|
|
QObject::connect(gmButton, &ButtonControl::clicked, [vehiclesLayout, gmPanel, this]() {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
vehiclesLayout->setCurrentWidget(gmPanel);
|
|
});
|
|
vehicleToggle = gmButton;
|
|
|
|
} else if (param == "HKGToggles") {
|
|
ButtonControl *hkgButton = new ButtonControl(title, tr("MANAGE"), desc);
|
|
QObject::connect(hkgButton, &ButtonControl::clicked, [vehiclesLayout, hkgPanel, this]() {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
vehiclesLayout->setCurrentWidget(hkgPanel);
|
|
});
|
|
vehicleToggle = hkgButton;
|
|
|
|
} else if (param == "HondaToggles") {
|
|
ButtonControl *hondaButton = new ButtonControl(title, tr("MANAGE"), desc);
|
|
QObject::connect(hondaButton, &ButtonControl::clicked, [vehiclesLayout, hondaPanel, this]() {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
vehiclesLayout->setCurrentWidget(hondaPanel);
|
|
});
|
|
vehicleToggle = hondaButton;
|
|
|
|
} else if (param == "SubaruToggles") {
|
|
ButtonControl *subaruButton = new ButtonControl(title, tr("MANAGE"), desc);
|
|
QObject::connect(subaruButton, &ButtonControl::clicked, [vehiclesLayout, subaruPanel, this]() {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
vehiclesLayout->setCurrentWidget(subaruPanel);
|
|
});
|
|
vehicleToggle = subaruButton;
|
|
|
|
} else if (param == "ToyotaToggles") {
|
|
ButtonControl *toyotaButton = new ButtonControl(title, tr("MANAGE"), desc);
|
|
QObject::connect(toyotaButton, &ButtonControl::clicked, [vehiclesLayout, toyotaPanel, this]() {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
vehiclesLayout->setCurrentWidget(toyotaPanel);
|
|
});
|
|
vehicleToggle = toyotaButton;
|
|
} else if (param == "ToyotaDoors") {
|
|
std::vector<QString> lockToggles{"LockDoors", "UnlockDoors"};
|
|
std::vector<QString> lockToggleNames{tr("Lock"), tr("Unlock")};
|
|
vehicleToggle = new FrogPilotButtonToggleControl(param, title, desc, icon, lockToggles, lockToggleNames);
|
|
} else if (param == "LockDoorsTimer") {
|
|
std::map<float, QString> autoLockLabels;
|
|
for (int i = 0; i <= 300; ++i) {
|
|
autoLockLabels[i] = i == 0 ? tr("Never") : QString::number(i) + tr(" seconds");
|
|
}
|
|
vehicleToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 300, QString(), autoLockLabels, 5);
|
|
} else if (param == "ClusterOffset") {
|
|
std::vector<QString> clusterOffsetButton{"Reset"};
|
|
FrogPilotParamValueButtonControl *clusterOffsetToggle = new FrogPilotParamValueButtonControl(param, title, desc, icon, 1.000, 1.050, "x", std::map<float, QString>(), 0.001, false, {}, clusterOffsetButton, false, false);
|
|
QObject::connect(clusterOffsetToggle, &FrogPilotParamValueButtonControl::buttonClicked, [clusterOffsetToggle, this]() {
|
|
params.putFloat("ClusterOffset", params_default.getFloat("ClusterOffset"));
|
|
clusterOffsetToggle->refresh();
|
|
});
|
|
vehicleToggle = clusterOffsetToggle;
|
|
|
|
} else if (param == "VehicleInfo") {
|
|
ButtonControl *VehicleInfoButton = new ButtonControl(title, tr("VIEW"), desc);
|
|
QObject::connect(VehicleInfoButton, &ButtonControl::clicked, [vehiclesLayout, vehicleInfoPanel, this]() {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
vehiclesLayout->setCurrentWidget(vehicleInfoPanel);
|
|
});
|
|
vehicleToggle = VehicleInfoButton;
|
|
} else if (vehicleInfoKeys.contains(param)) {
|
|
vehicleToggle = new LabelControl(title, "", desc);
|
|
|
|
} else {
|
|
vehicleToggle = new ParamControl(param, title, desc, icon);
|
|
}
|
|
|
|
toggles[param] = vehicleToggle;
|
|
|
|
if (gmKeys.contains(param)) {
|
|
gmList->addItem(vehicleToggle);
|
|
} else if (hkgKeys.contains(param)) {
|
|
hkgList->addItem(vehicleToggle);
|
|
} else if (hondaKeys.contains(param)) {
|
|
hondaList->addItem(vehicleToggle);
|
|
} else if (subaruKeys.contains(param)) {
|
|
subaruList->addItem(vehicleToggle);
|
|
} else if (toyotaKeys.contains(param)) {
|
|
toyotaList->addItem(vehicleToggle);
|
|
} else if (vehicleInfoKeys.contains(param)) {
|
|
vehicleInfoList->addItem(vehicleToggle);
|
|
} else {
|
|
settingsList->addItem(vehicleToggle);
|
|
|
|
parentKeys.insert(param);
|
|
}
|
|
|
|
if (ButtonControl *buttonControl = qobject_cast<ButtonControl*>(vehicleToggle)) {
|
|
QObject::connect(buttonControl, &ButtonControl::clicked, this, &FrogPilotVehiclesPanel::openSubPanel);
|
|
}
|
|
|
|
QObject::connect(vehicleToggle, &AbstractControl::hideDescriptionEvent, [this]() {
|
|
update();
|
|
});
|
|
QObject::connect(vehicleToggle, &AbstractControl::showDescriptionEvent, [this]() {
|
|
update();
|
|
});
|
|
}
|
|
|
|
static_cast<FrogPilotParamValueControl*>(toggles["LockDoorsTimer"])->setWarning("<b>Warning:</b> openpilot can't detect if keys are still inside the car, so ensure you have a spare key to prevent accidental lockouts!");
|
|
|
|
QSet<QString> rebootKeys = {"HondaAltTune", "NewLongAPI", "TacoTuneHacks"};
|
|
for (const QString &key : rebootKeys) {
|
|
QObject::connect(static_cast<ToggleControl*>(toggles[key]), &ToggleControl::toggleFlipped, [key, this](bool state) {
|
|
if (started) {
|
|
if (key == "HondaAltTune" || key == "TacoTuneHacks" && state) {
|
|
if (FrogPilotConfirmationDialog::toggleReboot(this)) {
|
|
Hardware::reboot();
|
|
}
|
|
} else if (key != "TacoTuneHacks") {
|
|
if (FrogPilotConfirmationDialog::toggleReboot(this)) {
|
|
Hardware::reboot();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
|
|
QObject::connect(uiState(), &UIState::offroadTransition, [selectMakeButton, selectModelButton, this]() {
|
|
std::thread([selectMakeButton, selectModelButton, this]() {
|
|
selectMakeButton->setValue(QString::fromStdString(params.get("CarMake", true)));
|
|
selectModelButton->setValue(QString::fromStdString(params.get(params.get("CarModelName").empty() ? "CarModel" : "CarModelName")));
|
|
}).detach();
|
|
});
|
|
|
|
QObject::connect(parent, &FrogPilotSettingsWindow::closeSubPanel, [vehiclesLayout, vehiclesPanel, this] {
|
|
if (forceOpenDescriptions) {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
|
|
disableOpenpilotLong->showDescription();
|
|
forceFingerprint->showDescription();
|
|
}
|
|
vehiclesLayout->setCurrentWidget(vehiclesPanel);
|
|
});
|
|
QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotVehiclesPanel::updateState);
|
|
}
|
|
|
|
void FrogPilotVehiclesPanel::showEvent(QShowEvent *event) {
|
|
if (forceOpenDescriptions) {
|
|
disableOpenpilotLong->showDescription();
|
|
forceFingerprint->showDescription();
|
|
}
|
|
|
|
frogpilotToggleLevels = parent->frogpilotToggleLevels;
|
|
|
|
QStringList detected;
|
|
if (parent->hasPedal) detected << "comma Pedal";
|
|
if (parent->hasSDSU) detected << "SDSU";
|
|
if (parent->hasZSS) detected << "ZSS";
|
|
static_cast<LabelControl*>(toggles["HardwareDetected"])->setText(detected.isEmpty() ? tr("None") : detected.join(", "));
|
|
|
|
static_cast<LabelControl*>(toggles["BlindSpotSupport"])->setText(parent->hasBSM ? tr("Yes") : tr("No"));
|
|
static_cast<LabelControl*>(toggles["OpenpilotLongitudinal"])->setText(parent->hasOpenpilotLongitudinal ? tr("Yes") : tr("No"));
|
|
static_cast<LabelControl*>(toggles["PedalSupport"])->setText(parent->canUsePedal ? tr("Yes") : tr("No"));
|
|
static_cast<LabelControl*>(toggles["RadarSupport"])->setText(parent->hasRadar ? tr("Yes") : tr("No"));
|
|
static_cast<LabelControl*>(toggles["SDSUSupport"])->setText(parent->canUseSDSU ? tr("Yes") : tr("No"));
|
|
static_cast<LabelControl*>(toggles["SNGSupport"])->setText(parent->hasSNG ? tr("Yes") : tr("No"));
|
|
|
|
updateToggles();
|
|
}
|
|
|
|
void FrogPilotVehiclesPanel::updateState(const UIState &s) {
|
|
if (!isVisible()) {
|
|
return;
|
|
}
|
|
|
|
started = s.scene.started;
|
|
}
|
|
|
|
void FrogPilotVehiclesPanel::updateToggles() {
|
|
for (auto &[key, toggle] : toggles) {
|
|
if (parentKeys.contains(key)) {
|
|
toggle->setVisible(false);
|
|
}
|
|
}
|
|
|
|
for (auto &[key, toggle] : toggles) {
|
|
if (parentKeys.contains(key)) {
|
|
continue;
|
|
}
|
|
|
|
bool setVisible = parent->tuningLevel >= frogpilotToggleLevels[key].toDouble();
|
|
|
|
if (gmKeys.contains(key)) {
|
|
setVisible &= parent->isGM;
|
|
} else if (hkgKeys.contains(key)) {
|
|
setVisible &= parent->isHKG;
|
|
} else if (hondaKeys.contains(key)) {
|
|
setVisible &= parent->isHonda;
|
|
} else if (subaruKeys.contains(key)) {
|
|
setVisible &= parent->isSubaru;
|
|
} else if (toyotaKeys.contains(key)) {
|
|
setVisible &= parent->isToyota;
|
|
} else if (vehicleInfoKeys.contains(key)) {
|
|
setVisible = true;
|
|
}
|
|
|
|
if (longitudinalKeys.contains(key)) {
|
|
setVisible &= parent->hasOpenpilotLongitudinal;
|
|
}
|
|
|
|
if (key == "HondaAltTune") {
|
|
setVisible &= parent->isHondaNidec;
|
|
}
|
|
|
|
else if (key == "HondaLowSpeedPedal") {
|
|
setVisible &= parent->hasPedal;
|
|
}
|
|
|
|
else if (key == "HondaMaxBrake") {
|
|
setVisible &= parent->isHondaNidec;
|
|
}
|
|
|
|
else if (key == "LockDoorsTimer") {
|
|
setVisible &= !parent->isC3;
|
|
}
|
|
|
|
else if (key == "SNGHack") {
|
|
setVisible &= !parent->hasPedal && !parent->hasSNG;
|
|
}
|
|
|
|
else if (key == "SubaruSNG") {
|
|
setVisible &= parent->hasSNG;
|
|
}
|
|
|
|
else if (key == "TacoTuneHacks") {
|
|
setVisible &= parent->isHKGCanFd;
|
|
}
|
|
|
|
else if (key == "VoltSNG") {
|
|
setVisible &= parent->isVolt && !parent->hasSNG;
|
|
}
|
|
|
|
toggle->setVisible(setVisible);
|
|
|
|
if (setVisible) {
|
|
if (gmKeys.contains(key)) {
|
|
toggles["GMToggles"]->setVisible(true);
|
|
} else if (hkgKeys.contains(key)) {
|
|
toggles["HKGToggles"]->setVisible(true);
|
|
} else if (hondaKeys.contains(key)) {
|
|
toggles["HondaToggles"]->setVisible(true);
|
|
} else if (subaruKeys.contains(key)) {
|
|
toggles["SubaruToggles"]->setVisible(true);
|
|
} else if (toyotaKeys.contains(key)) {
|
|
toggles["ToyotaToggles"]->setVisible(true);
|
|
} else if (vehicleInfoKeys.contains(key)) {
|
|
toggles["VehicleInfo"]->setVisible(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
disableOpenpilotLong->setVisible((parent->hasOpenpilotLongitudinal || parent->openpilotLongitudinalControlDisabled) && !parent->hasExperimentalOpenpilotLongitudinal && parent->tuningLevel >= frogpilotToggleLevels["DisableOpenpilotLongitudinal"].toBool());
|
|
forceFingerprint->setVisible(parent->tuningLevel >= frogpilotToggleLevels["ForceFingerprint"].toBool());
|
|
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
|
|
update();
|
|
}
|