diff --git a/companion/src/firmwares/customfunctiondata.h b/companion/src/firmwares/customfunctiondata.h index f8246880c1f..b87d5df18b3 100644 --- a/companion/src/firmwares/customfunctiondata.h +++ b/companion/src/firmwares/customfunctiondata.h @@ -28,6 +28,8 @@ #include #include +#define CF_CUSTNAME_LEN 10 + class Firmware; class ModelData; class GeneralSettings; @@ -106,6 +108,7 @@ class CustomFunctionData { unsigned int enabled; // TODO perhaps not any more the right name unsigned int adjustMode; int repeatParam; + char custName[CF_CUSTNAME_LEN + 1]; void convert(RadioDataConversionState & cstate); diff --git a/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp b/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp index 15a9f1d3590..ac01b2a2d66 100644 --- a/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp +++ b/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp @@ -244,6 +244,8 @@ Node convert::encode(const CustomFunctionData& rhs) node["def"] = def; } + node["custName"] = rhs.custName; + return node; } @@ -252,6 +254,8 @@ bool convert::decode(const Node& node, { node["swtch"] >> rhs.swtch; + node["custName"] >> rhs.custName; + int func = 0; node["func"] >> customFnLut >> func; rhs.func = (AssignFunc)func; diff --git a/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp index b3f5eff5f31..bea44ef4de9 100644 --- a/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp +++ b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp @@ -42,6 +42,7 @@ static const YamlLookupTable funcLut = { {LS_FN_DAPOS, "FUNC_ADIFFEGREATER"}, {LS_FN_TIMER, "FUNC_TIMER"}, {LS_FN_STICKY, "FUNC_STICKY"}, + {LS_FN_SAFE, "FUNC_SAFE"}, }; static int timerValue2lsw(uint32_t t) @@ -80,6 +81,12 @@ Node convert::encode(const LogicalSwitchData& rhs) def += YamlRawSwitchEncode(RawSwitch(rhs.val2)); } break; + case LS_FAMILY_SAFE: { + def += YamlRawSwitchEncode(RawSwitch(rhs.val1)); + def += ","; + def += YamlRawSwitchEncode(RawSwitch(rhs.val2)); + } break; + case LS_FAMILY_EDGE: { def += YamlRawSwitchEncode(RawSwitch(rhs.val1)); def += ","; @@ -119,7 +126,7 @@ Node convert::encode(const LogicalSwitchData& rhs) node["andsw"] = YamlRawSwitchEncode(RawSwitch(rhs.andsw)); node["lsPersist"] = (int)rhs.lsPersist; node["lsState"] = (int)rhs.lsState; - + node["custName"] = rhs.custName; return node; } @@ -127,6 +134,7 @@ bool convert::decode(const Node& node, LogicalSwitchData& rhs) { node["func"] >> funcLut >> rhs.func; + node["custName"] >> rhs.custName; std::string def_str; node["def"] >> def_str; @@ -142,6 +150,14 @@ bool convert::decode(const Node& node, rhs.val2 = YamlRawSwitchDecode(sw_str).toValue(); } break; +case LS_FAMILY_SAFE: { + std::string sw_str; + getline(def, sw_str, ','); + rhs.val1 = YamlRawSwitchDecode(sw_str).toValue(); + getline(def, sw_str); + rhs.val2 = YamlRawSwitchDecode(sw_str).toValue(); + } break; + case LS_FAMILY_EDGE: { std::string sw_str; getline(def, sw_str, ','); diff --git a/companion/src/firmwares/logicalswitchdata.cpp b/companion/src/firmwares/logicalswitchdata.cpp index 527b475f7f4..e5e26ee0527 100644 --- a/companion/src/firmwares/logicalswitchdata.cpp +++ b/companion/src/firmwares/logicalswitchdata.cpp @@ -28,7 +28,7 @@ bool LogicalSwitchData::isEmpty() const { - return (func == 0); + return (func == LS_FN_OFF); } CSFunctionFamily LogicalSwitchData::getFunctionFamily() const @@ -39,6 +39,8 @@ CSFunctionFamily LogicalSwitchData::getFunctionFamily() const return LS_FAMILY_TIMER; else if (func == LS_FN_STICKY) return LS_FAMILY_STICKY; + else if (func == LS_FN_SAFE) + return LS_FAMILY_SAFE; else if (func < LS_FN_AND || func > LS_FN_ELESS) return LS_FAMILY_VOFS; else if (func < LS_FN_EQUAL) @@ -103,6 +105,8 @@ QString LogicalSwitchData::funcToString() const return tr("Timer"); case LS_FN_STICKY: return tr("Sticky"); + case LS_FN_SAFE: + return tr("Safe"); case LS_FN_EDGE: return tr("Edge"); default: @@ -112,7 +116,7 @@ QString LogicalSwitchData::funcToString() const QString LogicalSwitchData::nameToString(int index) const { - return RadioData::getElementName(tr("L"), index + 1, NULL, true); + return RadioData::getElementName(tr("L"), index + 1, custName, true); } void LogicalSwitchData::convert(RadioDataConversionState & cstate) @@ -125,6 +129,10 @@ void LogicalSwitchData::convert(RadioDataConversionState & cstate) val1 = RawSource(val1).convert(cstate.withComponentField("V1")).toValue(); break; case LS_FAMILY_STICKY: + case LS_FAMILY_SAFE: + val1 = RawSwitch(val1).convert(cstate.withComponentField("V1")).toValue(); + val2 = RawSwitch(val2).convert(cstate.withComponentField("V2")).toValue(); + break; case LS_FAMILY_VBOOL: val1 = RawSwitch(val1).convert(cstate.withComponentField("V1")).toValue(); val2 = RawSwitch(val2).convert(cstate.withComponentField("V2")).toValue(); diff --git a/companion/src/firmwares/logicalswitchdata.h b/companion/src/firmwares/logicalswitchdata.h index f915d4ee179..181362efb33 100644 --- a/companion/src/firmwares/logicalswitchdata.h +++ b/companion/src/firmwares/logicalswitchdata.h @@ -19,11 +19,12 @@ * GNU General Public License for more details. */ -#ifndef LOGICALSWITCHDATA_H -#define LOGICALSWITCHDATA_H +#pragma once #include +#define LS_CUSTNAME_LEN 10 + class RadioDataConversionState; enum CSFunction { @@ -48,8 +49,10 @@ enum CSFunction { LS_FN_TIMER, LS_FN_STICKY, LS_FN_EDGE, + LS_FN_SAFE, // later ... LS_FN_RANGE, - LS_FN_MAX + LS_FN_MAX, + }; enum CSFunctionFamily { @@ -59,6 +62,7 @@ enum CSFunctionFamily { LS_FAMILY_TIMER, LS_FAMILY_STICKY, LS_FAMILY_EDGE, + LS_FAMILY_SAFE, }; class LogicalSwitchData { @@ -79,6 +83,7 @@ class LogicalSwitchData { int andsw; bool lsState; bool lsPersist; + char custName[LS_CUSTNAME_LEN + 1]; void clear() { memset(this, 0, sizeof(LogicalSwitchData)); } bool isEmpty() const; @@ -88,5 +93,3 @@ class LogicalSwitchData { QString nameToString(int index) const; void convert(RadioDataConversionState & cstate); }; - -#endif // LOGICALSWITCHDATA_H diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 5a10293c59f..a1c5a2ff54f 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -719,6 +719,12 @@ int ModelData::updateReference() } break; case LS_FAMILY_STICKY: + case LS_FAMILY_SAFE: + if (lsd->val1 != 0) + updateSwitchIntRef(lsd->val1); + if (lsd->val2 != 0) + updateSwitchIntRef(lsd->val2); + break; case LS_FAMILY_VBOOL: oldval1 = lsd->val1; oldval2 = lsd->val2; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index be925798aa4..1be6d3a9a3b 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -1515,6 +1515,7 @@ class LogicalSwitchesFunctionsTable: public ConversionTable { addConversion(LS_FN_DAPOS, val++); addConversion(LS_FN_TIMER, val++); addConversion(LS_FN_STICKY, val++); + addConversion(LS_FN_SAFE, val++); } }; @@ -1570,7 +1571,7 @@ class LogicalSwitchField: public TransformedField { v2 = csw.val2; v3 = csw.val3; } - else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY) { + else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY || csw.func == LS_FN_SAFE) { switchesConversionTable->exportValue(csw.val1, v1); switchesConversionTable->exportValue(csw.val2, v2); } @@ -1595,7 +1596,7 @@ class LogicalSwitchField: public TransformedField { csw.val2 = v2; csw.val3 = v3; } - else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY) { + else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY || csw.func == LS_FN_SAFE) { switchesConversionTable->importValue(v1, csw.val1); switchesConversionTable->importValue(v2, csw.val2); } diff --git a/companion/src/firmwares/rawsource.cpp b/companion/src/firmwares/rawsource.cpp index 32dffd8db37..62488a2344f 100644 --- a/companion/src/firmwares/rawsource.cpp +++ b/companion/src/firmwares/rawsource.cpp @@ -208,7 +208,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con return DataHelpers::getCompositeName(dfltName, custName, prefixCustomName); case SOURCE_TYPE_CUSTOM_SWITCH: - return RawSwitch(SWITCH_TYPE_VIRTUAL, index).toString(); // RawSwitch uses 1 based index + return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1) .toString(board, generalSettings, model); // RawSwitch uses 1 based index case SOURCE_TYPE_CYC: return tr("CYC%1").arg(index); diff --git a/companion/src/firmwares/rawswitch.cpp b/companion/src/firmwares/rawswitch.cpp index 8fe7b2aacd2..e88cf42541c 100644 --- a/companion/src/firmwares/rawswitch.cpp +++ b/companion/src/firmwares/rawswitch.cpp @@ -99,10 +99,20 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen case SWITCH_TYPE_VIRTUAL: if (modelData) - return modelData->logicalSw[index].nameToString(index - 1); + return modelData->logicalSw[index - 1].nameToString(index - 1); else return LogicalSwitchData().nameToString(index - 1); + case SWITCH_TYPE_FUNCTIONSWITCH: + if (!Boards::getCapability(board, Board::FunctionSwitches)) + return CPN_STR_UNKNOWN_ITEM; + qr = div(index - 1, 3); + if (modelData) + swName = QString(modelData->functionSwitchNames[qr.quot]).trimmed(); + if (swName.isEmpty()) + swName = tr("SW%1").arg(qr.quot + 1); + return swName + directionIndicators.at(qr.rem > -1 && qr.rem < directionIndicators.size() ? qr.rem : 1); + case SWITCH_TYPE_MULTIPOS_POT: if (!Boards::getCapability(board, Board::MultiposPotsPositions)) return CPN_STR_UNKNOWN_ITEM; diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index fa2fede880e..3381d934fdd 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -113,7 +113,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, playIcon.addImage("stop.png", QIcon::Normal, QIcon::On); QStringList headerLabels; - headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Repeat") << tr("Enable"); + headerLabels << "#" << tr("Name") << tr("Switch") << tr("Action") << tr("Parameters") << tr("Repeat") << tr("Enable"); TableLayout * tableLayout = new TableLayout(this, fswCapability, headerLabels); for (int i = 0; i < fswCapability; i++) { @@ -131,6 +131,16 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint))); tableLayout->addWidget(i, 0, label); + // The Custom Name + name[i] = new QLineEdit(this); + name[i]->setProperty("index", i); + name[i]->setMaxLength(CF_CUSTNAME_LEN); + QRegExp rx(CHAR_FOR_NAMES_REGEX); + name[i]->setValidator(new QRegExpValidator(rx, this)); + name[i]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + connect(name[i], SIGNAL(editingFinished()), this, SLOT(onNameEdited())); + tableLayout->addWidget(i, 1, name[i]); + // The switch fswtchSwtch[i] = new QComboBox(this); fswtchSwtch[i]->setProperty("index", i); @@ -140,7 +150,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, fswtchSwtch[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); fswtchSwtch[i]->setMaxVisibleItems(10); connect(fswtchSwtch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); - tableLayout->addWidget(i, 1, fswtchSwtch[i]); + tableLayout->addWidget(i, 2, fswtchSwtch[i]); // The function fswtchFunc[i] = new QComboBox(this); @@ -149,11 +159,11 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func)); fswtchFunc[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(fswtchFunc[i], SIGNAL(currentIndexChanged(int)), this, SLOT(functionEdited())); - tableLayout->addWidget(i, 2, fswtchFunc[i]); + tableLayout->addWidget(i, 3, fswtchFunc[i]); // The parameters QHBoxLayout * paramLayout = new QHBoxLayout(); - tableLayout->addLayout(i, 3, paramLayout); + tableLayout->addLayout(i, 4, paramLayout); fswtchGVmode[i] = new QComboBox(this); fswtchGVmode[i]->setProperty("index", i); @@ -204,14 +214,14 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, connect(playBT[i], &QToolButton::clicked, this, &CustomFunctionsPanel::toggleSound); QHBoxLayout * repeatLayout = new QHBoxLayout(); - tableLayout->addLayout(i, 4, repeatLayout); + tableLayout->addLayout(i, 5, repeatLayout); fswtchRepeat[i] = new QComboBox(this); fswtchRepeat[i]->setProperty("index", i); if (functions[i].func == FuncPlayScript || functions[i].func == FuncRGBLed) fswtchRepeat[i]->setModel(tabModelFactory->getItemModel(repeatLuaId)); else fswtchRepeat[i]->setModel(tabModelFactory->getItemModel(repeatId)); - fswtchRepeat[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + fswtchRepeat[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); fswtchRepeat[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); repeatLayout->addWidget(fswtchRepeat[i], i + 1); connect(fswtchRepeat[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); @@ -227,7 +237,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, disableMouseScrolling(); tableLayout->resizeColumnsToContents(); - tableLayout->setColumnWidth(3, 300); + tableLayout->setColumnWidth(5, 300); tableLayout->pushRowsUp(fswCapability + 1); update(); @@ -350,6 +360,8 @@ void CustomFunctionsPanel::functionEdited() lock = true; int index = sender()->property("index").toInt(); RawSwitch swtch = functions[index].swtch; + int paramTemp =functions[index].param; + functions[index].clear(); functions[index].swtch = swtch; functions[index].func = (AssignFunc)fswtchFunc[index]->currentData().toInt(); @@ -358,24 +370,43 @@ void CustomFunctionsPanel::functionEdited() fswtchRepeat[index]->setModel(tabModelFactory->getItemModel(repeatLuaId)); else fswtchRepeat[index]->setModel(tabModelFactory->getItemModel(repeatId)); + functions[index].param = paramTemp; + strcpy(functions[index].custName, name[index]->text().toLatin1()); + refreshCustomFunction(index); emit modified(); lock = false; } } +void CustomFunctionsPanel::onNameEdited() +{ + QLineEdit *le = qobject_cast(sender()); + int index = le->property("index").toInt(); + CustomFunctionData & cfn = functions[index]; + if (cfn.custName != le->text()) { + strcpy(cfn.custName, le->text().toLatin1()); + emit modified(); + } +} + void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) { CustomFunctionData & cfn = functions[i]; AssignFunc func = (AssignFunc)fswtchFunc[i]->currentData().toInt(); + + unsigned int widgetsMask = 0; if (modified) { + cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt()); cfn.func = func; cfn.enabled = fswtchEnable[i]->isChecked(); + } else { + name[i]->setText(cfn.custName); fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(cfn.swtch.toValue())); fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(cfn.func)); fswtchEnable[i]->setChecked(cfn.enabled); @@ -384,6 +415,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) if (!cfn.isEmpty()) { widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC | CUSTOM_FUNCTION_ENABLE; + name[i]->setText(cfn.custName); + if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) { if (model) { int channelsMax = model->getChannelsMax(true); @@ -391,8 +424,11 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParam[i]->setSingleStep(1); fswtchParam[i]->setMinimum(-channelsMax); fswtchParam[i]->setMaximum(channelsMax); + name[i]->setText(cfn.custName); + if (modified) { cfn.param = fswtchParam[i]->value(); + strcpy(cfn.custName, name[i]->text().toLatin1()); } fswtchParam[i]->setValue(cfn.param); widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; @@ -777,6 +813,7 @@ void CustomFunctionsPanel::swapData(int idx1, int idx2) void CustomFunctionsPanel::resetCBsAndRefresh(int idx) { lock = true; + name[idx]->clear(); fswtchSwtch[idx]->setCurrentIndex(fswtchSwtch[idx]->findData(functions[idx].swtch.toValue())); fswtchFunc[idx]->setCurrentIndex(fswtchFunc[idx]->findData(functions[idx].func)); fswtchGVmode[idx]->setCurrentIndex(functions[idx].adjustMode); diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index a629a7fc143..d5d989a2a29 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -47,6 +47,7 @@ class CustomFunctionsPanel : public GenericPanel private slots: void customFunctionEdited(); + void onNameEdited(); void functionEdited(); void onCustomContextMenuRequested(QPoint pos); void refreshCustomFunction(int index, bool modified=false); @@ -94,6 +95,7 @@ class CustomFunctionsPanel : public GenericPanel QSet tracksSet; QSet scriptsSet; int mediaPlayerCurrent; + QLineEdit * name[CPN_MAX_SPECIAL_FUNCTIONS]; QComboBox * fswtchSwtch[CPN_MAX_SPECIAL_FUNCTIONS]; QComboBox * fswtchFunc[CPN_MAX_SPECIAL_FUNCTIONS]; QCheckBox * fswtchParamGV[CPN_MAX_SPECIAL_FUNCTIONS]; diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp index b628fcd0d1a..ab0571698b1 100644 --- a/companion/src/modeledit/logicalswitches.cpp +++ b/companion/src/modeledit/logicalswitches.cpp @@ -44,7 +44,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt); QStringList headerLabels; - headerLabels << "#" << tr("Function") << tr("V1") << tr("V2") << tr("AND Switch"); + headerLabels << "#" << tr("Name") << tr("Function") << tr("V1") << tr("V2") << tr("AND Switch"); if (lsCapabilityExt) { headerLabels << tr("Duration") << tr("Delay"); } @@ -65,12 +65,22 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint))); tableLayout->addWidget(i, 0, label); + // The Custom Name + name[i] = new QLineEdit(this); + name[i]->setProperty("index", i); + name[i]->setMaxLength(LS_CUSTNAME_LEN); + QRegExp rx(CHAR_FOR_NAMES_REGEX); + name[i]->setValidator(new QRegExpValidator(rx, this)); + name[i]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + connect(name[i], SIGNAL(editingFinished()), this, SLOT(onNameEdited())); + tableLayout->addWidget(i, 1, name[i]); + // The function cbFunction[i] = new QComboBox(this); cbFunction[i]->setProperty("index", i); populateFunctionCB(cbFunction[i]); connect(cbFunction[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onFunctionChanged())); - tableLayout->addWidget(i, 1, cbFunction[i]); + tableLayout->addWidget(i, 2, cbFunction[i]); // V1 QHBoxLayout *v1Layout = new QHBoxLayout(); @@ -88,7 +98,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, connect(dsbValue[i], SIGNAL(editingFinished()), this, SLOT(onOffsetChanged())); v1Layout->addWidget(dsbValue[i]); dsbValue[i]->setVisible(false); - tableLayout->addLayout(i, 2, v1Layout); + tableLayout->addLayout(i, 3, v1Layout); // V2 QHBoxLayout *v2Layout = new QHBoxLayout(); @@ -121,7 +131,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, connect(teOffset[i],SIGNAL(editingFinished()),this,SLOT(onOffsetChanged())); v2Layout->addWidget(teOffset[i]); teOffset[i]->setVisible(false); - tableLayout->addLayout(i, 3, v2Layout); + tableLayout->addLayout(i, 4, v2Layout); // AND cbAndSwitch[i] = new QComboBox(this); @@ -129,7 +139,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, cbAndSwitch[i]->setModel(rawSwitchFilteredModel); cbAndSwitch[i]->setVisible(true); connect(cbAndSwitch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onAndSwitchChanged(int))); - tableLayout->addWidget(i, 4, cbAndSwitch[i]); + tableLayout->addWidget(i, 5, cbAndSwitch[i]); if (lsCapabilityExt) { // Duration @@ -141,7 +151,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, dsbDuration[i]->setAccelerated(true); dsbDuration[i]->setDecimals(1); connect(dsbDuration[i], SIGNAL(valueChanged(double)), this, SLOT(onDurationChanged(double))); - tableLayout->addWidget(i, 5, dsbDuration[i]); + tableLayout->addWidget(i, 6, dsbDuration[i]); // Delay dsbDelay[i] = new QDoubleSpinBox(this); @@ -152,7 +162,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, dsbDelay[i]->setAccelerated(true); dsbDelay[i]->setDecimals(1); connect(dsbDelay[i], SIGNAL(valueChanged(double)), this, SLOT(onDelayChanged(double))); - tableLayout->addWidget(i, 6, dsbDelay[i]); + tableLayout->addWidget(i, 7, dsbDelay[i]); } cbPersist[i] = new QCheckBox(this); @@ -165,7 +175,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, disableMouseScrolling(); tableLayout->resizeColumnsToContents(); - tableLayout->pushRowsUp(lsCapability+1); + tableLayout->pushRowsUp(lsCapability + 1); } LogicalSwitchesPanel::~LogicalSwitchesPanel() @@ -174,6 +184,19 @@ LogicalSwitchesPanel::~LogicalSwitchesPanel() delete rawSwitchFilteredModel; } +void LogicalSwitchesPanel::onNameEdited() +{ + QLineEdit *le = qobject_cast(sender()); + int index = le->property("index").toInt(); + + if (model->logicalSw[index].custName != le->text()) { + strcpy(model->logicalSw[index].custName, le->text().toLatin1()); + if (model->logicalSw[index].func != LS_FN_OFF) + updateItemModels(); + emit modified(); + } +} + void LogicalSwitchesPanel::onFunctionChanged() { if (!lock) { @@ -377,6 +400,8 @@ void LogicalSwitchesPanel::updateLine(int i) if (!model->logicalSw[i].isEmpty()) { mask = LINE_ENABLED | DELAY_ENABLED | DURATION_ENABLED; + name[i]->setText(model->logicalSw[i].custName); + switch (model->logicalSw[i].getFunctionFamily()) { case LS_FAMILY_VOFS: @@ -412,6 +437,7 @@ void LogicalSwitchesPanel::updateLine(int i) case LS_FAMILY_STICKY: // no break mask |= PERSIST_ENABLED; cbPersist[i]->setChecked(model->logicalSw[i].lsPersist); + case LS_FAMILY_SAFE: // no break case LS_FAMILY_VBOOL: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; cbSource1[i]->setModel(rawSwitchFilteredModel); @@ -490,7 +516,8 @@ void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b) LS_FN_DPOS, LS_FN_DAPOS, LS_FN_TIMER, - LS_FN_STICKY + LS_FN_STICKY, + LS_FN_SAFE, }; b->clear(); @@ -620,6 +647,7 @@ void LogicalSwitchesPanel::cmClear(bool prompt) model->logicalSw[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); + name[selectedIndex]->clear(); updateLine(selectedIndex); updateItemModels(); emit modified(); @@ -632,6 +660,7 @@ void LogicalSwitchesPanel::cmClearAll() for (int i = 0; i < lsCapability; i++) { model->logicalSw[i].clear(); + name[i]->clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, i); } update(); diff --git a/companion/src/modeledit/logicalswitches.h b/companion/src/modeledit/logicalswitches.h index 3b0fb4a9ac6..88d5a3bd414 100644 --- a/companion/src/modeledit/logicalswitches.h +++ b/companion/src/modeledit/logicalswitches.h @@ -19,8 +19,7 @@ * GNU General Public License for more details. */ -#ifndef _LOGICALSWITCHES_H_ -#define _LOGICALSWITCHES_H_ +#pragma once #include "modeledit.h" #include "radiodata.h" @@ -43,6 +42,7 @@ class LogicalSwitchesPanel : public ModelPanel private slots: void onFunctionChanged(); + void onNameEdited(); void onV1Changed(int value); void onV2Changed(int value); void onAndSwitchChanged(int value); @@ -66,6 +66,7 @@ class LogicalSwitchesPanel : public ModelPanel void onItemModelUpdateComplete(); private: + QLineEdit *name[CPN_MAX_LOGICAL_SWITCHES]; QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES]; QDoubleSpinBox * dsbValue[CPN_MAX_LOGICAL_SWITCHES]; QDoubleSpinBox * dsbOffset[CPN_MAX_LOGICAL_SWITCHES]; @@ -94,5 +95,3 @@ class LogicalSwitchesPanel : public ModelPanel void updateItemModels(); void connectItemModelEvents(const FilteredItemModel * itemModel); }; - -#endif // _LOGICALSWITCHES_H_ diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index bf083532352..fc09832c62e 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -399,6 +399,18 @@ QString ModelPrinter::printMixerLine(const MixData & mix, bool showMultiplex, in { QString str = " "; + if (firmware->getCapability(HasMixerNames) && mix.name[0]){ + std::string strMixName(mix.name); + str += QString(" [%1]").arg(mix.name).toHtmlEscaped(); + for (int i = 0; i < (6- strMixName.length()); i++) { + str += " "; + } + } + else { + str += "       "; + } + str += "     "; + if (showMultiplex) { switch(mix.mltpx) { case (1): str += "*="; break; @@ -541,6 +553,9 @@ QString ModelPrinter::printLogicalSwitchLine(int idx) if (ls.lsPersist) result += tr(" Persistent"); break; + case LS_FAMILY_SAFE: + result += tr("Safe") + QString("(%1, %2)").arg(sw1Name).arg(sw2Name); + break; case LS_FAMILY_TIMER: result += tr("Timer") + QString("(%1, %2)").arg(ValToTim(ls.val1)).arg(ValToTim(ls.val2)); break; diff --git a/companion/src/simulation/radiooutputswidget.cpp b/companion/src/simulation/radiooutputswidget.cpp index 74f109f1526..ef6419cc22a 100644 --- a/companion/src/simulation/radiooutputswidget.cpp +++ b/companion/src/simulation/radiooutputswidget.cpp @@ -283,6 +283,11 @@ void RadioOutputsWidget::setupLsDisplay() QWidget * RadioOutputsWidget::createLogicalSwitch(QWidget * parent, int switchNo) { + //TODO: place logicSwitch friendly name on radio output window. + //int modelindex = RadioData().generalSettings.currModelIndex; + //ModelData &model = RadioData().models[modelindex]; + //QString namestring = model.logicalSw[switchNo].custName; + QLabel * swtch = new QLabel(parent); swtch->setAutoFillBackground(true); swtch->setFrameStyle(QFrame::Panel | QFrame::Raised); @@ -298,7 +303,8 @@ QWidget * RadioOutputsWidget::createLogicalSwitch(QWidget * parent, int switchNo #endif font.setBold(false); swtch->setFont(font); - swtch->setText(QString("%1").arg(switchNo+1, 2, 10, QChar('0'))); + swtch->setText(QString("%1").arg(switchNo+1, 2, 10, QChar('0')) ); + //swtch->setText(QString("%1").arg(switchNo+1, 2, 10, QChar('0')) + ": " + namestring); swtch->setAlignment(Qt::AlignCenter); m_logicSwitchMap.insert(switchNo, swtch); return swtch; diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index abfd5603b63..e3a3f4eea39 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -135,6 +135,9 @@ enum CurveType { #define MAX_CURVE_POINTS 512 #endif +#define LEN_SPEC_FN_NAME 10 +#define LEN_LOGICSW_NAME 10 + #define NUM_MODULES 2 #define XPOTS_MULTIPOS_COUNT 6 diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 6215d367e68..bcf1e995b84 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -45,14 +45,14 @@ static inline void check_struct() CHKSIZE(ExpoData, 18); CHKSIZE(SwashRingData, 8); CHKSIZE(CurveHeader, 4); - CHKSIZE(LogicalSwitchData, 9); + CHKSIZE(LogicalSwitchData, 19); CHKSIZE(TelemetrySensor, 14); CHKSIZE(ModuleData, 29); CHKSIZE(GVarData, 7); CHKSIZE(RFAlarmData, 2); CHKSIZE(TrainerData, 16); CHKSIZE(FlightModeData, 22 + 2 * MAX_TRIMS + LEN_FLIGHT_MODE_NAME); - CHKSIZE(CustomFunctionData, 11); + CHKSIZE(CustomFunctionData, 21); #if defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) CHKSIZE(LimitData, 11); @@ -83,33 +83,33 @@ static inline void check_struct() #endif #if defined(PCBXLITES) - CHKSIZE(RadioData, 871); + CHKSIZE(RadioData, 1511); #elif defined(COLORLCD) - CHKSIZE(RadioData, 965); + CHKSIZE(RadioData, 1605); #else - CHKSIZE(RadioData, 869); + CHKSIZE(RadioData, 1509); #endif #if defined(RADIO_TPRO) || defined(RADIO_TPROV2) - CHKSIZE(ModelData, 6354); + CHKSIZE(ModelData, 7634); #elif defined(RADIO_T14) || defined(RADIO_T12MAX) - CHKSIZE(ModelData, 6329); + CHKSIZE(ModelData, 7609); #elif defined(RADIO_FAMILY_T20) - CHKSIZE(ModelData, 6390); + CHKSIZE(ModelData, 7670); #elif defined(PCBX9E) - CHKSIZE(ModelData, 6771); + CHKSIZE(ModelData, 8051); #elif defined(PCBX9D) || defined(PCBX9DP) - CHKSIZE(ModelData, 6770); + CHKSIZE(ModelData, 8050); #elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) - CHKSIZE(ModelData, 6329); + CHKSIZE(ModelData, 7609); #elif defined(PCBNV14) - CHKSIZE(ModelData, 21899); + CHKSIZE(ModelData, 23179); #elif defined(PCBPL18) - CHKSIZE(ModelData, 22201); + CHKSIZE(ModelData, 23481); #elif defined(RADIO_T15) - CHKSIZE(ModelData, 22190); + CHKSIZE(ModelData, 23470); #elif defined(PCBHORUS) - CHKSIZE(ModelData, 22165); + CHKSIZE(ModelData, 23445); #else #error CHKSIZE not set up #endif diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 4a22abd8222..1bdd2a0587a 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -159,6 +159,7 @@ PACK(struct LogicalSwitchData { int16_t v2 SKIP; uint8_t delay; uint8_t duration; + NOBACKUP(char custName[LEN_LOGICSW_NAME]); }); /* @@ -168,6 +169,7 @@ PACK(struct LogicalSwitchData { PACK(struct CustomFunctionData { int16_t swtch:10 CUST(r_swtchSrc,w_swtchSrc); uint16_t func:6 ENUM(Functions); // TODO: 6 bits for Functions? + NOBACKUP(char custName[LEN_SPEC_FN_NAME]); CUST_ATTR(def,r_customFn,w_customFn); PACK(union { NOBACKUP(PACK(struct { diff --git a/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp b/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp index 11ae108fd1b..139cb85a244 100644 --- a/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp +++ b/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp @@ -111,6 +111,14 @@ class LogicalSwitchDisplayFooter : public Window char s[20]; + //LS friendly name + /*const char* chrs = cs->custName; + if (strlen(chrs) > 0) { + dc->drawText(15, 1, cs->custName, textColor); + } else { + dc->drawTextAtIndex(5, 1, STR_VCSWFUNC, cs->func, textColor); + }*/ + lv_label_set_text(lsFunc, STR_VCSWFUNC[ls->func]); // CSW params - V1 @@ -118,6 +126,7 @@ class LogicalSwitchDisplayFooter : public Window case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: case LS_FAMILY_EDGE: + case LS_FAMILY_SAFE: lv_label_set_text(lsV1, getSwitchPositionName(ls->v1)); break; case LS_FAMILY_TIMER: @@ -135,6 +144,7 @@ class LogicalSwitchDisplayFooter : public Window switch (lsFamily) { case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: + case LS_FAMILY_SAFE: lv_label_set_text(lsV2, getSwitchPositionName(ls->v2)); break; case LS_FAMILY_EDGE: diff --git a/radio/src/gui/colorlcd/model/model_logical_switches.cpp b/radio/src/gui/colorlcd/model/model_logical_switches.cpp index 1c0e5654711..4bde9d4693c 100644 --- a/radio/src/gui/colorlcd/model/model_logical_switches.cpp +++ b/radio/src/gui/colorlcd/model/model_logical_switches.cpp @@ -108,6 +108,10 @@ class LogicalSwitchEditPage : public Page LogicalSwitchData* cs = lswAddress(index); uint8_t cstate = lswFamily(cs->func); + // new StaticText(logicalSwitchOneWindow, grid.getLabelSlot(), STR_CUST_LOGICALSWITCH_LABEL, 0, COLOR_THEME_PRIMARY1); + // new ModelTextEdit(logicalSwitchOneWindow, grid.getFieldSlot(), cs->custName, LEN_LOGICSW_NAME); + // grid.nextLine(); + // V1 auto line = logicalSwitchOneWindow->newLine(grid); new StaticText(line, rect_t{}, STR_V1); @@ -115,6 +119,7 @@ class LogicalSwitchEditPage : public Page case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: case LS_FAMILY_EDGE: + case LS_FUNC_SAFE: choice = new SwitchChoice( line, rect_t{}, SWSRC_FIRST_IN_LOGICAL_SWITCHES, SWSRC_LAST_IN_LOGICAL_SWITCHES, GET_SET_DEFAULT(cs->v1)); @@ -216,11 +221,13 @@ class LogicalSwitchEditPage : public Page } // AND switch - line = logicalSwitchOneWindow->newLine(grid); - new StaticText(line, rect_t{}, STR_AND_SWITCH); - choice = new SwitchChoice(line, rect_t{}, -MAX_LS_ANDSW, MAX_LS_ANDSW, - GET_SET_DEFAULT(cs->andsw)); - choice->setAvailableHandler(isSwitchAvailableInLogicalSwitches); + if (cs->func != LS_FUNC_SAFE) { + line = logicalSwitchOneWindow->newLine(grid); + new StaticText(line, rect_t{}, STR_AND_SWITCH); + choice = new SwitchChoice(line, rect_t{}, -MAX_LS_ANDSW, MAX_LS_ANDSW, + GET_SET_DEFAULT(cs->andsw)); + choice->setAvailableHandler(isSwitchAvailableInLogicalSwitches); + } // Duration line = logicalSwitchOneWindow->newLine(grid); @@ -426,11 +433,14 @@ class LogicalSwitchButton : public ListLineButton lsName, getSwitchPositionName(SWSRC_FIRST_LOGICAL_SWITCH + index)); lv_label_set_text(lsFunc, STR_VCSWFUNC[ls->func]); + //dc->drawText(col1, line1, ls->custName, COLOR_THEME_SECONDARY1); + // CSW params - V1 switch (lsFamily) { case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: case LS_FAMILY_EDGE: + case LS_FUNC_SAFE: lv_label_set_text(lsV1, getSwitchPositionName(ls->v1)); break; case LS_FAMILY_TIMER: @@ -453,6 +463,7 @@ class LogicalSwitchButton : public ListLineButton switch (lsFamily) { case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: + case LS_FUNC_SAFE: lv_label_set_text(lsV2, getSwitchPositionName(ls->v2)); break; case LS_FAMILY_EDGE: diff --git a/radio/src/gui/colorlcd/model/special_functions.cpp b/radio/src/gui/colorlcd/model/special_functions.cpp index 3deabf01726..bc7a1815d1c 100644 --- a/radio/src/gui/colorlcd/model/special_functions.cpp +++ b/radio/src/gui/colorlcd/model/special_functions.cpp @@ -145,6 +145,9 @@ void FunctionLineButton::refresh() lv_label_set_text(sfName, (prefix + std::to_string(index + 1)).c_str()); lv_label_set_text(sfSwitch, getSwitchPositionName(CFN_SWITCH(cfn))); + //paint special function custom name + //dc->drawText(col3, line1, cfn->custName, COLOR_THEME_SECONDARY1); + strcpy(s, funcGetLabel(func)); strcat(s, " - "); @@ -624,9 +627,14 @@ void FunctionEditPage::buildBody(Window *form) FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY); CustomFunctionData *cfn = customFunctionData(); + auto line = form->newLine(grid); + + // Custom label + new StaticText(line, rect_t{}, STR_CUST_FUNC_CUST_LABEL); + new ModelTextEdit(line, rect_t{}, cfn->custName, LEN_SPEC_FN_NAME); + line = form->newLine(grid); // Switch - auto line = form->newLine(grid); new StaticText(line, rect_t{}, STR_SF_SWITCH); auto switchChoice = new SwitchChoice(line, rect_t{}, SWSRC_FIRST, SWSRC_LAST, GET_SET_DEFAULT(CFN_SWITCH(cfn))); diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 5621ff0fd51..e9acd59d4b3 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -210,6 +210,7 @@ enum LogicalSwitchesFunctions { LS_FUNC_ADIFFEGREATER, LS_FUNC_TIMER, LS_FUNC_STICKY, + LS_FUNC_SAFE, LS_FUNC_COUNT SKIP, LS_FUNC_MAX SKIP = LS_FUNC_COUNT-1 }; diff --git a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp index 007a4b2c2ec..f1e26751138 100644 --- a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -470,6 +472,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -804,8 +807,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index 0f99fa061b6..874fc18d167 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -1921,6 +1921,14 @@ static void r_logicSw(void* user, uint8_t* data, uint32_t bitoffs, ls->v2 = r_swtchSrc(nullptr, val, val_len); break; + case LS_FAMILY_SAFE: + ls->v1 = r_swtchSrc(nullptr, val, l_sep); + val += l_sep; val_len -= l_sep; + if (!val_len || val[0] != ',') return; + val++; val_len--; + ls->v2 = r_swtchSrc(nullptr, val, val_len); + break; + case LS_FAMILY_EDGE: ls->v1 = r_swtchSrc(nullptr, val, l_sep); val += l_sep; val_len -= l_sep; @@ -1988,6 +1996,12 @@ static bool w_logicSw(void* user, uint8_t* data, uint32_t bitoffs, if (!w_swtchSrc_unquoted(&_ls_node_v2, ls->v2, wf, opaque)) return false; break; + case LS_FAMILY_SAFE: + if (!w_swtchSrc_unquoted(&_ls_node_v1, ls->v1, wf, opaque)) return false; + if (!wf(opaque,",",1)) return false; + if (!w_swtchSrc_unquoted(&_ls_node_v2, ls->v2, wf, opaque)) return false; + break; + case LS_FAMILY_EDGE: if (!w_swtchSrc_unquoted(&_ls_node_v1, ls->v1, wf, opaque)) return false; if (!wf(opaque,",",1)) return false; diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index e8a98b6f012..a359e187e8e 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -140,6 +140,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -274,6 +275,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -350,7 +352,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -496,6 +498,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -838,8 +841,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp index 90508b4ea08..ee63a32f06b 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp @@ -140,6 +140,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -274,6 +275,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -350,7 +352,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -496,6 +498,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -838,8 +841,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_t15.cpp b/radio/src/storage/yaml/yaml_datastructs_t15.cpp index 01f6d577a4a..a4cb14b8447 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t15.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t15.cpp @@ -141,6 +141,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -275,6 +276,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -349,7 +351,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -498,6 +500,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -844,8 +847,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_t20.cpp b/radio/src/storage/yaml/yaml_datastructs_t20.cpp index c39a02703b7..5f12ac3a31d 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t20.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t20.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -470,6 +472,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -804,8 +807,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp index da473f47238..94f5bd0a4c7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -470,6 +472,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -804,8 +807,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index 78b36eed5a1..ca08b6ed62c 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -141,6 +141,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -275,6 +276,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -349,7 +351,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -498,6 +500,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -839,8 +842,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp index 78b36eed5a1..ca08b6ed62c 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp @@ -141,6 +141,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -275,6 +276,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -349,7 +351,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -498,6 +500,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -839,8 +842,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp index 5b1c439b7db..4f24948f54c 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -469,6 +471,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -803,8 +806,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp index c1a49413cfc..64d8b4a8936 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -470,6 +472,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -804,8 +807,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp index 239e008d68e..35c05e42110 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp @@ -133,6 +133,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -258,6 +259,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -334,7 +336,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -473,6 +475,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -807,8 +810,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 166b6c45607..0bb1534fc93 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -511,77 +511,79 @@ bool getLogicalSwitch(uint8_t idx) LogicalSwitchContext &context = lswFm[mixerCurrentFlightMode].lsw[idx]; bool result; - swsrc_t s = ls->andsw; + if (ls->func == LS_FAMILY_SAFE) { + result = lswFm[mixerCurrentFlightMode].lsw[idx].state; + } else { + swsrc_t s = ls->andsw; - if (ls->func == LS_FUNC_NONE || (s && !getSwitch(s))) { - if (ls->func != LS_FUNC_STICKY && ls->func != LS_FUNC_EDGE ) { - // AND switch must not affect STICKY and EDGE processing - context.lastValue = CS_LAST_VALUE_INIT; - } - result = false; - } - else if ((s=lswFamily(ls->func)) == LS_FAMILY_BOOL) { - bool res1 = getSwitch(ls->v1); - bool res2 = getSwitch(ls->v2); - switch (ls->func) { - case LS_FUNC_AND: - result = (res1 && res2); - break; - case LS_FUNC_OR: - result = (res1 || res2); - break; - // case LS_FUNC_XOR: - default: - result = (res1 ^ res2); - break; + if (ls->func == LS_FUNC_NONE || (s && !getSwitch(s))) { + if (ls->func != LS_FUNC_STICKY && ls->func != LS_FUNC_EDGE ) { + // AND switch must not affect STICKY and EDGE processing + LS_LAST_VALUE(mixerCurrentFlightMode, idx) = CS_LAST_VALUE_INIT; + } + result = false; } - } - else if (s == LS_FAMILY_TIMER) { - result = (context.lastValue <= 0); - } - else if (s == LS_FAMILY_STICKY) { - result = (context.lastValue & (1<<0)); - } - else if (s == LS_FAMILY_EDGE) { - result = (context.lastValue & (1<<0)); - } - else { - getvalue_t x = getValueForLogicalSwitch(ls->v1); - getvalue_t y; - if (s == LS_FAMILY_COMP) { - y = getValueForLogicalSwitch(ls->v2); - + else if ((s=lswFamily(ls->func)) == LS_FAMILY_BOOL) { + bool res1 = getSwitch(ls->v1); + bool res2 = getSwitch(ls->v2); switch (ls->func) { - case LS_FUNC_EQUAL: - result = (x==y); + case LS_FUNC_AND: + result = (res1 && res2); break; - case LS_FUNC_GREATER: - result = (x>y); + case LS_FUNC_OR: + result = (res1 || res2); break; + // case LS_FUNC_XOR: default: - result = (xv1; - // Telemetry - if (v1 >= MIXSRC_FIRST_TELEM) { - if (!TELEMETRY_STREAMING() || IS_FAI_FORBIDDEN(v1-1)) { - result = false; - goto DurationAndDelayProcessing; - } + getvalue_t x = getValueForLogicalSwitch(ls->v1); + getvalue_t y; + if (s == LS_FAMILY_COMP) { + y = getValueForLogicalSwitch(ls->v2); + + switch (ls->func) { + case LS_FUNC_EQUAL: + result = (x == y); + break; + case LS_FUNC_GREATER: + result = (x > y); + break; + default: + result = (x < y); + break; + } + } else { + mixsrc_t v1 = ls->v1; + // Telemetry + if (v1 >= MIXSRC_FIRST_TELEM) { + if (!TELEMETRY_STREAMING() || IS_FAI_FORBIDDEN(v1 - 1)) { + result = false; + goto DurationAndDelayProcessing; + } - y = convertLswTelemValue(ls); + y = convertLswTelemValue(ls); - } - else if (v1 >= MIXSRC_FIRST_GVAR) { - y = ls->v2; - } - else { - y = calc100toRESX(ls->v2); - } + } + else if (v1 >= MIXSRC_FIRST_GVAR) { + y = ls->v2; + } + else { + y = calc100toRESX(ls->v2); + } switch (ls->func) { case LS_FUNC_VEQUAL: @@ -645,44 +647,43 @@ bool getLogicalSwitch(uint8_t idx) } } -DurationAndDelayProcessing: - - if (ls->delay || ls->duration) { - if (result) { - if (context.timerState == SWITCH_START) { - // set delay timer - context.timerState = SWITCH_DELAY; - context.timer = (ls->func == LS_FUNC_EDGE ? 0 : ls->delay); - } + DurationAndDelayProcessing: - if (context.timerState == SWITCH_DELAY) { - if (context.timer) { - result = false; // return false while delay timer running + if (ls->delay || ls->duration) { + if (result) { + if (context.timerState == SWITCH_START) { + // set delay timer + context.timerState = SWITCH_DELAY; + context.timer = (ls->func == LS_FUNC_EDGE ? 0 : ls->delay); } - else { - // set duration timer - context.timerState = SWITCH_ENABLE; - context.timer = ls->duration; + + if (context.timerState == SWITCH_DELAY) { + if (context.timer) { + result = false; // return false while delay timer running + } else { + // set duration timer + context.timerState = SWITCH_ENABLE; + context.timer = ls->duration; + } } - } - if (context.timerState == SWITCH_ENABLE) { - result = (ls->duration==0 || context.timer>0); // return false after duration timer runs out - if (!result && ls->func == LS_FUNC_STICKY) { - ls_sticky_struct & lastValue = (ls_sticky_struct &)context.lastValue; - lastValue.state = 0; + if (context.timerState == SWITCH_ENABLE) { + result = (ls->duration == 0 || context.timer > 0); // return false after duration timer runs out + if (!result && ls->func == LS_FUNC_STICKY) { + ls_sticky_struct &lastValue = (ls_sticky_struct &)context.lastValue; + lastValue.state = 0; + } } + } else if (context.timerState == SWITCH_ENABLE && ls->duration > 0 && + context.timer > 0) { + result = true; + } else { + context.timerState = SWITCH_START; + context.timer = 0; } } - else if (context.timerState == SWITCH_ENABLE && ls->duration > 0 && context.timer > 0) { - result = true; - } - else { - context.timerState = SWITCH_START; - context.timer = 0; - } } - + } return result; } @@ -775,28 +776,53 @@ uint8_t getXPotPosition(uint8_t idx) return potsPos[idx] & 0x0F; } +void evalLogicalSwitch_FUNC_SAFE(LogicalSwitchData *ls, + LogicalSwitchContext &context) +{ + if (ls->v1 != SWSRC_NONE) { + if (getSwitch(ls->v2)) { + // ON + if (getSwitch(ls->v1)) { + context.state = 1; + } + // OFF + if (!getSwitch(ls->v1)) { + context.state = 0; + } + } + } else { // no source set therfore switch is off + context.state = 0; + } +} /** @brief Calculates new state of logical switches for mixerCurrentFlightMode */ void evalLogicalSwitches(bool isCurrentFlightmode) { + for (unsigned int idx=0; idxfunc == LS_FUNC_SAFE) { + evalLogicalSwitch_FUNC_SAFE(ls, context); + } else { + bool result = getLogicalSwitch(idx); + if (isCurrentFlightmode) { + if (result) { + if (!context.state) PLAY_LOGICAL_SWITCH_ON(idx); + } + else { + if (context.state) PLAY_LOGICAL_SWITCH_OFF(idx); + } } - else { - if (context.state) PLAY_LOGICAL_SWITCH_OFF(idx); + context.state = result; + if ((g_model.logicalSw[idx].func == LS_FUNC_STICKY) && (g_model.logicalSw[idx].lsState != result)) { + g_model.logicalSw[idx].lsState = result; + storageDirty(EE_MODEL); } } - context.state = result; - if ((g_model.logicalSw[idx].func == LS_FUNC_STICKY) && (g_model.logicalSw[idx].lsState != result)) { - g_model.logicalSw[idx].lsState = result; - storageDirty(EE_MODEL); - } } } @@ -1076,6 +1102,7 @@ void logicalSwitchesTimerTick() for (uint8_t fm=0; fmfunc == LS_FUNC_TIMER) { int16_t * lastValue = &LS_LAST_VALUE(fm, i); if (*lastValue == 0 || *lastValue == CS_LAST_VALUE_INIT) { @@ -1115,7 +1142,11 @@ void logicalSwitchesTimerTick() } } } - } + } + else if (ls->func == LS_FUNC_SAFE) { + LogicalSwitchContext &context = lswFm[mixerCurrentFlightMode].lsw[i]; + evalLogicalSwitch_FUNC_SAFE(ls, context); + } else if (ls->func == LS_FUNC_EDGE) { ls_stay_struct & lastValue = (ls_stay_struct &)LS_LAST_VALUE(fm, i); // if this ls was reset by the logicalSwitchesReset() the lastValue will be set to CS_LAST_VALUE_INIT(0x8000) diff --git a/radio/src/switches.h b/radio/src/switches.h index 08ea25f56f3..f0792f8db1c 100644 --- a/radio/src/switches.h +++ b/radio/src/switches.h @@ -32,6 +32,7 @@ enum LogicalSwitchFamilies { LS_FAMILY_DIFF, LS_FAMILY_TIMER, LS_FAMILY_STICKY, + LS_FAMILY_SAFE, LS_FAMILY_RANGE, LS_FAMILY_EDGE }; diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index b3e7e7b7274..3f2e5b4bac5 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -337,7 +337,9 @@ const char STR_MENUCURVES[] = TR_MENUCURVES; const char STR_MENUCURVE[] = TR_MENUCURVE; const char STR_MENULOGICALSWITCH[] = TR_MENULOGICALSWITCH; const char STR_MENULOGICALSWITCHES[] = TR_MENULOGICALSWITCHES; +const char STR_CUST_LOGICALSWITCH_LABEL[] = TR_CUST_LOGICALSWITCH_LABEL; const char STR_MENUCUSTOMFUNC[] = TR_MENUCUSTOMFUNC; +const char STR_CUST_FUNC_CUST_LABEL[] = TR_CUST_FUNC_CUST_LABEL; const char STR_SPLASHSCREEN[] = TR_SPLASHSCREEN; const char STR_PLAY_HELLO[] = TR_PLAY_HELLO; const char STR_PWR_ON_DELAY[] = TR_PWR_ON_DELAY; diff --git a/radio/src/translations.h b/radio/src/translations.h index 775c624782d..10ff8ddafc3 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -526,7 +526,9 @@ extern const char STR_MENUCURVES[]; extern const char STR_MENUCURVE[]; extern const char STR_MENULOGICALSWITCH[]; extern const char STR_MENULOGICALSWITCHES[]; +extern const char STR_CUST_LOGICALSWITCH_LABEL[]; extern const char STR_MENUCUSTOMFUNC[]; +extern const char STR_CUST_FUNC_CUST_LABEL[]; extern const char STR_MENUCUSTOMSCRIPTS[]; extern const char STR_MENUTELEMETRY[]; extern const char STR_MENUSTAT[]; diff --git a/radio/src/translations/cn.h b/radio/src/translations/cn.h index 4b359121c5a..ffe0c21be38 100644 --- a/radio/src/translations/cn.h +++ b/radio/src/translations/cn.h @@ -76,6 +76,7 @@ #define TR_CSWTIMER "定时" #define TR_CSWSTICKY "粘滞" #define TR_CSWSTAY "边沿" +#define TR_CSWSAFE "Safe" #define TR_CSWEQUAL "a=x" #define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","a= 212 #define TR_CSWTIMER "Stopky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTICKY "Sticky" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" + #define TR_CSWSAFE "Safe" #define TR_CSWSTICKY "Stky" #define TR_CSWSTAY "Edge" #endif diff --git a/radio/src/translations/da.h b/radio/src/translations/da.h index 416b3f8108c..19bba4ae92a 100644 --- a/radio/src/translations/da.h +++ b/radio/src/translations/da.h @@ -82,15 +82,17 @@ #if LCD_W >= 212 #define TR_CSWTIMER "Tid" #define TR_CSWSTICKY "Sej" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tid" #define TR_CSWSTICKY "Sej" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Takt" // TIM = Takt = Taktgenerator #define TR_CSWSTICKY "SRFF" // Sticky = RS-Flip-Flop + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Puls" // Edge = einstellbarer Impuls #else #define TR_CSWTIMER "Takt" // TIM = Takt = Taktgenerator #define TR_CSWSTICKY "SRFF" // Sticky = RS-Flip-Flop + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Puls" // Edge = einstellbarer Impuls #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Pega" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Borde" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Pega" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Bord" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Chrono" #define TR_CSWSTICKY "Bistb" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Chrono" #define TR_CSWSTICKY "Bist" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Glue" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stały" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Brzeg" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stały" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Brzeg" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Seg" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Kant" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Seg" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Kant" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "定時" #define TR_CSWSTICKY "粘滯" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "邊沿" #else #define TR_CSWTIMER "定時" #define TR_CSWSTICKY "粘滯" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "邊沿" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a