mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-23 01:04:01 +08:00
2f5aef1fb8
No longer needed toggle. Values.py do the same now
449 lines
19 KiB
C++
449 lines
19 KiB
C++
#include <QRegularExpression>
|
|
|
|
#include "starpilot/ui/qt/offroad/vehicle_settings.h"
|
|
#include "system/hardware/hw.h"
|
|
|
|
QStringList getCarNames(const QString &carMake, QMap<QString, QString> &carModels) {
|
|
static const QHash<QString, QString> makeToFolder = {
|
|
{"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"},
|
|
{"peugeot", "psa"},
|
|
{"ram", "chrysler"},
|
|
{"rivian", "rivian"},
|
|
{"seat", "volkswagen"},
|
|
{"škoda", "volkswagen"},
|
|
{"subaru", "subaru"},
|
|
{"tesla", "tesla"},
|
|
{"toyota", "toyota"},
|
|
{"volkswagen", "volkswagen"}
|
|
};
|
|
|
|
QStringList carNames;
|
|
|
|
const QString folder = makeToFolder.value(carMake.toLower());
|
|
if (folder.isEmpty()) {
|
|
return carNames;
|
|
}
|
|
|
|
QFile file(QString("../../opendbc/car/%1/values.py").arg(folder));
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
return carNames;
|
|
}
|
|
|
|
QString content = file.readAll();
|
|
file.close();
|
|
|
|
static const QRegularExpression commentRe("#[^\\n]*");
|
|
static const QRegularExpression footnoteRe("footnotes=\\[[^\\]]*\\],\\s*");
|
|
content.remove(commentRe).remove(footnoteRe);
|
|
|
|
static const QRegularExpression platformRe("(\\w+)\\s*=\\s*\\w+\\s*\\(");
|
|
QRegularExpressionMatchIterator platformIt = platformRe.globalMatch(content);
|
|
|
|
QVector<QPair<int, QString>> platforms;
|
|
while (platformIt.hasNext()) {
|
|
QRegularExpressionMatch match = platformIt.next();
|
|
platforms.append({match.capturedStart(), match.captured(1)});
|
|
}
|
|
platforms.append({content.length(), QString()});
|
|
|
|
static const QRegularExpression carNameRe("CarDocs\\w*\\s*\\(\\s*\"([^\"]+)\"");
|
|
const QString lowerMake = carMake.toLower();
|
|
|
|
for (int i = 0; i < platforms.size() - 1; ++i) {
|
|
int start = platforms[i].first;
|
|
int end = platforms[i + 1].first;
|
|
const QString &platformName = platforms[i].second;
|
|
|
|
QRegularExpressionMatchIterator carIt = carNameRe.globalMatch(
|
|
content.mid(start, end - start)
|
|
);
|
|
|
|
while (carIt.hasNext()) {
|
|
QString carName = carIt.next().captured(1);
|
|
if (carName.startsWith(carMake, Qt::CaseInsensitive)) {
|
|
carModels[carName] = platformName;
|
|
carNames.append(carName);
|
|
}
|
|
}
|
|
}
|
|
|
|
carNames.sort(Qt::CaseInsensitive);
|
|
return carNames;
|
|
}
|
|
|
|
StarPilotVehiclesPanel::StarPilotVehiclesPanel(StarPilotSettingsWindow *parent, bool forceOpen) : StarPilotListWidget(parent), parent(parent) {
|
|
forceOpenDescriptions = forceOpen;
|
|
|
|
QStackedLayout *vehiclesLayout = new QStackedLayout();
|
|
addItem(vehiclesLayout);
|
|
|
|
StarPilotListWidget *settingsList = new StarPilotListWidget(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", "Peugeot", "Ram",
|
|
"Rivian", "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 (StarPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely disable openpilot longitudinal control?"), this)) {
|
|
if (started) {
|
|
if (StarPilotConfirmationDialog::toggleReboot(this)) {
|
|
Hardware::reboot();
|
|
}
|
|
}
|
|
} else {
|
|
params.putBool("DisableOpenpilotLongitudinal", false);
|
|
disableOpenpilotLong->refresh();
|
|
}
|
|
}
|
|
|
|
parent->updateVariables();
|
|
updateToggles();
|
|
});
|
|
settingsList->addItem(disableOpenpilotLong);
|
|
|
|
StarPilotListWidget *gmList = new StarPilotListWidget(this);
|
|
StarPilotListWidget *subaruList = new StarPilotListWidget(this);
|
|
StarPilotListWidget *toyotaList = new StarPilotListWidget(this);
|
|
StarPilotListWidget *vehicleInfoList = new StarPilotListWidget(this);
|
|
|
|
ScrollView *gmPanel = new ScrollView(gmList, this);
|
|
ScrollView *subaruPanel = new ScrollView(subaruList, this);
|
|
ScrollView *toyotaPanel = new ScrollView(toyotaList, this);
|
|
ScrollView *vehicleInfoPanel = new ScrollView(vehicleInfoList, this);
|
|
|
|
vehiclesLayout->addWidget(gmPanel);
|
|
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>StarPilot features for General Motors vehicles.</b>"), ""},
|
|
{"GMPedalLongitudinal", tr("Use Pedal For Longitudinal"), tr("<b>Use the pedal interceptor for full longitudinal control</b> on supported GM vehicles."), ""},
|
|
{"GMDashSpoofOffsets", tr("Apply Offsets To Dash Spoof"), tr("<b>On GM pedal-long cars, add the configured set-speed offset</b> to the spoofed dash set speed so it matches the on-screen set speed."), ""},
|
|
{"LongPitch", tr("Smooth Pedal Response on Hills"), tr("<b>Smoothen acceleration and braking</b> when driving downhill/uphill."), ""},
|
|
{"RemoteStartBootsComma", tr("Remote Start Boots comma"), tr("<b>Use the remote-start GM panda firmware at boot.</b><br><br>Required for GM remote-start startup signal behavior."), ""},
|
|
{"RemapCancelToDistance", tr("Remap Cancel Button"), tr("<b>On pedal-interceptor Bolts, treat the steering-wheel CANCEL button as an extra mappable button.</b>"), ""},
|
|
{"VoltSNG", tr("Stop-and-Go Hack"), tr("<b>Force stop-and-go</b> on the 2017 Chevy Volt."), ""},
|
|
|
|
|
|
{"SubaruToggles", tr("Subaru Settings"), tr("<b>StarPilot 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>StarPilot 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 == "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 StarPilotButtonToggleControl(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 StarPilotParamValueControl(param, title, desc, icon, 0, 300, QString(), autoLockLabels, 5);
|
|
} else if (param == "ClusterOffset") {
|
|
std::vector<QString> clusterOffsetButton{"Reset"};
|
|
StarPilotParamValueButtonControl *clusterOffsetToggle = new StarPilotParamValueButtonControl(param, title, desc, icon, 1.000, 1.050, "x", std::map<float, QString>(), 0.001, false, {}, clusterOffsetButton, false, false);
|
|
QObject::connect(clusterOffsetToggle, &StarPilotParamValueButtonControl::buttonClicked, [clusterOffsetToggle, this]() {
|
|
params.putFloat("ClusterOffset", std::stof(params.getKeyDefaultValue("ClusterOffset").value()));
|
|
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 (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, &StarPilotVehiclesPanel::openSubPanel);
|
|
}
|
|
|
|
QObject::connect(vehicleToggle, &AbstractControl::hideDescriptionEvent, [this]() {
|
|
update();
|
|
});
|
|
QObject::connect(vehicleToggle, &AbstractControl::showDescriptionEvent, [this]() {
|
|
update();
|
|
});
|
|
}
|
|
|
|
static_cast<StarPilotParamValueControl*>(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 = {"RemapCancelToDistance"};
|
|
for (const QString &key : rebootKeys) {
|
|
QObject::connect(static_cast<ToggleControl*>(toggles[key]), &ToggleControl::toggleFlipped, [key, this](bool state) {
|
|
if (started) {
|
|
if (StarPilotConfirmationDialog::toggleReboot(this)) {
|
|
Hardware::reboot();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
ParamControl *remoteStartToggle = static_cast<ParamControl*>(toggles["RemoteStartBootsComma"]);
|
|
QObject::connect(remoteStartToggle, &ToggleControl::toggleFlipped, [parent, remoteStartToggle, this](bool state) {
|
|
const QString prompt = tr("Remote Start requires a Panda firmware update. Flash the Panda now?");
|
|
if (!StarPilotConfirmationDialog::yesorno(prompt, this)) {
|
|
params.putBool("RemoteStartBootsComma", !state);
|
|
remoteStartToggle->refresh();
|
|
return;
|
|
}
|
|
|
|
std::thread([parent, this]() {
|
|
parent->keepScreenOn = true;
|
|
params_memory.putBool("FlashPanda", true);
|
|
while (params_memory.getBool("FlashPanda")) {
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
}
|
|
Hardware::reboot();
|
|
}).detach();
|
|
});
|
|
|
|
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", true)));
|
|
}).detach();
|
|
});
|
|
|
|
QObject::connect(parent, &StarPilotSettingsWindow::closeSubPanel, [vehiclesLayout, vehiclesPanel, this] {
|
|
if (forceOpenDescriptions) {
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
disableOpenpilotLong->showDescription();
|
|
forceFingerprint->showDescription();
|
|
}
|
|
vehiclesLayout->setCurrentWidget(vehiclesPanel);
|
|
});
|
|
QObject::connect(uiState(), &UIState::uiUpdate, this, &StarPilotVehiclesPanel::updateState);
|
|
}
|
|
|
|
void StarPilotVehiclesPanel::showEvent(QShowEvent *event) {
|
|
if (forceOpenDescriptions) {
|
|
disableOpenpilotLong->showDescription();
|
|
forceFingerprint->showDescription();
|
|
}
|
|
|
|
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 StarPilotVehiclesPanel::updateState(const UIState &s) {
|
|
if (!isVisible()) {
|
|
return;
|
|
}
|
|
|
|
started = s.scene.started;
|
|
}
|
|
|
|
void StarPilotVehiclesPanel::updateToggles() {
|
|
const bool showAllToggles = parent->showAllTogglesEnabled();
|
|
|
|
for (auto &[key, toggle] : toggles) {
|
|
if (parentKeys.contains(key)) {
|
|
toggle->setVisible(showAllToggles);
|
|
}
|
|
}
|
|
|
|
for (auto &[key, toggle] : toggles) {
|
|
if (parentKeys.contains(key)) {
|
|
continue;
|
|
}
|
|
|
|
bool setVisible = showAllToggles || parent->tuningLevel >= parent->starpilotToggleLevels[key].toDouble();
|
|
|
|
if (!showAllToggles) {
|
|
if (gmKeys.contains(key)) {
|
|
setVisible &= parent->isGM;
|
|
} 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 == "SNGHack") {
|
|
setVisible &= !parent->hasSNG;
|
|
}
|
|
|
|
else if (key == "GMPedalLongitudinal") {
|
|
setVisible &= parent->hasPedal || (Hardware::PC() && parent->canUsePedal);
|
|
}
|
|
|
|
else if (key == "GMDashSpoofOffsets") {
|
|
setVisible &= parent->hasPedal || (Hardware::PC() && parent->canUsePedal);
|
|
}
|
|
|
|
else if (key == "RemapCancelToDistance") {
|
|
setVisible &= parent->isBolt && (parent->hasPedal || (Hardware::PC() && parent->canUsePedal));
|
|
}
|
|
|
|
else if (key == "SubaruSNG") {
|
|
setVisible &= parent->hasSNG;
|
|
}
|
|
|
|
else if (key == "VoltSNG") {
|
|
setVisible &= parent->isVolt && !parent->hasSNG;
|
|
}
|
|
}
|
|
|
|
toggle->setVisible(setVisible);
|
|
|
|
if (setVisible) {
|
|
if (gmKeys.contains(key)) {
|
|
toggles["GMToggles"]->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(showAllToggles || ((parent->hasOpenpilotLongitudinal || parent->openpilotLongitudinalControlDisabled) && !parent->hasAlphaLongitudinal && parent->tuningLevel >= parent->starpilotToggleLevels["DisableOpenpilotLongitudinal"].toDouble()));
|
|
forceFingerprint->setVisible(showAllToggles || parent->tuningLevel >= parent->starpilotToggleLevels["ForceFingerprint"].toDouble());
|
|
|
|
openDescriptions(forceOpenDescriptions, toggles);
|
|
|
|
update();
|
|
}
|