feat: add inverted sources (#4722)

Co-authored-by: elecpower <neilh713@tpg.com.au>
This commit is contained in:
Neil Horne
2024-05-25 09:25:15 +10:00
committed by GitHub
co-authored by elecpower
parent ca50d4ee04
commit 80659c3e3f
87 changed files with 798 additions and 496 deletions
+2
View File
@@ -92,6 +92,8 @@
#define CPN_STR_SW_INDICATOR_NEUT QCoreApplication::translate("RawSwitch", "-") // Switch neutral (middle) position indicator.
#define CPN_STR_SW_INDICATOR_REV QCoreApplication::translate("RawSwitch", "!") // Switch reversed logic (NOT) indicator.
#define CPN_STR_SRC_INDICATOR_INVERT QCoreApplication::translate("RawSource", "!") // Source inverted logic indicator.
#define EDGETX_HOME_PAGE_URL "https://edgetx.org"
#define CPN_ADC_REFACTOR_VERSION "2.10.0"
@@ -106,11 +106,31 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett
setId(IMID_RawSource);
setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts));
// Descending source direction: inverted (!) sources
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, -firmware->getCapability(Sensors) * 3);
addItems(SOURCE_TYPE_TIMER, RawSource::TelemGroup, -firmware->getCapability(Timers));
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, -(SOURCE_TYPE_SPECIAL_COUNT - 1));
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, -firmware->getCapability(Gvars));
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, -firmware->getCapability(Outputs));
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, -firmware->getCapability(TrainerInputs));
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, -CPN_MAX_CYC);
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, -firmware->getCapability(LogicalSwitches));
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, -board->getCapability(Board::Switches));
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, -1);
addItems(SOURCE_TYPE_MIN, RawSource::SourcesGroup, -1);
addItems(SOURCE_TYPE_SPACEMOUSE, RawSource::SourcesGroup, -CPN_MAX_SPACEMOUSE);
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, -board->getCapability(Board::NumTrims));
addItems(SOURCE_TYPE_INPUT, RawSource::SourcesGroup, -board->getCapability(Board::Inputs));
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, -firmware->getCapability(VirtualInputs));
for (int i = firmware->getCapability(LuaScripts) - 1; i >= 0; i--)
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, -firmware->getCapability(LuaOutputsPerScript), -i * 16);
// Ascending source direction (including zero)
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
for (int i = 0; i < firmware->getCapability(LuaScripts); i++)
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, firmware->getCapability(LuaOutputsPerScript), i * 16);
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, firmware->getCapability(VirtualInputs));
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board->getCapability(Board::Inputs));
addItems(SOURCE_TYPE_INPUT, RawSource::SourcesGroup, board->getCapability(Board::Inputs));
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board->getCapability(Board::NumTrims));
addItems(SOURCE_TYPE_SPACEMOUSE, RawSource::SourcesGroup, CPN_MAX_SPACEMOUSE);
addItems(SOURCE_TYPE_MIN, RawSource::SourcesGroup, 1);
@@ -121,7 +141,8 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, firmware->getCapability(TrainerInputs));
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, firmware->getCapability(Outputs));
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, firmware->getCapability(Gvars));
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, SOURCE_TYPE_SPECIAL_COUNT);
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, SOURCE_TYPE_SPECIAL_COUNT - 1);
addItems(SOURCE_TYPE_TIMER, RawSource::TelemGroup, firmware->getCapability(Timers));
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, firmware->getCapability(Sensors) * 3);
}
@@ -131,14 +152,19 @@ void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSourc
item->setData(src.isAvailable(modelData, generalSettings, boardType), IMDR_Available);
}
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, int count, const int start)
{
for (int i = start; i < start + count; i++) {
const RawSource src = RawSource(type, i);
const int idxAdj = (type == SOURCE_TYPE_NONE ? -1 : 0);
int first = start + count < 0 ? start + count : start + 1;
int last = start + count < 0 ? start : start + count + 1;
for (int i = first; i < last; ++i) {
const RawSource src = RawSource(type, i + idxAdj);
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(src.toValue(), IMDR_Id);
modelItem->setData(type, IMDR_Type);
modelItem->setData(group, IMDR_Flags);
modelItem->setData((group | (i + idxAdj < 0 ? RawSource::NegativeGroup : i > 0 ? RawSource::PositiveGroup : 0)), IMDR_Flags);
setDynamicItemData(modelItem, src);
appendRow(modelItem);
}
@@ -197,7 +197,7 @@ class RawSourceItemModel: public AbstractDynamicItemModel
protected:
virtual void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
void addItems(const RawSourceType & type, const int group, int count, const int start = 0);
};
class RawSwitchItemModel: public AbstractDynamicItemModel
@@ -61,7 +61,7 @@ QString AdjustmentReference::toString(const ModelData * model, const bool sign)
switch(type) {
case ADJUST_REF_GVAR:
ret = RawSource(SOURCE_TYPE_GVAR, abs(value) - 1).toString(model);
ret = RawSource(SOURCE_TYPE_GVAR, abs(value)).toString(model);
if (value < 0)
ret.prepend("-");
else if (sign)
+1 -2
View File
@@ -80,8 +80,7 @@ Boards::Boards(Board::Type board) :
legacyTrimSourcesLookupTable(legacyTrimSourcesLut),
trimSwitchesLookupTable(trimSwitchesLut),
rawSwitchTypesLookupTable(RawSwitch::getRawSwitchTypesLookupTable()),
rawSourceSpecialTypesLookupTable(RawSource::getSpecialTypesLookupTable()),
rawSourceCyclicLookupTable(RawSource::getCyclicLookupTable())
rawSourceSpecialTypesLookupTable(RawSource::getSpecialTypesLookupTable())
{
setBoardType(board);
}
-2
View File
@@ -355,7 +355,6 @@ class Boards
STRINGTAGMAPPINGFUNCS(trimSwitchesLookupTable, TrimSwitch);
STRINGTAGMAPPINGFUNCS(rawSwitchTypesLookupTable, RawSwitchType);
STRINGTAGMAPPINGFUNCS(rawSourceSpecialTypesLookupTable, RawSourceSpecialType);
STRINGTAGMAPPINGFUNCS(rawSourceCyclicLookupTable, RawSourceCyclic);
static bool isInputAvailable(int index, Board::Type board = Board::BOARD_UNKNOWN);
static bool isInputCalibrated(int index, Board::Type board = Board::BOARD_UNKNOWN);
@@ -382,7 +381,6 @@ class Boards
const StringTagMappingTable trimSwitchesLookupTable;
const StringTagMappingTable rawSwitchTypesLookupTable;
const StringTagMappingTable rawSourceSpecialTypesLookupTable;
const StringTagMappingTable rawSourceCyclicLookupTable;
static StringTagMappingTable getLegacyAnalogsLookupTable(Board::Type board = Board::BOARD_UNKNOWN);
};
@@ -62,7 +62,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData * model)
{
if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast)
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func + 1).toString(model));
else if (func == FuncTrainer)
return tr("Trainer Axis");
else if (func == FuncTrainerRUD)
@@ -84,7 +84,7 @@ QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData
else if (func == FuncReset)
return tr("Reset");
else if (func >= FuncSetTimer1 && func <= FuncSetTimerLast)
return tr("Set %1").arg(RawSource(SOURCE_TYPE_SPECIAL, SOURCE_TYPE_SPECIAL_FIRST_TIMER + func - FuncSetTimer1).toString(model));
return tr("Set %1").arg(RawSource(SOURCE_TYPE_TIMER, func - FuncSetTimer1 + 1).toString(model));
else if (func == FuncVario)
return tr("Vario");
else if (func == FuncPlayPrompt)
@@ -108,7 +108,7 @@ QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData
else if (func == FuncBackgroundMusicPause)
return tr("Background Music Pause");
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast)
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func - FuncAdjustGV1).toString(model));
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func - FuncAdjustGV1 + 1).toString(model));
else if (func == FuncSetFailsafe)
return tr("Set Failsafe");
else if (func == FuncRangeCheckInternalModule)
@@ -281,7 +281,7 @@ QString CustomFunctionData::resetToString(const int value, const ModelData * mod
if (value < step) {
if (value < firmware->getCapability(Timers))
return RawSource(SOURCE_TYPE_SPECIAL, value + SOURCE_TYPE_SPECIAL_FIRST_TIMER).toString(model);
return RawSource(SOURCE_TYPE_TIMER, value).toString(model);
else
return QString(CPN_STR_UNKNOWN_ITEM);
}
@@ -293,7 +293,7 @@ QString CustomFunctionData::resetToString(const int value, const ModelData * mod
return tr("Telemetry");
if (value < step + firmware->getCapability(Sensors))
return RawSource(SOURCE_TYPE_TELEMETRY, 3 * (value - step)).toString(model);
return RawSource(SOURCE_TYPE_TELEMETRY, 3 * (value - step + 1)).toString(model);
return QString(CPN_STR_UNKNOWN_ITEM);
}
@@ -36,7 +36,6 @@ class AbstractStaticItemModel;
enum AssignFunc {
FuncOverrideCH1 = 0,
FuncOverrideCHLast = FuncOverrideCH1 + CPN_MAX_CHNOUT - 1,
FuncOverrideCH32 = FuncOverrideCHLast, // TODO remove
FuncTrainer,
FuncTrainerRUD,
FuncTrainerELE,
@@ -48,8 +47,6 @@ enum AssignFunc {
FuncPlayHaptic,
FuncReset,
FuncSetTimer1,
FuncSetTimer2, // TODO remove
FuncSetTimer3, // TODO remove
FuncSetTimerLast = FuncSetTimer1 + CPN_MAX_TIMERS - 1,
FuncVario,
FuncPlayPrompt,
@@ -167,7 +167,7 @@ struct YamlThrTrace {
YamlThrTrace(unsigned int cpn_value)
{
if (cpn_value == 0) {
src = RawSource(SOURCE_TYPE_STICK, 2/* throttle */);
src = RawSource(SOURCE_TYPE_INPUT, 2/* throttle */);
return;
}
cpn_value--;
@@ -175,7 +175,7 @@ struct YamlThrTrace {
int pots = board.getCapability(Board::Pots);
int sliders = board.getCapability(Board::Sliders);
if (cpn_value < (unsigned int)(pots + sliders)) {
src = RawSource(SOURCE_TYPE_STICK, 4/* sticks */ + cpn_value);
src = RawSource(SOURCE_TYPE_INPUT, 4/* sticks */ + cpn_value);
}
else {
cpn_value -= pots + sliders;
@@ -186,7 +186,7 @@ struct YamlThrTrace {
unsigned int toCpn()
{
switch (src.type) {
case SOURCE_TYPE_STICK:
case SOURCE_TYPE_INPUT:
if (src.index == 2 /* throttle */) {
return 0;
} else {
+106 -71
View File
@@ -23,37 +23,47 @@
#include "boardjson.h"
static const YamlLookupTable spacemouseLut = {
{ 0, "SPACEMOUSE_A" },
{ 1, "SPACEMOUSE_B" },
{ 2, "SPACEMOUSE_C" },
{ 3, "SPACEMOUSE_D" },
{ 4, "SPACEMOUSE_E" },
{ 5, "SPACEMOUSE_F" },
{ 0, "INVALID" },
{ 1, "SPACEMOUSE_A" },
{ 2, "SPACEMOUSE_B" },
{ 3, "SPACEMOUSE_C" },
{ 4, "SPACEMOUSE_D" },
{ 5, "SPACEMOUSE_E" },
{ 6, "SPACEMOUSE_F" },
};
std::string YamlRawSourceEncode(const RawSource& rhs)
{
Board::Type board = getCurrentBoard();
Boards b = Boards(board);
std::string src_str;
div_t qr;
char c = 'A';
int32_t sval = rhs.index;
if (rhs.index < 0) {
sval = -sval;
src_str += "!";
}
switch (rhs.type) {
case SOURCE_TYPE_VIRTUAL_INPUT:
src_str += "I" + std::to_string(rhs.index);
src_str += "I" + std::to_string(sval - 1);
break;
case SOURCE_TYPE_LUA_OUTPUT:
qr = div(sval - 1, 16);
src_str += "lua(";
src_str += std::to_string(rhs.index / 16);
src_str += std::to_string(qr.quot);
src_str += ",";
src_str += std::to_string(rhs.index % 16);
src_str += std::to_string(qr.rem);
src_str += ")";
break;
case SOURCE_TYPE_STICK:
src_str = Boards::getInputYamlName(rhs.index, BoardJson::YLT_REF).toStdString();
case SOURCE_TYPE_INPUT:
src_str += Boards::getInputYamlName(sval - 1, BoardJson::YLT_REF).toStdString();
break;
case SOURCE_TYPE_TRIM:
src_str = Boards::getTrimYamlName(rhs.index, BoardJson::YLT_REF).toStdString();
src_str += Boards::getTrimYamlName(sval - 1, BoardJson::YLT_REF).toStdString();
break;
case SOURCE_TYPE_MIN:
src_str += "MIN";
@@ -62,37 +72,41 @@ std::string YamlRawSourceEncode(const RawSource& rhs)
src_str += "MAX";
break;
case SOURCE_TYPE_SWITCH:
src_str += Boards::getSwitchYamlName(rhs.index, BoardJson::YLT_REF).toStdString();
src_str += Boards::getSwitchYamlName(sval - 1, BoardJson::YLT_REF).toStdString();
break;
case SOURCE_TYPE_CUSTOM_SWITCH:
src_str += "ls(";
src_str += std::to_string(rhs.index + 1);
src_str += std::to_string(sval);
src_str += ")";
break;
case SOURCE_TYPE_CYC:
src_str = b.getRawSourceCyclicTag(rhs.index);
src_str += "CYC" + std::to_string(sval);
break;
case SOURCE_TYPE_PPM:
src_str += "tr(";
src_str += std::to_string(rhs.index);
src_str += std::to_string(sval - 1);
src_str += ")";
break;
case SOURCE_TYPE_CH:
src_str += "ch(";
src_str += std::to_string(rhs.index);
src_str += std::to_string(sval - 1);
src_str += ")";
break;
case SOURCE_TYPE_GVAR:
src_str += "gv(";
src_str += std::to_string(rhs.index);
src_str += std::to_string(sval - 1);
src_str += ")";
break;
case SOURCE_TYPE_SPECIAL:
src_str = b.getRawSourceSpecialTypeTag(rhs.index);
src_str += b.getRawSourceSpecialTypeTag(sval);
break;
case SOURCE_TYPE_TIMER:
src_str += "Tmr" + std::to_string(sval);
break;
case SOURCE_TYPE_TELEMETRY:
src_str = "tele(";
switch (rhs.index % 3) {
qr = div(sval - 1, 3);
src_str += "tele(";
switch (qr.rem) {
case 0:
break;
case 1:
@@ -102,12 +116,12 @@ std::string YamlRawSourceEncode(const RawSource& rhs)
src_str += '+';
break;
}
src_str += std::to_string(rhs.index / 3);
src_str += std::to_string(qr.quot);
src_str += ")";
break;
case SOURCE_TYPE_SPACEMOUSE:
src_str = "SPACEMOUSE_";
c += rhs.index;
src_str += "SPACEMOUSE_";
c += sval - 1;
src_str += c;
break;
default:
@@ -124,13 +138,22 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
RawSource rhs;
const char* val = src_str.data();
size_t val_len = src_str.size();
std::string src_str_tmp = src_str;
bool neg = false;
if (val_len > 0 && val[0] == '!') {
neg = true;
val++;
val_len--;
src_str_tmp = src_str_tmp.substr(1);
}
if (val_len > 1 && val[0] == 'I'
&& (val[1] >= '0') && (val[1] <= '9')) {
int idx = std::stoi(src_str.substr(1));
int idx = std::stoi(src_str_tmp.substr(1));
if (idx < CPN_MAX_INPUTS) {
rhs = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, idx);
rhs = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, idx + 1);
}
} else if ((val_len == 2 &&
@@ -141,9 +164,9 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
(val[0] == 'S' && val[1] == 'W')) &&
val[2] >= '1' && val[2] <= '9')) {
int idx = Boards::getSwitchYamlIndex(src_str.c_str(), BoardJson::YLT_REF);
int idx = Boards::getSwitchYamlIndex(src_str_tmp.c_str(), BoardJson::YLT_REF);
if (idx >= 0) {
rhs = RawSource(SOURCE_TYPE_SWITCH, idx);
rhs = RawSource(SOURCE_TYPE_SWITCH, idx + 1);
}
} else if (val_len > 4 &&
@@ -152,24 +175,24 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
val[2] == 'a' &&
val[3] == '(') {
std::stringstream src(src_str.substr(4));
std::stringstream src(src_str_tmp.substr(4));
int script = 0, output = 0; // TODO: check rename outputs to inputs???
src >> script;
src.ignore();
src >> output;
if (script < CPN_MAX_SCRIPTS && output < CPN_MAX_SCRIPT_INPUTS)
rhs = RawSource(SOURCE_TYPE_LUA_OUTPUT, script * 16 + output);
rhs = RawSource(SOURCE_TYPE_LUA_OUTPUT, script * 16 + output + 1);
} else if (val_len > 3 &&
val[0] == 'l' &&
val[1] == 's' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
std::stringstream src(src_str_tmp.substr(3));
int ls = 0;
src >> ls;
if (ls > 0 && ls <= CPN_MAX_LOGICAL_SWITCHES)
rhs = RawSource(SOURCE_TYPE_CUSTOM_SWITCH, ls - 1);
rhs = RawSource(SOURCE_TYPE_CUSTOM_SWITCH, ls);
// appears depreciated - maybe early support for T20 as SWn the current std and no match in encode
} else if (val_len > 3 &&
@@ -177,13 +200,13 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
val[1] == 's' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
std::stringstream src(src_str_tmp.substr(3));
int fs = 0;
src >> fs;
if (fs > 0) {
int fsidx = Boards::getSwitchYamlIndex(QString("SW%1").arg(fs), BoardJson::YLT_REF);
if (fsidx >= 0)
rhs = RawSource(SOURCE_TYPE_SWITCH, fsidx);
rhs = RawSource(SOURCE_TYPE_SWITCH, fsidx + 1);
}
} else if (val_len > 3 &&
@@ -191,33 +214,33 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
val[1] == 'r' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
std::stringstream src(src_str_tmp.substr(3));
int tr = 0;
src >> tr;
if (tr < getCurrentFirmware()->getCapability(TrainerInputs))
rhs = RawSource(SOURCE_TYPE_PPM, tr);
rhs = RawSource(SOURCE_TYPE_PPM, tr + 1);
} else if (val_len > 3 &&
val[0] == 'c' &&
val[1] == 'h' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
std::stringstream src(src_str_tmp.substr(3));
int ch = 0;
src >> ch;
if (ch < CPN_MAX_CHNOUT)
rhs = RawSource(SOURCE_TYPE_CH, ch);
rhs = RawSource(SOURCE_TYPE_CH, ch + 1);
} else if (val_len > 3 &&
val[0] == 'g' &&
val[1] == 'v' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
std::stringstream src(src_str_tmp.substr(3));
int gv = 0;
src >> gv;
if (gv < CPN_MAX_GVARS)
rhs = RawSource(SOURCE_TYPE_GVAR, gv);
rhs = RawSource(SOURCE_TYPE_GVAR, gv + 1);
} else if (val_len > 5 &&
val[0] == 't' &&
@@ -226,7 +249,7 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
val[3] == 'e' &&
val[4] == '(') {
std::stringstream src(src_str.substr(5));
std::stringstream src(src_str_tmp.substr(5));
// parse sign
uint8_t sign = 0;
@@ -242,22 +265,32 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
int sensor = 0;
src >> sensor;
if (sensor < CPN_MAX_SENSORS)
rhs = RawSource(SOURCE_TYPE_TELEMETRY, sensor * 3 + sign);
rhs = RawSource(SOURCE_TYPE_TELEMETRY, sensor * 3 + sign + 1);
} else if (val_len > 3 &&
val[0] == 'C' &&
val[1] == 'Y' &&
val[2] == 'C' &&
val[3] >= '1' && val[3] <= '3') {
std::stringstream src(src_str_tmp.substr(3));
int cyc = 0;
src >> cyc;
if (cyc <= CPN_MAX_CYC)
rhs = RawSource(SOURCE_TYPE_CYC, cyc);
} else {
YAML::Node node(src_str);
YAML::Node node(src_str_tmp);
if (node.IsScalar() && node.as<std::string>() == "MAX") {
rhs.type = SOURCE_TYPE_MAX;
rhs.index = 0;
return rhs;
rhs.index = 1;
}
if (node.IsScalar() && node.as<std::string>() == "MIN") {
rhs.type = SOURCE_TYPE_MIN;
rhs.index = 0;
return rhs;
rhs.index = 1;
}
std::string ana_str;
@@ -272,16 +305,15 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
int ana_idx = Boards::getInputYamlIndex(ana_str.c_str(), BoardJson::YLT_REF);
if (ana_idx >= 0) {
rhs.type = SOURCE_TYPE_STICK;
rhs.index = ana_idx;
return rhs;
rhs.type = SOURCE_TYPE_INPUT;
rhs.index = ana_idx + 1;
}
std::string trim_str;
node >> trim_str;
if (modelSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
int idx = b.getLegacyTrimSourceIndex(src_str.c_str());
int idx = b.getLegacyTrimSourceIndex(src_str_tmp.c_str());
if (idx >= 0)
trim_str = Boards::getTrimYamlName(idx, BoardJson::YLT_REF).toStdString();
}
@@ -289,31 +321,32 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
int trm_idx = Boards::getTrimYamlIndex(trim_str.c_str(), BoardJson::YLT_REF);
if (trm_idx >= 0) {
rhs.type = SOURCE_TYPE_TRIM;
rhs.index = trm_idx;
return rhs;
rhs.index = trm_idx + 1;
}
std::string timer_str;
node >> timer_str;
if (modelSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
if (timer_str.size() == 6 && timer_str.substr(0, 5) == "TIMER") {
timer_str = "Tmr" + timer_str.substr(5, 1);
}
}
if (timer_str.substr(0, 3) == "Tmr" && timer_str.substr(3, 1) >= "1" && timer_str.substr(3, 1) <= "9") {
if (std::stoi(timer_str.substr(3, 1)) <= CPN_MAX_TIMERS) {
rhs.type = SOURCE_TYPE_TIMER;
rhs.index = std::stoi(timer_str.substr(3, 1));
}
}
std::string special_str;
node >> special_str;
if (modelSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
if (special_str.size() == 6 && special_str.substr(0, 5) == "TIMER") {
special_str = "Tmr" + special_str.substr(5, 1);
}
}
int sp_idx = b.getRawSourceSpecialTypeIndex(special_str.c_str());
if (sp_idx >= 0) {
if (sp_idx > 0) {
rhs.type = SOURCE_TYPE_SPECIAL;
rhs.index = sp_idx;
return rhs;
}
int cyc_idx = b.getRawSourceCyclicIndex(src_str.c_str());
if (cyc_idx >= 0) {
rhs.type = SOURCE_TYPE_CYC;
rhs.index = cyc_idx;
return rhs;
}
if (node.IsScalar() && node.as<std::string>().size() == 12 && node.as<std::string>().substr(0, 11) == "SPACEMOUSE_") {
@@ -321,12 +354,14 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
node >> spacemouseLut >> sm_idx;
if (sm_idx >= 0) {
rhs.type = SOURCE_TYPE_SPACEMOUSE;
rhs.index = sm_idx;
return rhs;
rhs.index = sm_idx + 1;
}
}
}
if (neg)
rhs.index = -rhs.index;
return rhs;
}
@@ -98,7 +98,8 @@ RawSwitch YamlRawSwitchDecode(const std::string& sw_str)
// yaml-cpp does not escape this
if (val_len > 0 && val[0] == '\\') {
val++; val_len--;
val++;
val_len--;
sw_str_tmp = sw_str_tmp.substr(1);
}
+6 -6
View File
@@ -187,14 +187,14 @@ t_Er9xMixData::operator MixData ()
c9x.sOffset=gvar;
} else {
c9x.sOffset=sOffset;
}
}
c9x.swtch = er9xToSwitch(swtch);
if (srcRaw == 0) {
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
}
else if (srcRaw <= 7) {
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
c9x.srcRaw = RawSource(SOURCE_TYPE_INPUT, srcRaw-1);
}
else if (srcRaw == 8) {
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
@@ -221,9 +221,9 @@ t_Er9xMixData::operator MixData ()
}
else if (srcRaw <=37) {
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21);
}
}
else {
c9x.srcRaw = RawSource(SOURCE_TYPE_GVAR, srcRaw-38);
c9x.srcRaw = RawSource(SOURCE_TYPE_GVAR, srcRaw-38);
}
if (differential==1) {
@@ -257,7 +257,7 @@ RawSource er9xToSource(int8_t value)
return RawSource(SOURCE_TYPE_NONE);
}
else if (value <= 7) {
return RawSource(SOURCE_TYPE_STICK, value - 1);
return RawSource(SOURCE_TYPE_INPUT, value - 1);
}
else if (value == 8) {
return RawSource(SOURCE_TYPE_MAX);
@@ -285,7 +285,7 @@ Er9xLogicalSwitchData::operator LogicalSwitchData ()
c9x.func = func;
c9x.val1 = v1;
c9x.val2 = v2;
if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) {
c9x.val1 = er9xToSource(v1).toValue();
}
@@ -186,7 +186,7 @@ t_Ersky9xMixData_v10::operator MixData ()
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
}
else if (srcRaw <= 7) {
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
c9x.srcRaw = RawSource(SOURCE_TYPE_INPUT, srcRaw-1);
}
else if (srcRaw == 8) {
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
@@ -256,7 +256,7 @@ t_Ersky9xMixData_v11::operator MixData ()
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
}
else if (srcRaw <= 7) {
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
c9x.srcRaw = RawSource(SOURCE_TYPE_INPUT, srcRaw-1);
}
else if (srcRaw == 8) {
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
@@ -318,7 +318,7 @@ RawSource ersky9xToSource_v10(int8_t value)
return RawSource(SOURCE_TYPE_NONE);
}
else if (value <= 7) {
return RawSource(SOURCE_TYPE_STICK, value - 1);
return RawSource(SOURCE_TYPE_INPUT, value - 1);
}
else if (value == 8) {
return RawSource(SOURCE_TYPE_MAX);
@@ -346,7 +346,7 @@ RawSource ersky9xToSource_v11(int8_t value)
return RawSource(SOURCE_TYPE_NONE);
}
else if (value <= 7) {
return RawSource(SOURCE_TYPE_STICK, value - 1);
return RawSource(SOURCE_TYPE_INPUT, value - 1);
}
else if (value == 8) {
return RawSource(SOURCE_TYPE_MAX);
+1 -1
View File
@@ -382,7 +382,7 @@ RawSource GeneralSettings::getDefaultSource(unsigned int channel) const
{
int stick = getDefaultStick(channel);
if (stick >= 0)
return RawSource(SOURCE_TYPE_STICK, stick);
return RawSource(SOURCE_TYPE_INPUT, stick + 1);
else
return RawSource(SOURCE_TYPE_NONE);
}
+1 -1
View File
@@ -59,7 +59,7 @@ AbstractStaticItemModel * ExpoData::carryTrimItemModel()
mdl->setName(AIM_EXPO_CARRYTRIM);
ExpoData tmp = ExpoData();
tmp.srcRaw = RawSource(SOURCE_TYPE_STICK, 0);
tmp.srcRaw = RawSource(SOURCE_TYPE_INPUT, 0);
for (int i = -CARRYTRIM_STICK_OFF; i <= Boards::getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) {
tmp.carryTrim = -i;
+7 -11
View File
@@ -210,7 +210,7 @@ void ModelData::setDefaultMixes(const GeneralSettings & settings)
MixData * mix = &mixData[i];
mix->destCh = i + 1;
mix->weight = 100;
mix->srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i);
mix->srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i + 1);
}
}
@@ -446,7 +446,7 @@ void ModelData::convert(RadioDataConversionState & cstate)
cstate.setComponent("Settings", 0);
if (thrTraceSrc && (int)thrTraceSrc < cstate.fromBoard.getCapability(Board::Pots) + cstate.fromBoard.getCapability(Board::Sliders)) {
cstate.setSubComp(tr("Throttle Source"));
thrTraceSrc = RawSource(SOURCE_TYPE_STICK, (int)thrTraceSrc + 3).convert(cstate).index - 3;
thrTraceSrc = RawSource(SOURCE_TYPE_INPUT, (int)thrTraceSrc + 3).convert(cstate).index - 3;
}
Firmware *fw = getCurrentFirmware();
@@ -603,12 +603,8 @@ int ModelData::updateReference()
updRefInfo.occurences = 3;
break;
case REF_UPD_TYPE_TIMER:
updRefInfo.srcType = SOURCE_TYPE_SPECIAL;
updRefInfo.srcType = SOURCE_TYPE_TIMER;
updRefInfo.maxindex = fw->getCapability(Timers);
// rawsource index offset TODO refactor timers so be own category
updRefInfo.index1 += 2;
updRefInfo.index2 += 2;
updRefInfo.maxindex += 2;
break;
default:
qDebug() << "Error - unhandled reference type:" << updRefInfo.type;
@@ -1030,7 +1026,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
switch (updRefInfo.type)
{
case REF_UPD_TYPE_CHANNEL:
if(cfd->func < FuncOverrideCH1 || cfd->func > FuncOverrideCH32) // TODO refactor to FuncOverrideCHLast
if(cfd->func < FuncOverrideCH1 || cfd->func > FuncOverrideCHLast)
return;
idxAdj = FuncOverrideCH1;
break;
@@ -1040,9 +1036,9 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
idxAdj = FuncAdjustGV1;
break;
case REF_UPD_TYPE_TIMER:
if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimer3) // TODO refactor to FuncSetTimerLast
if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimerLast)
return;
idxAdj = FuncSetTimer1 - 2; // reverse earlier offset required for rawsource
idxAdj = FuncSetTimer1;
break;
default:
return;
@@ -1526,7 +1522,7 @@ bool ModelData::isThrTraceSrcAvailable(const GeneralSettings * generalSettings,
const Board::Type board = getCurrentBoard();
if (index > 0 && index <= Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders))
return RawSource(SOURCE_TYPE_STICK, index + Boards::getCapability(board, Board::Sticks) - 1).isAvailable(this, generalSettings, board);
return RawSource(SOURCE_TYPE_INPUT, index + Boards::getCapability(board, Board::Sticks) - 1).isAvailable(this, generalSettings, board);
else
return true;
}
+2 -2
View File
@@ -381,13 +381,13 @@ class ModelData {
void updateTelemetryRef(int & idx);
void updateTelemetryRef(unsigned int & idx);
void updateModuleFailsafes(ModuleData * md);
inline void updateSourceRef(RawSource & src) { updateTypeIndexRef<RawSource, RawSourceType>(src, updRefInfo.srcType); }
inline void updateSourceRef(RawSource & src) { updateTypeIndexRef<RawSource, RawSourceType>(src, updRefInfo.srcType, 1); }
inline void updateSwitchRef(RawSwitch & swtch) { updateTypeIndexRef<RawSwitch, RawSwitchType>(swtch, updRefInfo.swtchType, 1); }
inline void updateTimerMode(RawSwitch & swtch) { updateTypeIndexRef<RawSwitch, RawSwitchType>(swtch, updRefInfo.swtchType, 1, false, (int)SWITCH_TYPE_TIMER_MODE, 0); }
inline void updateSourceIntRef(int & value)
{
RawSource src = RawSource(value);
updateTypeIndexRef<RawSource, RawSourceType>(src, updRefInfo.srcType);
updateTypeIndexRef<RawSource, RawSourceType>(src, updRefInfo.srcType, 1);
if (value != src.toValue())
value = src.toValue();
}
+35 -30
View File
@@ -307,6 +307,7 @@ inline int MAX_TRIMS(Board::Type board)
#define ROTENC_COUNT(board, version) ((IS_STM32(board) && version >= 218) ? 0 : 1)
#define MAX_AUX_TRIMS(board) ((IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) ? 2 : 0)
#define MAX_SOURCE_TYPE_SPECIAL(board, version) SOURCE_TYPE_SPECIAL_COUNT
#define MAX_TIMERS(board, version) 3
inline int switchIndex(int i, Board::Type board, unsigned int version)
{
@@ -457,7 +458,7 @@ class SourcesConversionTable: public ConversionTable {
}
if (version >= 218 || IS_STM32(board)) {
for (int i=0; i<32; i++) {
for (int i=1; i<=32; i++) {
addConversion(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i), val++);
}
}
@@ -465,7 +466,7 @@ class SourcesConversionTable: public ConversionTable {
if (IS_STM32(board)) {
for (int i = 0; i < MAX_SCRIPTS(board); i++) {
for (int j = 0; j < 6; j++) {
addConversion(RawSource(SOURCE_TYPE_LUA_OUTPUT, i * 16 + j), val++);
addConversion(RawSource(SOURCE_TYPE_LUA_OUTPUT, i * 16 + j + 1), val++);
}
}
}
@@ -484,10 +485,12 @@ class SourcesConversionTable: public ConversionTable {
int offset = 0;
if (version <= 218 && IS_HORUS_X10(board) && i >= CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version))
offset += 2;
// ADC refactor shuffles
//if (version <= 220 && (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) && i >= CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version))
// offset += 2;
// ADC refactor shuffles
if (IS_FAMILY_HORUS_OR_T16(board)) {
if (i >= 7 && i <= 8)
offset += 2;
@@ -502,47 +505,50 @@ class SourcesConversionTable: public ConversionTable {
}
// end ADC refactor shuffles
addConversion(RawSource(SOURCE_TYPE_STICK, i + offset), val++);
//qDebug() << "i:" << i << "offset:" << offset << "index:" << i + offset << "desc:" << RawSource(SOURCE_TYPE_STICK, i + offset).toString() << "val:" << val;
addConversion(RawSource(SOURCE_TYPE_INPUT, i + offset + 1), val++);
// qDebug() << "i:" << i << "offset:" << offset << "index:" << i + offset + 1 << "desc:" << RawSource(SOURCE_TYPE_STICK, i + offset).toString() << "val:" << val;
}
for (int i=0; i<MAX_ROTARY_ENCODERS(board); i++) {
for (int i = 1; i <= MAX_ROTARY_ENCODERS(board); i++) {
addConversion(RawSource(SOURCE_TYPE_ROTARY_ENCODER, 0), val++);
}
addConversion(RawSource(SOURCE_TYPE_MAX), val++);
for (int i=0; i<3; i++)
for (int i = 1; i <= 3; i++)
addConversion(RawSource(SOURCE_TYPE_CYC, i), val++);
for (int i=0; i<MAX_TRIMS(board); i++)
for (int i = 1; i <= MAX_TRIMS(board); i++)
addConversion(RawSource(SOURCE_TYPE_TRIM, i), val++);
addConversion(RawSource(SOURCE_TYPE_SWITCH, 0), val++);
if (!(flags & FLAG_NOSWITCHES)) {
for (int i=1; i<MAX_SWITCHES_SOURCE(board, version); i++)
for (int i = 1; i <= MAX_SWITCHES_SOURCE(board, version); i++) {
addConversion(RawSource(SOURCE_TYPE_SWITCH, i), val++);
for (int i=0; i<MAX_FUNCTIONSWITCHES(board, version); i++)
addConversion(RawSource(SOURCE_TYPE_FUNCTIONSWITCH, i), val++);
for (int i=0; i<MAX_LOGICAL_SWITCHES(board, version); i++)
}
for (int i = 1; i <= MAX_FUNCTIONSWITCHES(board, version); i++) {
addConversion(RawSource(SOURCE_TYPE_FUNCTIONSWITCH, i), val++);
}
for (int i = 1; i <= MAX_LOGICAL_SWITCHES(board, version); i++) {
addConversion(RawSource(SOURCE_TYPE_CUSTOM_SWITCH, i), val++);
}
}
for (int i=0; i<NUM_PPM_INPUTS(board, version); i++) {
for (int i = 1; i <= NUM_PPM_INPUTS(board, version); i++) {
addConversion(RawSource(SOURCE_TYPE_PPM, i), val++);
}
for (int i=0; i<MAX_CHANNELS(board, version); i++) {
for (int i = 1; i <= MAX_CHANNELS(board, version); i++) {
addConversion(RawSource(SOURCE_TYPE_CH, i), val++);
}
if (!(flags & FLAG_NOTELEMETRY)) {
for (int i=0; i<MAX_GVARS(board, version); i++)
for (int i = 1; i <= MAX_GVARS(board, version); i++)
addConversion(RawSource(SOURCE_TYPE_GVAR, i), val++);
for (int i=0; i<MAX_SOURCE_TYPE_SPECIAL(board, version); i++)
for (int i = 1; i < MAX_SOURCE_TYPE_SPECIAL(board, version); i++) // exception '<' NOT '<=' due to moving TIMERS to own TYPE
addConversion(RawSource(SOURCE_TYPE_SPECIAL, i), val++);
for (int i=0; i<MAX_TELEMETRY_SENSORS(board, version)*3; ++i) {
for (int i = 1; i <= MAX_TIMERS(board, version); i++)
addConversion(RawSource(SOURCE_TYPE_TIMER, i), val++);
for (int i = 1; i <= MAX_TELEMETRY_SENSORS(board, version)*3; ++i) {
addConversion(RawSource(SOURCE_TYPE_TELEMETRY, i), val++);
}
}
@@ -1211,7 +1217,7 @@ class InputField: public TransformedField {
void afterImport() override
{
if (!IS_STM32(board) && expo.mode) {
expo.srcRaw = RawSource(SOURCE_TYPE_STICK, expo.chn);
expo.srcRaw = RawSource(SOURCE_TYPE_INPUT, expo.chn);
}
expo.weight = smallGvarExport(_weight);
@@ -1609,12 +1615,11 @@ class CustomFunctionsConversionTable: public ConversionTable {
addConversion(FuncInstantTrim, val++);
addConversion(FuncReset, val++);
addConversion(FuncSetTimer1, val);
addConversion(FuncSetTimer2, val);
addConversion(FuncSetTimer3, val);
for (int i = 0; i < MAX_TIMERS(board, version); i++)
addConversion(FuncSetTimer1 + i, val);
val++;
for (int i=0; i<MAX_GVARS(board, version); i++)
addConversion(FuncAdjustGV1+i, val);
for (int i = 0; i < MAX_GVARS(board, version); i++)
addConversion(FuncAdjustGV1 + i, val);
val++;
addConversion(FuncVolume, val++);
addConversion(FuncSetFailsafe, val++);
@@ -1723,14 +1728,14 @@ class ArmCustomFunctionField: public TransformedField {
else
_active = (fn.enabled ? 1 : 0);
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCH32) {
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCHLast) {
*((uint16_t *)_param) = fn.param;
*((uint8_t *)(_param+3)) = fn.func - FuncOverrideCH1;
}
else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerChannels) {
*((uint8_t *)(_param+3)) = fn.func - FuncTrainer;
}
else if (fn.func >= FuncSetTimer1 && fn.func <= FuncSetTimer3) {
else if (fn.func >= FuncSetTimer1 && fn.func <= FuncSetTimerLast) {
*((uint16_t *)_param) = fn.param;
*((uint8_t *)(_param+3)) = fn.func - FuncSetTimer1;
}
@@ -1783,11 +1788,11 @@ class ArmCustomFunctionField: public TransformedField {
mode = *((uint8_t *)(_param+2));
index = *((uint8_t *)(_param+3));
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCH32) {
if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCHLast) {
fn.func = AssignFunc(fn.func + index);
fn.param = (int16_t)(uint16_t)value;
}
else if (fn.func >= FuncSetTimer1 && fn.func <= FuncSetTimer3) {
else if (fn.func >= FuncSetTimer1 && fn.func <= FuncSetTimerLast) {
fn.func = AssignFunc(fn.func + index);
fn.param = (int)value;
}
@@ -1807,7 +1812,7 @@ class ArmCustomFunctionField: public TransformedField {
if (fn.adjustMode == 1)
sourcesConversionTable->importValue(value, (int &)fn.param);
else if (fn.adjustMode == 2)
fn.param = RawSource(SOURCE_TYPE_GVAR, value).toValue();
fn.param = RawSource(SOURCE_TYPE_GVAR, value + 1).toValue();
else
fn.param = (int16_t)value;
}
+96 -97
View File
@@ -85,7 +85,7 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
}
case SOURCE_TYPE_SPECIAL:
if (index == 0) { //Batt
if (index == 0) { //Batt
result.step = 0.1;
result.decimals = 1;
result.max = 25.5;
@@ -100,12 +100,13 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
result.max = 30000;
result.min = -result.max;
}
else { // Timers 1 - 3
result.step = 1;
result.max = 9 * 60 * 60 - 1; // 8:59:59 (to match firmware)
result.min = -result.max;
result.unit = tr("s");
}
break;
case SOURCE_TYPE_TIMER:
result.step = 1;
result.max = 9 * 60 * 60 - 1; // 8:59:59 (to match firmware)
result.min = -result.max;
result.unit = tr("s");
break;
case SOURCE_TYPE_CH:
@@ -128,27 +129,25 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
QString RawSource::toString(const ModelData * model, const GeneralSettings * const generalSettings, Board::Type board, bool prefixCustomName) const
{
if (board == Board::BOARD_UNKNOWN) {
if (index < 0)
return CPN_STR_SRC_INDICATOR_INVERT % RawSource(type, -index).toString(model, generalSettings, board, prefixCustomName);
if (board == Board::BOARD_UNKNOWN)
board = getCurrentBoard();
}
static const QString trims[] = {
tr("TrmR"), tr("TrmE"), tr("TrmT"), tr("TrmA"), tr("Trm5"), tr("Trm6"), tr("Trm7"), tr("Trm8")
"", tr("TrmR"), tr("TrmE"), tr("TrmT"), tr("TrmA"), tr("Trm5"), tr("Trm6"), tr("Trm7"), tr("Trm8")
};
static const QString trims2[] = {
tr("TrmH"), tr("TrmV")
"", tr("TrmH"), tr("TrmV")
};
static const QString special[] = {
tr("Batt"), tr("Time"), tr("GPS"), tr("Reserved1"), tr("Reserved2"), tr("Reserved3"), tr("Reserved4")
"", tr("Batt"), tr("Time"), tr("GPS"), tr("Reserved1"), tr("Reserved2"), tr("Reserved3"), tr("Reserved4")
};
static const QString rotary[] = { tr("REa"), tr("REb") };
if (index < 0) {
return QString(CPN_STR_UNKNOWN_ITEM);
}
static const QString rotary[] = { "", tr("REa"), tr("REb") };
QString result;
QString dfltName;
@@ -161,18 +160,21 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
case SOURCE_TYPE_VIRTUAL_INPUT:
{
const char * name = nullptr;
if (model)
name = model->inputNames[index];
return RadioData::getElementName(tr("I", "as in Input"), index + 1, name);
if (model && index <= CPN_MAX_INPUTS)
name = model->inputNames[index - 1];
return RadioData::getElementName(tr("I", "as in Input"), index, name);
}
case SOURCE_TYPE_LUA_OUTPUT:
return tr("LUA%1%2").arg(index / 16 + 1).arg(QChar('a' + index % 16));
{
div_t qr = div(index - 1, 16);
return tr("LUA%1%2").arg(qr.quot + 1).arg(QChar('a' + qr.rem));
}
case SOURCE_TYPE_STICK:
dfltName = Boards::getInputName(index, board);
if (generalSettings)
custName = QString(generalSettings->inputConfig[index].name).trimmed();
case SOURCE_TYPE_INPUT:
dfltName = Boards::getInputName(index - 1, board);
if (generalSettings && index <= CPN_MAX_INPUTS)
custName = QString(generalSettings->inputConfig[index - 1].name).trimmed();
return DataHelpers::getCompositeName(dfltName, custName, prefixCustomName);
case SOURCE_TYPE_TRIM:
@@ -188,53 +190,53 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return tr("MAX");
case SOURCE_TYPE_SWITCH:
dfltName = Boards::getSwitchInfo(index, board).name.c_str();
if (Boards::isSwitchFunc(index, board)) {
if (model) {
int fsindex = Boards::getSwitchTagNum(index, board) - 1;
dfltName = Boards::getSwitchInfo(index - 1, board).name.c_str();
if (Boards::isSwitchFunc(index - 1, board)) {
if (model && index <= CPN_MAX_SWITCHES_FUNCTION) {
int fsindex = Boards::getSwitchTagNum(index - 1, board) - 1;
custName = QString(model->functionSwitchNames[fsindex]).trimmed();
}
}
else {
if (generalSettings) {
custName = QString(generalSettings->switchConfig[index].name).trimmed();
if (generalSettings && index <= CPN_MAX_SWITCHES) {
custName = QString(generalSettings->switchConfig[index - 1].name).trimmed();
}
}
return DataHelpers::getCompositeName(dfltName, custName, prefixCustomName);
case SOURCE_TYPE_CUSTOM_SWITCH:
return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1).toString();
return RawSwitch(SWITCH_TYPE_VIRTUAL, index).toString(); // RawSwitch uses 1 based index
case SOURCE_TYPE_CYC:
return tr("CYC%1").arg(index + 1);
return tr("CYC%1").arg(index);
case SOURCE_TYPE_PPM:
return RadioData::getElementName(tr("TR", "as in Trainer"), index + 1);
return RadioData::getElementName(tr("TR", "as in Trainer"), index);
case SOURCE_TYPE_CH:
if (model)
result = QString(model->limitData[index].nameToString(index)).trimmed();
if (model && index <= CPN_MAX_CHNOUT)
result = QString(model->limitData[index - 1].nameToString(index - 1)).trimmed();
if (result.isEmpty())
return LimitData().nameToString(index);
return LimitData().nameToString(index - 1);
return result;
case SOURCE_TYPE_SPECIAL:
if (index >= SOURCE_TYPE_SPECIAL_FIRST_TIMER && index <= SOURCE_TYPE_SPECIAL_LAST_TIMER) {
if (model)
result = QString(model->timers[index - SOURCE_TYPE_SPECIAL_FIRST_TIMER].nameToString(index - SOURCE_TYPE_SPECIAL_FIRST_TIMER)).trimmed();
if (result.isEmpty())
result = TimerData().nameToString(index - SOURCE_TYPE_SPECIAL_FIRST_TIMER);
}
else
result = CHECK_IN_ARRAY(special, index);
return CHECK_IN_ARRAY(special, index);
case SOURCE_TYPE_TIMER:
if (model && index <= CPN_MAX_TIMERS)
result = QString(model->timers[index - 1].nameToString(index - 1)).trimmed();
if (result.isEmpty())
result = TimerData().nameToString(index - 1);
return result;
case SOURCE_TYPE_TELEMETRY:
{
div_t qr = div(index, 3);
if (model)
div_t qr = div(index - 1, 3);
if (model && qr.quot < CPN_MAX_SENSORS)
result = QString(model->sensorData[qr.quot].nameToString(qr.quot)).trimmed();
if (result.isEmpty())
result = SensorData().nameToString(qr.quot);
@@ -244,14 +246,14 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
}
case SOURCE_TYPE_GVAR:
if (model)
result = QString(model->gvarData[index].nameToString(index)).trimmed();
if (model && index <= CPN_MAX_GVARS)
result = QString(model->gvarData[index - 1].nameToString(index - 1)).trimmed();
if (result.isEmpty())
result = GVarData().nameToString(index);
result = GVarData().nameToString(index - 1);
return result;
case SOURCE_TYPE_SPACEMOUSE:
return tr("sm%1").arg(QChar('A' + index));
return tr("sm%1").arg(QChar('A' + (index - 1)));
default:
return QString(CPN_STR_UNKNOWN_ITEM);
@@ -263,87 +265,100 @@ bool RawSource::isStick(Board::Type board) const
if (board == Board::BOARD_UNKNOWN)
board = getCurrentBoard();
if (type == SOURCE_TYPE_STICK && index < Boards::getCapability(board, Board::Sticks)) {
if (type == SOURCE_TYPE_INPUT && index - 1 < Boards::getCapability(board, Board::Sticks)) {
return true;
}
return false;
}
bool RawSource::isTimeBased(Board::Type board) const
{
return (type == SOURCE_TYPE_SPECIAL && index >= SOURCE_TYPE_SPECIAL_FIRST_TIMER && index <= SOURCE_TYPE_SPECIAL_LAST_TIMER);
}
bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings * const gs, Board::Type board) const
{
if (type == SOURCE_TYPE_NONE && index == 0)
return true;
if (board == Board::BOARD_UNKNOWN)
board = getCurrentBoard();
Boards b(board);
if (type == SOURCE_TYPE_STICK && index >= b.getCapability(Board::Inputs))
if (type == SOURCE_TYPE_CH && abs(index) > CPN_MAX_CHNOUT)
return false;
if (type == SOURCE_TYPE_SWITCH && index >= b.getCapability(Board::Switches))
if (type == SOURCE_TYPE_CUSTOM_SWITCH && abs(index) > CPN_MAX_LOGICAL_SWITCHES)
return false;
if (type == SOURCE_TYPE_SPECIAL && index >= SOURCE_TYPE_SPECIAL_FIRST_RESERVED && index <= SOURCE_TYPE_SPECIAL_LAST_RESERVED)
return false;
if (type == SOURCE_TYPE_LUA_OUTPUT && div(abs(index - 1), 16).quot >= CPN_MAX_SCRIPTS)
return false;
if (type == SOURCE_TYPE_INPUT && abs(index) > b.getCapability(Board::Inputs))
return false;
if (type == SOURCE_TYPE_SWITCH && abs(index) > b.getCapability(Board::Switches))
return false;
if (type == SOURCE_TYPE_SPECIAL && abs(index) >= SOURCE_TYPE_SPECIAL_FIRST_RESERVED)
return false;
if (type == SOURCE_TYPE_TIMER && abs(index) > CPN_MAX_TIMERS)
return false;
if (type == SOURCE_TYPE_TELEMETRY && div(abs(index), 3).quot > CPN_MAX_SENSORS)
return false;
if (model) {
if (type == SOURCE_TYPE_SPECIAL && index >= SOURCE_TYPE_SPECIAL_FIRST_TIMER && index <= SOURCE_TYPE_SPECIAL_LAST_TIMER &&
model->timers[index - SOURCE_TYPE_SPECIAL_FIRST_TIMER].isModeOff())
if (type == SOURCE_TYPE_TIMER && model->timers[abs(index) - 1].isModeOff())
return false;
if (type == SOURCE_TYPE_SWITCH && b.isSwitchFunc(index, board) &&
!model->isFunctionSwitchSourceAllowed(b.getSwitchTagNum(index, board) - 1))
if (type == SOURCE_TYPE_SWITCH && b.isSwitchFunc(abs(index) - 1, board) &&
!model->isFunctionSwitchSourceAllowed(b.getSwitchTagNum(abs(index) - 1, board) - 1))
return false;
if (type == SOURCE_TYPE_VIRTUAL_INPUT && !model->isInputValid(index))
if (type == SOURCE_TYPE_VIRTUAL_INPUT && !model->isInputValid(abs(index) - 1))
return false;
if (type == SOURCE_TYPE_PPM && model->trainerMode == TRAINER_MODE_OFF)
return false;
if (type == SOURCE_TYPE_CUSTOM_SWITCH && model->logicalSw[index].isEmpty())
if (type == SOURCE_TYPE_CUSTOM_SWITCH && model->logicalSw[abs(index) - 1].isEmpty())
return false;
if (type == SOURCE_TYPE_TELEMETRY) {
if (!model->sensorData[div(index, 3).quot].isAvailable()) {
if (!model->sensorData[div(abs(index) - 1, 3).quot].isAvailable()) {
return false;
}
}
if (type == SOURCE_TYPE_CH && !model->hasMixes(index))
if (type == SOURCE_TYPE_CH && !model->hasMixes(abs(index) - 1))
return false;
}
if (gs) {
if (type == SOURCE_TYPE_STICK) {
if (!gs->isInputAvailable(index))
if (type == SOURCE_TYPE_INPUT) {
if (!gs->isInputAvailable(abs(index) - 1))
return false;
if (gs->inputConfig[index].flexType == Board::FLEX_SWITCH)
if (gs->inputConfig[abs(index) - 1].flexType == Board::FLEX_SWITCH)
return false;
}
if (type == SOURCE_TYPE_SWITCH && !b.isSwitchFunc(index, board) && IS_HORUS_OR_TARANIS(board) &&
!gs->switchSourceAllowed(index))
if (type == SOURCE_TYPE_SWITCH && !b.isSwitchFunc(abs(index) - 1, board) && IS_HORUS_OR_TARANIS(board) &&
!gs->switchSourceAllowed(abs(index) - 1))
return false;
}
else {
if (type == SOURCE_TYPE_STICK) {
if (!Boards::isInputAvailable(index, board))
if (type == SOURCE_TYPE_INPUT) {
if (!Boards::isInputAvailable(abs(index) - 1, board))
return false;
if (Boards::getInputInfo(index, board).flexType == Board::FLEX_SWITCH)
if (Boards::getInputInfo(abs(index) - 1, board).flexType == Board::FLEX_SWITCH)
return false;
}
}
if (type == SOURCE_TYPE_TRIM && index >= b.getCapability(Board::NumTrims))
if (type == SOURCE_TYPE_TRIM && abs(index) > b.getCapability(Board::NumTrims))
return false;
if (type == SOURCE_TYPE_SPACEMOUSE &&
(index >= CPN_MAX_SPACEMOUSE ||
(abs(index) > CPN_MAX_SPACEMOUSE ||
(!(gs->serialPort[GeneralSettings::SP_AUX1] == GeneralSettings::AUX_SERIAL_SPACEMOUSE ||
gs->serialPort[GeneralSettings::SP_AUX2] == GeneralSettings::AUX_SERIAL_SPACEMOUSE))))
return false;
@@ -356,7 +371,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
cstate.setItemType(tr("SRC"), 1);
RadioDataConversionState::LogField oldData(index, toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType));
if (type == SOURCE_TYPE_STICK)
if (type == SOURCE_TYPE_INPUT)
index = Boards::getInputIndex(Boards::getInputTag(oldData.id, cstate.fromType), Board::LVT_TAG, cstate.toType);
else if (type == SOURCE_TYPE_SWITCH)
index = Boards::getSwitchIndex(Boards::getSwitchTag(oldData.id, cstate.fromType), Board::LVT_TAG, cstate.toType);
@@ -376,6 +391,7 @@ StringTagMappingTable RawSource::getSpecialTypesLookupTable()
StringTagMappingTable tbl;
tbl.insert(tbl.end(), {
{std::to_string(SOURCE_TYPE_SPECIAL_NONE), "NONE"},
{std::to_string(SOURCE_TYPE_SPECIAL_TX_BATT), "TX_VOLTAGE"},
{std::to_string(SOURCE_TYPE_SPECIAL_TX_TIME), "TX_TIME"},
{std::to_string(SOURCE_TYPE_SPECIAL_TX_GPS), "TX_GPS"},
@@ -383,23 +399,6 @@ tbl.insert(tbl.end(), {
{std::to_string(SOURCE_TYPE_SPECIAL_RESERVED2), "RESERVED2"},
{std::to_string(SOURCE_TYPE_SPECIAL_RESERVED3), "RESERVED3"},
{std::to_string(SOURCE_TYPE_SPECIAL_RESERVED4), "RESERVED4"},
{std::to_string(SOURCE_TYPE_SPECIAL_TIMER1), "Tmr1"},
{std::to_string(SOURCE_TYPE_SPECIAL_TIMER2), "Tmr2"},
{std::to_string(SOURCE_TYPE_SPECIAL_TIMER3), "Tmr3"},
});
return tbl;
}
// static
StringTagMappingTable RawSource::getCyclicLookupTable()
{
StringTagMappingTable tbl;
tbl.insert(tbl.end(), {
{"0", "CYC1"},
{"1", "CYC2"},
{"2", "CYC3"},
});
return tbl;
+12 -11
View File
@@ -31,6 +31,7 @@ class ModelData;
class GeneralSettings;
class RadioDataConversionState;
// TODO remove and refactor to use dynamic board switches
enum Switches {
SWITCH_NONE,
@@ -101,6 +102,7 @@ enum HeliSwashTypes {
};
enum TelemetrySource {
TELEMETRY_SOURCE_NONE,
TELEMETRY_SOURCE_TX_BATT,
TELEMETRY_SOURCE_TX_TIME,
TELEMETRY_SOURCE_TIMER1,
@@ -163,7 +165,7 @@ enum RawSourceType {
SOURCE_TYPE_NONE,
SOURCE_TYPE_VIRTUAL_INPUT,
SOURCE_TYPE_LUA_OUTPUT,
SOURCE_TYPE_STICK, // and POTS and Flex pots TODO rename to more appropriate
SOURCE_TYPE_INPUT,
SOURCE_TYPE_ROTARY_ENCODER,
SOURCE_TYPE_TRIM,
SOURCE_TYPE_MIN,
@@ -178,10 +180,12 @@ enum RawSourceType {
SOURCE_TYPE_SPECIAL,
SOURCE_TYPE_TELEMETRY,
SOURCE_TYPE_SPACEMOUSE,
SOURCE_TYPE_TIMER,
MAX_SOURCE_TYPE
};
enum RawSourceTypeSpecial {
SOURCE_TYPE_SPECIAL_NONE,
SOURCE_TYPE_SPECIAL_TX_BATT,
SOURCE_TYPE_SPECIAL_TX_TIME,
SOURCE_TYPE_SPECIAL_TX_GPS,
@@ -191,15 +195,10 @@ enum RawSourceTypeSpecial {
SOURCE_TYPE_SPECIAL_RESERVED3,
SOURCE_TYPE_SPECIAL_RESERVED4,
SOURCE_TYPE_SPECIAL_LAST_RESERVED = SOURCE_TYPE_SPECIAL_RESERVED4,
SOURCE_TYPE_SPECIAL_FIRST_TIMER,
SOURCE_TYPE_SPECIAL_TIMER1 = SOURCE_TYPE_SPECIAL_FIRST_TIMER,
SOURCE_TYPE_SPECIAL_TIMER2,
SOURCE_TYPE_SPECIAL_TIMER3,
SOURCE_TYPE_SPECIAL_LAST_TIMER = SOURCE_TYPE_SPECIAL_TIMER3,
SOURCE_TYPE_SPECIAL_COUNT
};
constexpr int SOURCE_TYPE_STICK_THR_IDX { 3 }; // TODO is there a function to determine index?
constexpr int SOURCE_TYPE_INPUT_THR_IDX { 3 }; // TODO is there a function to determine index?
class RawSourceRange
{
@@ -241,6 +240,8 @@ class RawSource {
TelemGroup = 0x020,
InputsGroup = 0x040,
ScriptsGroup = 0x080,
NegativeGroup = 0x100,
PositiveGroup = 0x200,
InputSourceGroups = NoneGroup | SourcesGroup | TrimsGroup | SwitchesGroup | InputsGroup,
AllSourceGroups = InputSourceGroups | GVarsGroup | TelemGroup | ScriptsGroup
@@ -249,14 +250,14 @@ class RawSource {
RawSource() { clear(); }
explicit RawSource(int value):
type(RawSourceType(abs(value)/65536)),
index(value >= 0 ? abs(value)%65536 : -(abs(value)%65536))
type(RawSourceType(abs(value) / 65536)),
index(value >= 0 ? abs(value) % 65536 : -(abs(value) % 65536))
{
}
RawSource(RawSourceType type, int index=0):
RawSource(RawSourceType type, int index = 0):
type(type),
index(index)
index(type != SOURCE_TYPE_NONE && index == 0 ? 1 : index)
{
}
+18 -7
View File
@@ -383,7 +383,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
if (!cfn.isEmpty()) {
widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC | CUSTOM_FUNCTION_ENABLE;
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) {
if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) {
if (model) {
int channelsMax = model->getChannelsMax(true);
fswtchParam[i]->setDecimals(0);
@@ -445,10 +445,10 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) {
else if (func >= FuncSetTimer1 && func <= FuncSetTimerLast) {
if (modified)
cfn.param = fswtchParamTime[i]->timeInSeconds();
RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings);
RawSourceRange range = RawSource(SOURCE_TYPE_TIMER, func - FuncSetTimer1 + 1).getRange(model, generalSettings);
fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max);
fswtchParamTime[i]->setTime(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM;
@@ -663,39 +663,50 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi
{
QStringList qs;
b->setModel(new QStandardItemModel(b)); // clear combo box but not any shared item model
if (function == FuncPlaySound) {
b->setModel(tabModelFactory->getItemModel(playSoundId));
b->setCurrentIndex(b->findData(value));
if (b->currentIndex() < 0)
b->setCurrentIndex(0);
}
else if (function == FuncPlayHaptic) {
b->setModel(tabModelFactory->getItemModel(harpicId));
b->setCurrentIndex(b->findData(value));
if (b->currentIndex() < 0)
b->setCurrentIndex(0);
}
else if (function == FuncReset) {
b->setModel(tabFilterFactory->getItemModel(funcResetParamId));
b->setCurrentIndex(b->findData(value));
if (b->currentIndex() < 0)
b->setCurrentIndex(0);
}
else if (function == FuncVolume || function == FuncBacklight) {
b->setModel(tabFilterFactory->getItemModel(rawSourceInputsId));
b->setCurrentIndex(b->findData(value));
if (b->currentIndex() < 0 && value == 0)
b->setCurrentIndex(b->count() / 2); // '----' not in list so set to first positive value
}
else if (function == FuncPlayValue) {
b->setModel(tabFilterFactory->getItemModel(rawSourceAllId));
b->setCurrentIndex(b->findData(value));
if (b->currentIndex() < 0 && value == 0)
b->setCurrentIndex(b->count() / 2); // '----' not in list so set to first positive value
}
else if (function >= FuncAdjustGV1 && function <= FuncAdjustGVLast) {
switch (adjustmode) {
case 1:
b->setModel(tabFilterFactory->getItemModel(rawSourceInputsId));
b->setCurrentIndex(b->findData(value));
if (b->currentIndex() < 0)
b->setCurrentIndex(0);
if (b->currentIndex() < 0 && value == 0)
b->setCurrentIndex(b->count() / 2); // '----' not in list so set to first positive value
break;
case 2:
b->setModel(tabFilterFactory->getItemModel(rawSourceGVarsId));
b->setCurrentIndex(b->findData(value));
if (b->currentIndex() < 0)
b->setCurrentIndex(0);
if (b->currentIndex() < 0 && value == 0)
b->setCurrentIndex(b->count() / 2); // '----' not in list so set to first positive value
break;
}
}
+3 -1
View File
@@ -48,7 +48,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
cb_fp[i] = tmp[i];
}
RawSourceType srcType = (firmware->getCapability(VirtualInputs) ? SOURCE_TYPE_VIRTUAL_INPUT : SOURCE_TYPE_STICK);
RawSourceType srcType = (firmware->getCapability(VirtualInputs) ? SOURCE_TYPE_VIRTUAL_INPUT : SOURCE_TYPE_INPUT);
setWindowTitle(tr("Edit %1").arg(RawSource(srcType, ed->chn).toString(&model, &generalSettings)));
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef)), "GVarRef");
@@ -109,6 +109,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
flags), "RawSource");
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue()));
if (ui->sourceCB->currentIndex() < 0 && ed->srcRaw.toValue() == 0)
ui->sourceCB->setCurrentIndex(ui->sourceCB->count() / 2); // '----' not in list so set to first positive entry
ui->inputName->setValidator(new NameValidator(board, this));
ui->inputName->setText(inputName);
}
+2 -2
View File
@@ -277,7 +277,7 @@ bool LogicalSwitchesPanel::offsetChangedAt(int index)
{
RawSource source = RawSource(model->logicalSw[index].val1);
RawSourceRange range = source.getRange(model, generalSettings, model->logicalSw[index].getRangeFlags());
double currVal = source.isTimeBased() ? teOffset[index]->timeInSeconds() : dsbOffset[index]->value();
double currVal = source.type == SOURCE_TYPE_TIMER ? teOffset[index]->timeInSeconds() : dsbOffset[index]->value();
value = round((currVal - range.offset) / range.step);
mod = (mod || value != model->logicalSw[index].val2);
model->logicalSw[index].val2 = value;
@@ -366,7 +366,7 @@ void LogicalSwitchesPanel::updateLine(int i)
double value = range.step * model->logicalSw[i].val2 + range.offset; /* TODO+source.getRawOffset(model)*/
cbSource1[i]->setModel(rawSourceFilteredModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(source.toValue()));
if (source.isTimeBased()) {
if (source.type == SOURCE_TYPE_TIMER) {
mask |= VALUE_TO_VISIBLE;
teOffset[i]->setTimeRange(range.min, range.max);
teOffset[i]->setSingleStep(range.step);
+3 -1
View File
@@ -55,6 +55,8 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
"RawSource");
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
if (ui->sourceCB->currentIndex() < 0 && md->srcRaw.toValue() == 0)
ui->sourceCB->setCurrentIndex(ui->sourceCB->count() / 2); // '----' not in list so set to first positive entry
int limit = firmware->getCapability(OffsetWeight);
@@ -206,7 +208,7 @@ void MixerDialog::valuesChanged()
lock = true;
md->srcRaw = RawSource(ui->sourceCB->itemData(ui->sourceCB->currentIndex()).toInt());
if (firmware->getCapability(HasNoExpo)) {
bool drVisible = (md->srcRaw.type == SOURCE_TYPE_STICK && md->srcRaw.index < CPN_MAX_STICKS);
bool drVisible = (md->srcRaw.type == SOURCE_TYPE_INPUT && md->srcRaw.index < CPN_MAX_STICKS);
ui->MixDR_CB->setEnabled(drVisible);
ui->label_MixDR->setEnabled(drVisible);
}
+2 -2
View File
@@ -1610,7 +1610,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
const int ttlInputs = ttlSticks + ttlFlexInputs;
for (int i = 0; i < ttlInputs + firmware->getCapability(RotaryEncoders); i++) {
RawSource src((i < ttlInputs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < ttlInputs) ? i : ttlInputs - i);
RawSource src((i < ttlInputs) ? SOURCE_TYPE_INPUT : SOURCE_TYPE_ROTARY_ENCODER, (i < ttlInputs) ? i : ttlInputs - i);
QCheckBox * checkbox = new QCheckBox(this);
checkbox->setProperty("index", i);
checkbox->setText(src.toString(&model, &generalSettings));
@@ -1674,7 +1674,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
if (IS_HORUS_OR_TARANIS(board) && ttlInputs > 0) {
for (int i = ttlSticks; i < ttlInputs; i++) {
RawSource src(SOURCE_TYPE_STICK, i);
RawSource src(SOURCE_TYPE_INPUT, i);
QCheckBox * cb = new QCheckBox(this);
cb->setProperty("index", i - ttlSticks);
cb->setText(src.toString(&model, &generalSettings));
@@ -158,7 +158,7 @@ void CustomScreen::updateBar(int line)
float maxVal = screen.body.bars[line].barMax;
maxVal = range.getValue(maxVal);
if (source.isTimeBased()) {
if (source.type == SOURCE_TYPE_TIMER) {
minTime[line]->setVisible(true);
minTime[line]->setTimeRange(range.min, range.max);
minTime[line]->setSingleStep(range.step);
+6 -6
View File
@@ -159,7 +159,7 @@ QString ModelPrinter::printEEpromSize()
QString ModelPrinter::printChannelName(int idx)
{
QString str = RawSource(SOURCE_TYPE_CH, idx).toString(&model, &generalSettings);
QString str = RawSource(SOURCE_TYPE_CH, idx + 1).toString(&model, &generalSettings);
if (firmware->getCapability(ChannelsName)) {
str = str.leftJustified(firmware->getCapability(ChannelsName) + 5, ' ', false);
}
@@ -273,7 +273,7 @@ QString ModelPrinter::printCenterBeep()
for (int i = 0; i < inputs + firmware->getCapability(RotaryEncoders); i++) {
if (model.beepANACenter & (0x01 << i)) {
RawSource src((i < inputs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < inputs) ? i : inputs - i);
RawSource src((i < inputs) ? SOURCE_TYPE_INPUT : SOURCE_TYPE_ROTARY_ENCODER, (i < inputs) ? i : inputs - i);
strl << src.toString(&model, &generalSettings);
}
}
@@ -338,8 +338,8 @@ QString ModelPrinter::printRotaryEncoder(int flightModeIndex, int reIndex)
QString ModelPrinter::printInputName(int idx)
{
RawSourceType srcType = (firmware->getCapability(VirtualInputs) ? SOURCE_TYPE_VIRTUAL_INPUT : SOURCE_TYPE_STICK);
return RawSource(srcType, idx).toString(&model, &generalSettings).toHtmlEscaped();
RawSourceType srcType = (firmware->getCapability(VirtualInputs) ? SOURCE_TYPE_VIRTUAL_INPUT : SOURCE_TYPE_INPUT);
return RawSource(srcType, idx + 1).toString(&model, &generalSettings).toHtmlEscaped();
}
QString ModelPrinter::printInputLine(int idx)
@@ -785,7 +785,7 @@ QString ModelPrinter::printPotWarnings()
for (int i = Boards::getCapability(board, Board::Sticks); i < Boards::getCapability(board, Board::Inputs); i++) {
if (generalSettings.isInputAvailable(i) && (generalSettings.isInputPot(i) || generalSettings.isInputSlider(i))) {
if (model.potsWarnEnabled[i]) {
RawSource src(SOURCE_TYPE_STICK, i);
RawSource src(SOURCE_TYPE_INPUT, i);
str += src.toString(&model, &generalSettings);
}
}
@@ -1075,7 +1075,7 @@ QString ModelPrinter::printTelemetryScreen(unsigned int idx, unsigned int line,
QString unit;
QString minstr;
QString maxstr;
if (source.isTimeBased()){
if (source.type == SOURCE_TYPE_TIMER) {
minstr = printTimeValue((float)screen.body.bars[line].barMin, MASK_TIMEVALUE_HRSMINS);
maxstr = printTimeValue((float)screen.body.bars[line].barMax, MASK_TIMEVALUE_HRSMINS);
}
+1 -1
View File
@@ -162,7 +162,7 @@ void joystickDialog::populateSourceCombo(QComboBox * cb)
if (radioSettings.isInputStick(i))
wname = Boards::getAxisName(i);
else
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, i).toString(nullptr, &radioSettings);
wname = RawSource(RawSourceType::SOURCE_TYPE_INPUT, i).toString(nullptr, &radioSettings);
cb->addItem(wname, i);
}
}
+2 -2
View File
@@ -632,7 +632,7 @@ void SimulatorWidget::setupRadioWidgets()
if (!(radioSettings.isInputAvailable(i) && radioSettings.isInputPot(i)))
continue;
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, i).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
wname = RawSource(RawSourceType::SOURCE_TYPE_INPUT, i).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
RadioKnobWidget * pot = new RadioKnobWidget(radioSettings.inputConfig[i].flexType, wname, 0, ui->radioWidgetsHT);
pot->setIndex(i);
ui->radioWidgetsHTLayout->insertWidget(midpos++, pot);
@@ -646,7 +646,7 @@ void SimulatorWidget::setupRadioWidgets()
if (!(radioSettings.isInputAvailable(i) && radioSettings.isInputSlider(i)))
continue;
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, i).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
wname = RawSource(RawSourceType::SOURCE_TYPE_INPUT, i).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false);
RadioFaderWidget * sl = new RadioFaderWidget(wname, 0, ui->radioWidgetsVC);
sl->setIndex(i);
ui->VCGridLayout->addWidget(sl, 0, fc++, 1, 1);
+4 -4
View File
@@ -245,7 +245,7 @@ TEST(Conversions, ConversionX10From22)
EXPECT_EQ(RawSwitch(SWITCH_TYPE_ON), settings.customFn[1].swtch);
EXPECT_EQ(FuncVolume, settings.customFn[1].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK, 4+5+1).toValue(), settings.customFn[1].param); // RS
EXPECT_EQ(RawSource(SOURCE_TYPE_INPUT, 4+5+1).toValue(), settings.customFn[1].param); // RS
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
@@ -265,7 +265,7 @@ TEST(Conversions, ConversionX10From22)
EXPECT_EQ(0, model.beepANACenter);
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_MAX), model.mixData[2].srcRaw); // MAX
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK, 4+5), model.mixData[3].srcRaw); // LS
EXPECT_EQ(RawSource(SOURCE_TYPE_INPUT, 4+5), model.mixData[3].srcRaw); // LS
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM, 0), model.mixData[5].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), model.mixData[5].swtch);
EXPECT_EQ(900, model.limitData[0].max); // -100
@@ -321,7 +321,7 @@ TEST(Conversions, ConversionX12SFrom22)
EXPECT_EQ(RawSwitch(SWITCH_TYPE_ON), settings.customFn[1].swtch);
EXPECT_EQ(FuncVolume, settings.customFn[1].func);
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK, 4+5+1).toValue(), settings.customFn[1].param); // RS
EXPECT_EQ(RawSource(SOURCE_TYPE_INPUT, 4+5+1).toValue(), settings.customFn[1].param); // RS
EXPECT_STREQ("Tes", settings.switchName[0]);
EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]);
@@ -341,7 +341,7 @@ TEST(Conversions, ConversionX12SFrom22)
EXPECT_EQ(0, model.beepANACenter);
EXPECT_EQ(80, model.mixData[0].weight);
EXPECT_EQ(RawSource(SOURCE_TYPE_MAX), model.mixData[2].srcRaw); // MAX
EXPECT_EQ(RawSource(SOURCE_TYPE_STICK, 4+5), model.mixData[3].srcRaw); // LS
EXPECT_EQ(RawSource(SOURCE_TYPE_INPUT, 4+5), model.mixData[3].srcRaw); // LS
EXPECT_EQ(RawSource(SOURCE_TYPE_PPM, 0), model.mixData[5].srcRaw);
EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), model.mixData[5].swtch);
EXPECT_EQ(900, model.limitData[0].max); // -100
+6 -6
View File
@@ -54,7 +54,7 @@ void WizMix::maxMixSwitch(char *name, MixData &mix, int channel, int sw, int wei
strncpy(mix.name, name, sizeof(mix.name)-1);
mix.destCh = channel;
mix.srcRaw = RawSource(SOURCE_TYPE_MAX);
mix.swtch = RawSwitch(SWITCH_TYPE_SWITCH, sw);
mix.swtch = RawSwitch(SWITCH_TYPE_SWITCH, sw + 1);
mix.weight = weight;
}
@@ -63,13 +63,13 @@ void WizMix::addMix(ModelData &model, Input input, int weight, int channel, int
if (input != NO_INPUT) {
if (input >= RUDDER_INPUT && input <= AILERONS_INPUT) {
MixData & mix = model.mixData[mixIndex++];
mix.destCh = channel+1;
mix.destCh = channel + 1;
if (IS_SKY9X(getCurrentBoard())) {
mix.srcRaw = RawSource(SOURCE_TYPE_STICK, input-1);
mix.srcRaw = RawSource(SOURCE_TYPE_INPUT, input + 1);
}
else {
int channel = settings.getDefaultChannel(input-1);
mix.srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, channel);
int channel = settings.getDefaultChannel(input - 1);
mix.srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, channel + 1);
}
mix.weight = weight;
@@ -118,7 +118,7 @@ WizMix::operator ModelData()
// Add the Throttle Cut option
MixData & mix = model.mixData[mixIndex++];
mix.destCh = i+1;
mix.srcRaw = SOURCE_TYPE_MAX;
mix.srcRaw = RawSource(SOURCE_TYPE_MAX);
mix.weight = -100;
mix.swtch.type = SWITCH_TYPE_SWITCH;
mix.swtch.index = IS_SKY9X(getCurrentBoard()) ? SWITCH_THR : SWITCH_SF0;
+2
View File
@@ -535,6 +535,8 @@ enum MixSources {
MIXSRC_FIRST_TELEM SKIP,
MIXSRC_LAST_TELEM SKIP = MIXSRC_FIRST_TELEM + 3 * MAX_TELEMETRY_SENSORS - 1,
MIXSRC_INVERT SKIP,
};
+2 -2
View File
@@ -74,7 +74,7 @@ PACK(struct CurveRef {
PACK(struct MixData {
int16_t weight:11 CUST(in_read_weight,in_write_weight); // GV1=-1024, -GV1=1023
uint16_t destCh:5;
uint16_t srcRaw:10 CUST(r_mixSrcRaw,w_mixSrcRaw); // srcRaw=0 means not used
int16_t srcRaw:10 CUST(r_mixSrcRawEx,w_mixSrcRawEx); // srcRaw=0 means not used
uint16_t carryTrim:1;
uint16_t mixWarn:2; // mixer warning
uint16_t mltpx:2 ENUM(MixerMultiplex);
@@ -99,7 +99,7 @@ PACK(struct ExpoData {
uint16_t scale:14;
CUST_ATTR(carryTrim, r_carryTrim, nullptr); //pre 2.9
int16_t trimSource:6;
uint16_t srcRaw:10 ENUM(MixSources) CUST(r_mixSrcRaw,w_mixSrcRaw);
int16_t srcRaw:10 ENUM(MixSources) CUST(r_mixSrcRawEx,w_mixSrcRawEx);
uint32_t chn:5;
int32_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
uint32_t flightModes:9 CUST(r_flightModes, w_flightModes);
+1 -1
View File
@@ -125,7 +125,7 @@ extern int8_t s_copySrcRow;
extern int8_t s_copyTgtOfs;
extern uint8_t s_currIdx;
extern uint8_t s_currIdxSubMenu;
extern uint16_t s_currSrcRaw;
extern mixsrc_t s_currSrcRaw;
extern uint16_t s_currScale;
extern uint8_t s_copySrcIdx;
extern uint8_t s_copySrcCh;
+19 -8
View File
@@ -657,23 +657,34 @@ void putsVBat(coord_t x, coord_t y, LcdFlags att)
putsVolts(x, y, g_vbat100mV, att);
}
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att)
{
if (idx == MIXSRC_NONE) {
uint16_t aidx = abs(idx);
bool inverted = idx < 0;
if (aidx == MIXSRC_NONE) {
lcdDrawText(x, y, STR_EMPTY, att);
}
else if (idx <= MIXSRC_LAST_INPUT) {
else if (aidx <= MIXSRC_LAST_INPUT) {
if (inverted) {
lcdDrawChar(x, y, '!');
x += 2;
}
lcdDrawChar(x+2, y+1, CHR_INPUT, TINSIZE);
lcdDrawSolidFilledRect(x, y, 7, 7);
if (g_model.inputNames[idx-MIXSRC_FIRST_INPUT][0])
lcdDrawSizedText(x+8, y, g_model.inputNames[idx-MIXSRC_FIRST_INPUT], LEN_INPUT_NAME, att);
if (g_model.inputNames[aidx-MIXSRC_FIRST_INPUT][0])
lcdDrawSizedText(x+8, y, g_model.inputNames[aidx-MIXSRC_FIRST_INPUT], LEN_INPUT_NAME, att);
else
lcdDrawNumber(x+8, y, idx, att|LEADING0|LEFT, 2);
lcdDrawNumber(x+8, y, aidx, att|LEADING0|LEFT, 2);
}
#if defined(LUA_INPUTS)
else if (idx <= MIXSRC_LAST_LUA) {
div_t qr = div(idx-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
else if (aidx <= MIXSRC_LAST_LUA) {
div_t qr = div((uint16_t)(aidx-MIXSRC_FIRST_LUA), MAX_SCRIPT_OUTPUTS);
#if defined(LUA_MODEL_SCRIPTS)
if (inverted) {
lcdDrawChar(x, y, '!');
x += 2;
}
if (qr.quot < MAX_SCRIPTS && qr.rem < scriptInputsOutputs[qr.quot].outputsCount) {
lcdDrawChar(x+2, y+1, '1'+qr.quot, TINSIZE);
lcdDrawFilledRect(x, y, 7, 7, 0);
+1 -1
View File
@@ -70,5 +70,5 @@ void editSingleName(coord_t x, coord_t y, const char* label, char* name,
uint8_t s_currIdx;
uint8_t s_currIdxSubMenu;
uint16_t s_currSrcRaw;
mixsrc_t s_currSrcRaw;
uint16_t s_currScale;
+6 -6
View File
@@ -79,7 +79,7 @@ void menuModelExpoOne(event_t event)
uint8_t old_editMode = s_editMode;
SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX,
{0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, LABEL(Curve), 1,
{0, 0, 0, abs(ed->srcRaw) >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, LABEL(Curve), 1,
CASE_FLIGHT_MODES(FM_ROW(LABEL(Flight Mode))) CASE_FLIGHT_MODES(FM_ROW((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE)) 0 /*, ...*/});
int8_t sub = menuVerticalPosition;
@@ -112,14 +112,14 @@ void menuModelExpoOne(event_t event)
lcdDrawTextAlignedLeft(y, STR_SOURCE);
drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, RIGHT|STREXPANDED|attr);
if (attr)
ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailableInInputs);
ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isSourceAvailableInInputs);
break;
case EXPO_FIELD_SCALE:
lcdDrawTextAlignedLeft(y, STR_SCALE);
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), RIGHT | attr);
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN, y, (abs(ed->srcRaw) - MIXSRC_FIRST_TELEM)/3, convertTelemValue(abs(ed->srcRaw) - MIXSRC_FIRST_TELEM + 1, ed->scale), RIGHT | attr);
if (attr)
ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(abs(ed->srcRaw) - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
break;
case EXPO_FIELD_WEIGHT:
@@ -161,13 +161,13 @@ void menuModelExpoOne(event_t event)
case EXPO_FIELD_TRIM:
lcdDrawTextAlignedLeft(y, STR_TRIM);
{
const char* trim_str = getTrimSourceLabel(ed->srcRaw, ed->trimSource);
const char* trim_str = getTrimSourceLabel(abs(ed->srcRaw), ed->trimSource);
LcdFlags flags = RIGHT | (menuHorizontalPosition==0 ? attr : 0);
lcdDrawText(EXPO_ONE_2ND_COLUMN, y, trim_str, flags);
if (attr) {
int8_t min = TRIM_ON;
if (ed->srcRaw >= MIXSRC_FIRST_STICK && ed->srcRaw <= MIXSRC_LAST_STICK) {
if (abs(ed->srcRaw) >= MIXSRC_FIRST_STICK && abs(ed->srcRaw) <= MIXSRC_LAST_STICK) {
min = -TRIM_OFF;
}
ed->trimSource = -checkIncDecModel(event, -ed->trimSource, min, keysGetMaxTrims());
@@ -116,7 +116,7 @@ void menuModelLogicalSwitchOne(event_t event)
else {
v1_val = cs->v1;
drawSource(CSWONE_2ND_COLUMN, y, v1_val, attr);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
if (attr) {
@@ -152,7 +152,7 @@ void menuModelLogicalSwitchOne(event_t event)
}
else if (cstate == LS_FAMILY_COMP) {
drawSource(CSWONE_2ND_COLUMN, y, cs->v2, attr);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else {
@@ -175,7 +175,7 @@ void menuModelLogicalSwitchOne(event_t event)
getMixSrcRange(v1_val, v2_min, v2_max, &lf);
if ((cs->func == LS_FUNC_APOS) || (cs->func == LS_FUNC_ANEG) || (cs->func == LS_FUNC_ADIFFEGREATER))
v2_min = 0;
drawSourceCustomValue(CSWONE_2ND_COLUMN, y, v1_val, (v1_val <= MIXSRC_LAST_CH ? calc100toRESX(cs->v2) : cs->v2), lf);
drawSourceCustomValue(CSWONE_2ND_COLUMN, y, v1_val, (abs(v1_val) <= MIXSRC_LAST_CH ? calc100toRESX(cs->v2) : cs->v2), lf);
}
}
@@ -313,7 +313,7 @@ void menuModelLogicalSwitches(event_t event)
lcdDrawNumber(CSW_3RD_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1);
}
else {
source_t v1 = cs->v1;
mixsrc_t v1 = cs->v1;
drawSource(CSW_2ND_COLUMN, y, v1, 0);
if (v1 >= MIXSRC_FIRST_TELEM) {
drawSourceCustomValue(CSW_3RD_COLUMN, y, v1, convertLswTelemValue(cs), LEFT);
+2 -1
View File
@@ -138,7 +138,8 @@ void menuModelMixOne(event_t event)
case MIX_FIELD_SOURCE:
lcdDrawTextAlignedLeft(y, STR_SOURCE);
drawSource(MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
if (attr)
md2->srcRaw = checkIncDec(event, md2->srcRaw, 1, MIXSRC_LAST, EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isSourceAvailable);
break;
case MIX_FIELD_WEIGHT:
@@ -351,7 +351,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_TELEM;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN - (val_displayed == 0 ? 0 : 2 * FW), y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalFunctions : isSourceAvailable);
}
}
@@ -360,7 +360,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
}
@@ -368,7 +368,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
}
@@ -397,7 +397,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
break;
+1 -1
View File
@@ -36,7 +36,7 @@
#define WARNING_LINE_X 12
#define WARNING_LINE_Y MESSAGEBOX_Y + 2
#define POPUP_MENU_MAX_LINES 12
#define POPUP_MENU_MAX_LINES 13
#define MENU_MAX_DISPLAY_LINES 6
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
+1 -1
View File
@@ -146,7 +146,7 @@ extern int8_t s_copySrcRow;
extern int8_t s_copyTgtOfs;
extern uint8_t s_currIdx;
extern uint8_t s_currIdxSubMenu;
extern uint16_t s_currSrcRaw;
extern mixsrc_t s_currSrcRaw;
extern uint16_t s_currScale;
extern uint8_t s_copySrcIdx;
extern uint8_t s_copySrcCh;
+19 -8
View File
@@ -627,23 +627,34 @@ void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
lcdDrawSizedText(x, y, getMainControlLabel(idx), UINT8_MAX, att);
}
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att)
void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att)
{
if (idx == MIXSRC_NONE) {
uint16_t aidx = abs(idx);
bool inverted = idx < 0;
if (aidx == MIXSRC_NONE) {
lcdDrawText(x, y, STR_EMPTY, att);
}
else if (idx <= MIXSRC_LAST_INPUT) {
else if (aidx <= MIXSRC_LAST_INPUT) {
if (inverted) {
lcdDrawChar(x, y, '!');
x += 2;
}
lcdDrawChar(x+2, y+1, CHR_INPUT, TINSIZE);
lcdDrawFilledRect(x, y, 7, 7);
if (ZEXIST(g_model.inputNames[idx-MIXSRC_FIRST_INPUT]))
lcdDrawSizedText(x+8, y, g_model.inputNames[idx-MIXSRC_FIRST_INPUT], LEN_INPUT_NAME, att);
if (ZEXIST(g_model.inputNames[aidx-MIXSRC_FIRST_INPUT]))
lcdDrawSizedText(x+8, y, g_model.inputNames[aidx-MIXSRC_FIRST_INPUT], LEN_INPUT_NAME, att);
else
lcdDrawNumber(x+8, y, idx, att|LEADING0|LEFT, 2);
lcdDrawNumber(x+8, y, aidx, att|LEADING0|LEFT, 2);
}
else if (idx <= MIXSRC_LAST_LUA) {
div_t qr = div(idx-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
else if (aidx <= MIXSRC_LAST_LUA) {
div_t qr = div((uint16_t)(aidx-MIXSRC_FIRST_LUA), MAX_SCRIPT_OUTPUTS);
#if defined(LUA_MODEL_SCRIPTS)
if (inverted) {
lcdDrawChar(x, y, '!');
x += 2;
}
if (qr.quot < MAX_SCRIPTS && qr.rem < scriptInputsOutputs[qr.quot].outputsCount) {
lcdDrawChar(x+2, y+1, '1'+qr.quot, TINSIZE);
lcdDrawFilledRect(x, y, 7, 7);
+1 -1
View File
@@ -112,7 +112,7 @@ void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0);
void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att);
void drawSwitch(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0, bool autoBold = true);
void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0);
void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att=0);
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0);
+1 -1
View File
@@ -74,5 +74,5 @@ void editSingleName(coord_t x, coord_t y, const char * label, char *name, uint8_
uint8_t s_currIdx;
uint8_t s_currIdxSubMenu;
uint16_t s_currSrcRaw;
mixsrc_t s_currSrcRaw;
uint16_t s_currScale;
+8 -8
View File
@@ -103,10 +103,10 @@ void menuModelExpoOne(event_t event)
lcdDrawTextAlignedLeft(y, STR_SOURCE);
drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr);
if (attr && menuHorizontalPosition==0)
ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailableInInputs);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN+30, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, getValue(ed->srcRaw), LEFT|(menuHorizontalPosition==1?attr:0));
if (attr && menuHorizontalPosition == 1) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isSourceAvailableInInputs);
if (abs(ed->srcRaw) >= MIXSRC_FIRST_TELEM) {
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN+30, y, (abs(ed->srcRaw) - MIXSRC_FIRST_TELEM)/3, getValue(ed->srcRaw), LEFT|(menuHorizontalPosition==1?attr:0));
if (attr && menuHorizontalPosition == 1) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(abs(ed->srcRaw) - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
}
else if (attr) {
menuHorizontalPosition = 0;
@@ -115,8 +115,8 @@ void menuModelExpoOne(event_t event)
case EXPO_FIELD_SCALE:
lcdDrawTextAlignedLeft(y, STR_SCALE);
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr);
if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN, y, (abs(ed->srcRaw) - MIXSRC_FIRST_TELEM)/3, convertTelemValue(abs(ed->srcRaw) - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr);
if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(abs(ed->srcRaw) - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
break;
case EXPO_FIELD_WEIGHT:
@@ -152,13 +152,13 @@ void menuModelExpoOne(event_t event)
case EXPO_FIELD_TRIM:
lcdDrawTextAlignedLeft(y, STR_TRIM);
{
const char* trim_str = getTrimSourceLabel(ed->srcRaw, ed->trimSource);
const char* trim_str = getTrimSourceLabel(abs(ed->srcRaw), ed->trimSource);
LcdFlags flags = RIGHT | (menuHorizontalPosition==0 ? attr : 0);
lcdDrawText(EXPO_ONE_2ND_COLUMN, y, trim_str, flags);
if (attr) {
int8_t min = TRIM_ON;
if (ed->srcRaw >= MIXSRC_FIRST_STICK && ed->srcRaw <= MIXSRC_LAST_STICK) {
if (abs(ed->srcRaw) >= MIXSRC_FIRST_STICK && abs(ed->srcRaw) <= MIXSRC_LAST_STICK) {
min = -TRIM_OFF;
}
ed->trimSource = -checkIncDecModel(event, -ed->trimSource, min, keysGetMaxTrims());
@@ -117,7 +117,7 @@ void menuModelLogicalSwitches(event_t event)
// CSW params
unsigned int cstate = lswFamily(cs->func);
int v1_val = cs->v1;
mixsrc_t v1_val = cs->v1;
int16_t v1_min = 0, v1_max = MIXSRC_LAST_TELEM;
int16_t v2_min = 0, v2_max = MIXSRC_LAST_TELEM;
int16_t v3_min =-1, v3_max = 100;
@@ -149,7 +149,7 @@ void menuModelLogicalSwitches(event_t event)
v1_val = cs->v1;
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
drawSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else if (cstate == LS_FAMILY_TIMER) {
@@ -164,7 +164,7 @@ void menuModelLogicalSwitches(event_t event)
v1_val = cs->v1;
drawSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (horz == 1) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailableInCustomSwitches);
}
else {
@@ -175,7 +175,7 @@ void menuModelLogicalSwitches(event_t event)
getMixSrcRange(v1_val, v2_min, v2_max, &lf);
if ((cs->func == LS_FUNC_APOS) || (cs->func == LS_FUNC_ANEG) || (cs->func == LS_FUNC_ADIFFEGREATER))
v2_min = 0;
drawSourceCustomValue(CSW_3RD_COLUMN, y, v1_val, (v1_val <= MIXSRC_LAST_CH ? calc100toRESX(cs->v2) : cs->v2), lf);
drawSourceCustomValue(CSW_3RD_COLUMN, y, v1_val, (abs(v1_val) <= MIXSRC_LAST_CH ? calc100toRESX(cs->v2) : cs->v2), lf);
}
// CSW AND switch
@@ -228,14 +228,14 @@ void menuModelLogicalSwitches(event_t event)
cs->v1 = CHECK_INCDEC_PARAM(event, v1_val, v1_min, v1_max);
break;
case LS_FIELD_V2:
if (v1_val >= MIXSRC_FIRST_TIMER) {
if (abs(v1_val) >= MIXSRC_FIRST_TIMER) {
INCDEC_SET_FLAG(EE_MODEL | INCDEC_REP10 | NO_INCDEC_MARKS);
}
cs->v2 = CHECK_INCDEC_PARAM(event, cs->v2, v2_min, v2_max);
if (cstate==LS_FAMILY_OFS && cs->v1!=0 && event==EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
getvalue_t x = getValue(v1_val);
if (v1_val <= MIXSRC_LAST_CH) {
if (abs(v1_val) <= MIXSRC_LAST_CH) {
cs->v2 = calcRESXto100(x);
}
storageDirty(EE_MODEL);
+2 -1
View File
@@ -126,7 +126,8 @@ void menuModelMixOne(event_t event)
case MIX_FIELD_SOURCE:
lcdDrawTextAlignedLeft(y, STR_SOURCE);
drawSource(MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr);
if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST);
if (attr)
md2->srcRaw = checkIncDec(event, md2->srcRaw, 1, MIXSRC_LAST, EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isSourceAvailable);
break;
case MIX_FIELD_WEIGHT:
@@ -326,7 +326,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_TELEM;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalFunctions : isSourceAvailable);
}
}
@@ -335,7 +335,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
}
@@ -354,7 +354,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
}
@@ -372,7 +372,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE | INCDEC_SOURCE_INVERT);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
break;
+1 -1
View File
@@ -34,7 +34,7 @@
#define WARNING_LINE_X 16
#define WARNING_LINE_Y MESSAGEBOX_Y + 2
#define POPUP_MENU_MAX_LINES 12
#define POPUP_MENU_MAX_LINES 13
#define MENU_MAX_DISPLAY_LINES 6
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
+1 -1
View File
@@ -193,7 +193,7 @@ void CurveDataEdit::update()
}
}
void CurveEdit::SetCurrentSource(uint32_t source)
void CurveEdit::SetCurrentSource(mixsrc_t source)
{
CurveEdit::currentSource = source;
if (source)
+1 -1
View File
@@ -31,7 +31,7 @@ class CurveEdit: public Window
{
public:
CurveEdit(Window * parent, const rect_t & rect, uint8_t index);
static void SetCurrentSource(uint32_t source);
static void SetCurrentSource(mixsrc_t source);
void deleteLater(bool detach = true, bool trash = true) override
{
+8 -8
View File
@@ -95,14 +95,14 @@ InputSource::InputSource(Window *parent, ExpoData *input) :
lv_obj_set_flex_flow(lvobj, LV_FLEX_FLOW_COLUMN);
lv_obj_set_size(lvobj, lv_pct(100), LV_SIZE_CONTENT);
new SourceChoice(this, rect_t{}, INPUTSRC_FIRST, INPUTSRC_LAST,
GET_DEFAULT(input->srcRaw), [=](int32_t newValue) {
input->srcRaw = newValue;
lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr);
SET_DIRTY();
});
lv_obj_add_event_cb(lvobj, InputSource::value_changed, LV_EVENT_VALUE_CHANGED,
nullptr);
new SourceChoice(
this, rect_t{}, INPUTSRC_FIRST, INPUTSRC_LAST, GET_DEFAULT(input->srcRaw),
[=](int32_t newValue) {
input->srcRaw = newValue;
lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr);
SET_DIRTY();
}, true);
lv_obj_add_event_cb(lvobj, InputSource::value_changed, LV_EVENT_VALUE_CHANGED, nullptr);
sensor_form = new Window(this, rect_t{});
sensor_form->padAll(PAD_TINY);
+1 -1
View File
@@ -110,7 +110,7 @@ void MixEditWindow::buildBody(Window *form)
line = form->newLine(grid);
new StaticText(line, rect_t{}, STR_SOURCE);
new SourceChoice(line, rect_t{}, 0, MIXSRC_LAST,
GET_SET_DEFAULT(mix->srcRaw));
GET_SET_DEFAULT(mix->srcRaw), true);
CurveEdit::SetCurrentSource(mix->srcRaw);
// Weight
@@ -122,7 +122,7 @@ class LogicalSwitchEditPage : public Page
break;
case LS_FAMILY_COMP:
new SourceChoice(line, rect_t{}, 0, MIXSRC_LAST_TELEM,
GET_SET_DEFAULT(cs->v1));
GET_SET_DEFAULT(cs->v1), true);
break;
case LS_FAMILY_TIMER:
timer =
@@ -144,7 +144,7 @@ class LogicalSwitchEditPage : public Page
v2Edit->setValue(cs->v2);
}
SET_DIRTY();
});
}, true);
break;
}
@@ -191,7 +191,7 @@ class LogicalSwitchEditPage : public Page
} break;
case LS_FAMILY_COMP:
new SourceChoice(line, rect_t{}, 0, MIXSRC_LAST_TELEM,
GET_SET_DEFAULT(cs->v2));
GET_SET_DEFAULT(cs->v2), true);
break;
case LS_FAMILY_TIMER:
timer =
@@ -208,7 +208,7 @@ class LogicalSwitchEditPage : public Page
GET_SET_DEFAULT(cs->v2));
v2Edit->setDisplayHandler([=](int value) -> std::string {
if (cs->v1 <= MIXSRC_LAST_CH) value = calc100toRESX(value);
if (abs(cs->v1) <= MIXSRC_LAST_CH) value = calc100toRESX(value);
std::string txt = getSourceCustomValueString(cs->v1, value, 0);
return txt;
});
+80 -3
View File
@@ -38,7 +38,7 @@
class SourceChoiceMenuToolbar : public MenuToolbar
{
public:
SourceChoiceMenuToolbar(SourceChoice *choice, Menu *menu) :
SourceChoiceMenuToolbar(SourceChoice* choice, Menu* menu) :
MenuToolbar(choice, menu, FILTER_COLUMNS)
{
addButton(STR_CHAR_INPUT, MIXSRC_FIRST_INPUT, MIXSRC_LAST_INPUT, nullptr,
@@ -104,9 +104,79 @@ class SourceChoiceMenuToolbar : public MenuToolbar
if ((nxtBtnPos > filterColumns) && choice->isValueAvailable &&
choice->isValueAvailable(0))
addButton(STR_SELECT_MENU_CLR, 0, 0, nullptr, nullptr, true);
#if defined(HARDWARE_TOUCH)
if (choice->canInvert) {
invertBtn = new MenuToolbarButton(this, {0, 0, LV_PCT(100), 0},
STR_SELECT_MENU_INV);
invertBtn->check(choice->inverted);
lv_obj_align(invertBtn->getLvObj(), LV_ALIGN_BOTTOM_MID, 0, 0);
invertBtn->setPressHandler([=]() {
lv_obj_clear_state(invertBtn->getLvObj(), LV_STATE_FOCUSED);
invertChoice();
return choice->inverted;
});
}
#endif
}
void invertChoice()
{
SourceChoice* sourceChoice = (SourceChoice*)choice;
if (sourceChoice->canInvert) {
sourceChoice->inverted = !sourceChoice->inverted;
auto idx = menu->selection();
sourceChoice->fillMenu(menu, filter);
menu->select(idx);
#if defined(HARDWARE_TOUCH)
invertBtn->check(sourceChoice->inverted);
#endif
}
}
void longPress()
{
lv_indev_t* indev = lv_indev_get_act();
if (indev->driver->type == LV_INDEV_TYPE_KEYPAD) {
invertChoice();
}
}
protected:
#if defined(HARDWARE_TOUCH)
MenuToolbarButton* invertBtn = nullptr;
#endif
};
void SourceChoice::LongPressHandler(void* data)
{
SourceChoice* src = (SourceChoice*)data;
if (src && src->canInvert) {
int16_t val = src->_getValue();
if (src->isValueAvailable && src->isValueAvailable(-val)) {
src->setValue(-val);
src->invalidate();
}
}
}
void SourceChoice::setValue(int value)
{
if (inMenu) {
if (inverted) value = -value;
inMenu = false;
}
Choice::setValue(value);
}
int SourceChoice::getIntValue() const
{
int value = Choice::getIntValue();
if (inMenu) value = abs(value);
return value;
}
// defined in gui/gui_common.cpp
uint8_t switchToMix(uint8_t source);
@@ -114,6 +184,9 @@ void SourceChoice::openMenu()
{
setEditMode(true); // this needs to be done first before menu is created.
inverted = getIntValue() < 0;
inMenu = true;
auto menu = new Menu(this);
if (menuTitle) menu->setTitle(menuTitle);
@@ -149,15 +222,19 @@ void SourceChoice::openMenu()
SourceChoice::SourceChoice(Window *parent, const rect_t &rect, int16_t vmin,
int16_t vmax, std::function<int16_t()> getValue,
std::function<void(int16_t)> setValue) :
Choice(parent, rect, vmin, vmax, getValue, setValue, STR_SOURCE)
std::function<void(int16_t)> setValue, bool allowInvert) :
Choice(parent, rect, vmin, vmax, getValue, setValue, STR_SOURCE), canInvert(allowInvert)
{
setTextHandler([=](int value) {
if (inMenu && inverted) value = -value;
if (isValueAvailable && !isValueAvailable(value))
return std::to_string(0); // we will fix this later
return std::string(getSourceString(value));
});
set_lv_LongPressHandler(LongPressHandler, this);
setAvailableHandler([](int v) { return isSourceAvailable(v); });
}
+11 -1
View File
@@ -33,11 +33,21 @@ class SourceChoice : public Choice
public:
SourceChoice(Window* parent, const rect_t& rect, int16_t vmin, int16_t vmax,
std::function<int16_t()> getValue,
std::function<void(int16_t)> setValue);
std::function<void(int16_t)> setValue, bool allowInvert = false);
static void LongPressHandler(void* data);
protected:
friend SourceChoiceMenuToolbar;
bool inMenu = false;
bool canInvert = false;
void setValue(int value) override;
int getIntValue() const override;
void invertChoice();
void openMenu() override;
#if defined(DEBUG_WINDOWS)
+1 -1
View File
@@ -373,7 +373,7 @@ void FunctionEditPage::addSourceChoice(FormLine *line, const char *title,
CustomFunctionData *cfn, int16_t vmax)
{
new StaticText(line, rect_t{}, title);
new SourceChoice(line, rect_t{}, 0, vmax, GET_SET_DEFAULT(CFN_PARAM(cfn)));
new SourceChoice(line, rect_t{}, 0, vmax, GET_SET_DEFAULT(CFN_PARAM(cfn)), true);
}
NumberEdit *FunctionEditPage::addNumberEdit(FormLine *line, const char *title,
+2
View File
@@ -98,7 +98,9 @@ class SwitchChoiceMenuToolbar : public MenuToolbar
}
protected:
#if defined(HARDWARE_TOUCH)
MenuToolbarButton* invertBtn = nullptr;
#endif
};
void SwitchChoice::LongPressHandler(void* data)
@@ -460,8 +460,10 @@ void drawSensorCustomValue(coord_t x, coord_t y, uint8_t sensor, int32_t value,
}
}
void drawSourceCustomValue(coord_t x, coord_t y, source_t source, int32_t value, LcdFlags flags)
void drawSourceCustomValue(coord_t x, coord_t y, mixsrc_t source, int32_t value, LcdFlags flags)
{
source = abs(source);
if (source >= MIXSRC_FIRST_TELEM) {
source = (source-MIXSRC_FIRST_TELEM) / 3;
drawSensorCustomValue(x, y, source, value, flags);
+5 -3
View File
@@ -175,11 +175,13 @@ void drawFunction(FnFuncP fn, uint8_t offset)
void drawCursor(FnFuncP fn, uint8_t offset)
{
int16_t src = abs(s_currSrcRaw);
int x512 = getValue(s_currSrcRaw);
if (s_currSrcRaw >= MIXSRC_FIRST_TELEM) {
if (src >= MIXSRC_FIRST_TELEM) {
if (s_currScale > 0)
x512 = (x512 * 1024) / convertTelemValue(s_currSrcRaw - MIXSRC_FIRST_TELEM + 1, s_currScale);
drawSensorCustomValue(LCD_W - FW - offset, 6 * FH, (s_currSrcRaw - MIXSRC_FIRST_TELEM) / 3, x512, 0);
x512 = (x512 * 1024) / convertTelemValue(src - MIXSRC_FIRST_TELEM + 1, s_currScale);
drawSensorCustomValue(LCD_W - FW - offset, 6 * FH, (src - MIXSRC_FIRST_TELEM) / 3, x512, 0);
}
else {
lcdDrawNumber(LCD_W - FW - offset, 6*FH, calcRESXto1000(x512), RIGHT | PREC1);
+1 -1
View File
@@ -179,7 +179,7 @@ int getChannelsUsed()
bool isSourceAvailable(int source)
{
if (source < 0)
return false;
source = -source;
if (source >= MIXSRC_FIRST_INPUT && source <= MIXSRC_LAST_INPUT) {
return isInputAvailable(source - MIXSRC_FIRST_INPUT);
+1 -1
View File
@@ -129,7 +129,7 @@ void drawTelemScreenDate(coord_t x, coord_t y, source_t sensor, LcdFlags flags=0
void drawGPSPosition(coord_t x, coord_t y, int32_t longitude, int32_t latitude, LcdFlags flags=0);
void drawGPSSensorValue(coord_t x, coord_t y, TelemetryItem & telemetryItem, LcdFlags flags=0);
void drawSensorCustomValue(coord_t x, coord_t y, uint8_t sensor, int32_t value, LcdFlags flags=0);
void drawSourceCustomValue(coord_t x, coord_t y, source_t channel, int32_t val, LcdFlags flags=0);
void drawSourceCustomValue(coord_t x, coord_t y, mixsrc_t channel, int32_t val, LcdFlags flags=0);
void drawSourceValue(coord_t x, coord_t y, source_t channel, LcdFlags flags=0);
// model_setup Defines that are used in all uis in the same way
+2
View File
@@ -115,6 +115,8 @@ void onSourceLongEnterPress(const char * result)
break;
}
}
} else if (result == STR_MENU_INVERT) {
checkIncDecSelection = MIXSRC_INVERT;
}
}
+2 -1
View File
@@ -73,6 +73,7 @@ extern int8_t s_editMode; // global editmode
#define INCDEC_SOURCE 0x10
#define INCDEC_REP10 0x40
#define NO_DBLKEYS 0x80
#define INCDEC_SOURCE_INVERT 0x100
int checkIncDec(event_t event, int val, int i_min, int i_max,
unsigned int i_flags = 0, IsValueAvailable isValueAvailable = nullptr,
@@ -96,7 +97,7 @@ void check(event_t event, uint8_t curr, const MenuHandler *menuTab,
vertpos_t rowcount, uint8_t flags = 0);
#define INCDEC_DECLARE_VARS(f) \
uint8_t incdecFlag = (f); \
uint16_t incdecFlag = (f); \
IsValueAvailable isValueAvailable = nullptr
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
+24 -10
View File
@@ -61,6 +61,13 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
#endif
if (s_editMode > 0) {
bool invert = false;
if ((i_flags & INCDEC_SOURCE_INVERT) && (newval < 0)) {
invert = true;
newval = -newval;
val = -val;
}
if (event == evt_rot_inc || event == EVT_KEY_FIRST(KEY_PLUS) ||
event == EVT_KEY_REPT(KEY_PLUS)) {
@@ -119,22 +126,19 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
#endif
}
#endif
if (invert) {
newval = -newval;
val = -val;
}
}
if (!READ_ONLY() && i_min == 0 && i_max == 1 &&
event == EVT_KEY_BREAK(KEY_ENTER)) {
s_editMode = 0;
newval = !val;
}
if (newval != val) {
storageDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
if (i_flags & INCDEC_SOURCE) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
@@ -178,10 +182,11 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
}
}
}
if (i_flags & INCDEC_SOURCE_INVERT) POPUP_MENU_ADD_ITEM(STR_MENU_INVERT);
POPUP_MENU_START(onSourceLongEnterPress);
}
if (checkIncDecSelection != 0) {
newval = checkIncDecSelection;
newval = (checkIncDecSelection == MIXSRC_INVERT ? -newval : checkIncDecSelection);
if (checkIncDecSelection != MIXSRC_MIN && checkIncDecSelection != MIXSRC_MAX)
s_editMode = EDIT_MODIFY_FIELD;
checkIncDecSelection = 0;
@@ -212,6 +217,15 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
checkIncDecSelection = 0;
}
}
if (newval != val) {
storageDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
return newval;
}
+57 -22
View File
@@ -61,6 +61,13 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
#endif
if (s_editMode > 0) {
bool invert = false;
if ((i_flags & INCDEC_SOURCE_INVERT) && (newval < 0)) {
invert = true;
newval = -newval;
val = -val;
}
if (event == evt_rot_inc || event == EVT_KEY_FIRST(KEY_PLUS) ||
event == EVT_KEY_REPT(KEY_PLUS)) {
@@ -119,6 +126,11 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
#endif
}
#endif
if (invert) {
newval = -newval;
val = -val;
}
}
if (!READ_ONLY() && i_min == 0 && i_max == 1 &&
@@ -127,27 +139,6 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
newval = !val;
}
if (newval != val) {
#if !defined(ROTARY_ENCODER_NAVIGATION)
if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) &&
(newval != i_min) && stops.contains(newval)) {
bool pause = (newval > val ? !stops.contains(newval + 1)
: !stops.contains(newval - 1));
if (pause) {
pauseEvents(event); // delay before auto-repeat continues
}
}
if (!IS_KEY_REPT(event)) {
AUDIO_KEY_PRESS();
}
#endif
storageDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
if (i_flags & INCDEC_SOURCE) {
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
@@ -191,10 +182,11 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
}
}
}
if (i_flags & INCDEC_SOURCE_INVERT) POPUP_MENU_ADD_ITEM(STR_MENU_INVERT);
POPUP_MENU_START(onSourceLongEnterPress);
}
if (checkIncDecSelection != 0) {
newval = checkIncDecSelection;
newval = (checkIncDecSelection == MIXSRC_INVERT ? -newval : checkIncDecSelection);
if (checkIncDecSelection != MIXSRC_MIN && checkIncDecSelection != MIXSRC_MAX)
s_editMode = EDIT_MODIFY_FIELD;
checkIncDecSelection = 0;
@@ -225,6 +217,49 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
checkIncDecSelection = 0;
}
}
if (newval != val) {
#if !defined(ROTARY_ENCODER_NAVIGATION)
if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) &&
(newval != i_min) && stops.contains(newval)) {
bool pause = (newval > val ? !stops.contains(newval + 1)
: !stops.contains(newval - 1));
if (pause) {
pauseEvents(event); // delay before auto-repeat continues
}
}
if (!IS_KEY_REPT(event)) {
AUDIO_KEY_PRESS();
}
#endif
storageDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
if (newval != val) {
#if !defined(ROTARY_ENCODER_NAVIGATION)
if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) &&
(newval != i_min) && stops.contains(newval)) {
bool pause = (newval > val ? !stops.contains(newval + 1)
: !stops.contains(newval - 1));
if (pause) {
pauseEvents(event); // delay before auto-repeat continues
}
}
if (!IS_KEY_REPT(event)) {
AUDIO_KEY_PRESS();
}
#endif
storageDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
return newval;
}
+14 -1
View File
@@ -50,6 +50,13 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
int newval = val;
if (s_editMode > 0) {
bool invert = false;
if ((i_flags & INCDEC_SOURCE_INVERT) && (newval < 0)) {
invert = true;
newval = -newval;
val = -val;
}
if (event == EVT_KEY_FIRST(KEY_RIGHT) || event == EVT_KEY_REPT(KEY_RIGHT) ||
event == EVT_KEY_FIRST(KEY_UP) || event == EVT_KEY_REPT(KEY_UP)) {
do {
@@ -109,6 +116,11 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
#endif
}
#endif
if (invert) {
newval = -newval;
val = -val;
}
}
if (!READ_ONLY() && i_min == 0 && i_max == 1 &&
@@ -179,10 +191,11 @@ int checkIncDec(event_t event, int val, int i_min, int i_max,
}
}
}
if (i_flags & INCDEC_SOURCE_INVERT) POPUP_MENU_ADD_ITEM(STR_MENU_INVERT);
POPUP_MENU_START(onSourceLongEnterPress);
}
if (checkIncDecSelection != 0) {
newval = checkIncDecSelection;
newval = (checkIncDecSelection == MIXSRC_INVERT ? -newval : checkIncDecSelection);
if (checkIncDecSelection != MIXSRC_MIN && checkIncDecSelection != MIXSRC_MAX)
s_editMode = EDIT_MODIFY_FIELD;
checkIncDecSelection = 0;
+27 -12
View File
@@ -155,29 +155,31 @@ int expo(int x, int k)
return neg ? -y : y;
}
void applyExpos(int16_t * anas, uint8_t mode, uint8_t ovwrIdx, int16_t ovwrValue)
void applyExpos(int16_t * anas, uint8_t mode, int16_t ovwrIdx, int16_t ovwrValue)
{
int8_t cur_chn = -1;
for (uint8_t i=0; i<MAX_EXPOS; i++) {
if (mode == e_perout_mode_normal) mixState[i].activeExpo = false;
ExpoData * ed = expoAddress(i);
mixsrc_t srcRaw = ed->srcRaw;
mixsrc_t src = abs(srcRaw);
if (!EXPO_VALID(ed)) break; // end of list
if (ed->chn == cur_chn)
continue;
if (ed->flightModes & (1<<mixerCurrentFlightMode))
continue;
if (ed->srcRaw >= MIXSRC_FIRST_TRAINER && ed->srcRaw <= MIXSRC_LAST_TRAINER && !isTrainerValid())
if (src >= MIXSRC_FIRST_TRAINER && src <= MIXSRC_LAST_TRAINER && !isTrainerValid())
continue;
if (getSwitch(ed->swtch)) {
int32_t v;
if (ed->srcRaw == ovwrIdx) {
if (srcRaw == ovwrIdx) {
v = ovwrValue;
}
else {
v = getValue(ed->srcRaw);
if (ed->srcRaw >= MIXSRC_FIRST_TELEM && ed->scale > 0) {
v = (v * 1024) / convertTelemValue(ed->srcRaw-MIXSRC_FIRST_TELEM+1, ed->scale);
v = getValue(srcRaw);
if (src >= MIXSRC_FIRST_TELEM && ed->scale > 0) {
v = (v * 1024) / convertTelemValue(src-MIXSRC_FIRST_TELEM+1, ed->scale);
}
v = limit<int32_t>(-1024, v, 1024);
}
@@ -201,11 +203,12 @@ void applyExpos(int16_t * anas, uint8_t mode, uint8_t ovwrIdx, int16_t ovwrValue
//========== TRIMS ================
if (ed->trimSource < TRIM_ON)
virtualInputsTrims[cur_chn] = -ed->trimSource - 1;
else if (ed->trimSource == TRIM_ON && ed->srcRaw >= MIXSRC_FIRST_STICK &&
ed->srcRaw <= MIXSRC_LAST_STICK)
virtualInputsTrims[cur_chn] = ed->srcRaw - MIXSRC_FIRST_STICK;
else if (ed->trimSource == TRIM_ON && src >= MIXSRC_FIRST_STICK &&
src <= MIXSRC_LAST_STICK)
virtualInputsTrims[cur_chn] = src - MIXSRC_FIRST_STICK;
else
virtualInputsTrims[cur_chn] = -1;
// if (srcRaw < 0) v = -v;
anas[cur_chn] = v;
}
}
@@ -313,7 +316,7 @@ static const getvalue_t _switch_3pos_lookup[] = {
// TODO same naming convention than the drawSource
// *valid added to return status to Lua for invalid sources
getvalue_t getValue(mixsrc_t i, bool* valid)
getvalue_t _getValue(mixsrc_t i, bool* valid)
{
if (i == MIXSRC_NONE) {
if (valid != nullptr) *valid = false;
@@ -325,7 +328,7 @@ getvalue_t getValue(mixsrc_t i, bool* valid)
#if defined(LUA_INPUTS)
else if (i <= MIXSRC_LAST_LUA) {
#if defined(LUA_MODEL_SCRIPTS)
div_t qr = div(i-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
div_t qr = div((uint16_t)(i-MIXSRC_FIRST_LUA), MAX_SCRIPT_OUTPUTS);
return scriptInputsOutputs[qr.quot].outputs[qr.rem].value;
#else
if (valid != nullptr) *valid = false;
@@ -464,7 +467,7 @@ getvalue_t getValue(mixsrc_t i, bool* valid)
return 0;
}
i -= MIXSRC_FIRST_TELEM;
div_t qr = div(i, 3);
div_t qr = div((uint16_t)i, 3);
TelemetryItem & telemetryItem = telemetryItems[qr.quot];
switch (qr.rem) {
case 1:
@@ -595,6 +598,18 @@ void evalInputs(uint8_t mode)
}
}
getvalue_t getValue(mixsrc_t i, bool* valid)
{
bool invert = false;
if (i < 0) {
invert = true;
i = -i;
}
getvalue_t v = _getValue(i, valid);
if (invert) v = -v;
return v;
}
#if defined(SURFACE_RADIO)
constexpr int IDLE_TRIM_SCALE = 1;
#else
+13 -11
View File
@@ -1881,43 +1881,45 @@ bool modelTelemetryEnabled() {
void getMixSrcRange(const int source, int16_t & valMin, int16_t & valMax, LcdFlags * flags)
{
if (source >= MIXSRC_FIRST_TRIM && source <= MIXSRC_LAST_TRIM) {
int asrc = abs(source);
if (asrc >= MIXSRC_FIRST_TRIM && asrc <= MIXSRC_LAST_TRIM) {
valMax = g_model.extendedTrims ? TRIM_EXTENDED_MAX : TRIM_MAX;
valMin = -valMax;
}
#if defined(LUA_INPUTS)
else if (source >= MIXSRC_FIRST_LUA && source <= MIXSRC_LAST_LUA) {
else if (asrc >= MIXSRC_FIRST_LUA && asrc <= MIXSRC_LAST_LUA) {
valMax = 30000;
valMin = -valMax;
}
#endif
else if (source < MIXSRC_FIRST_CH) {
else if (asrc < MIXSRC_FIRST_CH) {
valMax = 100;
valMin = -valMax;
}
else if (source <= MIXSRC_LAST_CH) {
else if (asrc <= MIXSRC_LAST_CH) {
valMax = g_model.extendedLimits ? LIMIT_EXT_PERCENT : 100;
valMin = -valMax;
}
#if defined(GVARS)
else if (source >= MIXSRC_FIRST_GVAR && source <= MIXSRC_LAST_GVAR) {
valMax = min<int>(CFN_GVAR_CST_MAX, MODEL_GVAR_MAX(source-MIXSRC_FIRST_GVAR));
valMin = max<int>(CFN_GVAR_CST_MIN, MODEL_GVAR_MIN(source-MIXSRC_FIRST_GVAR));
if (flags && g_model.gvars[source-MIXSRC_FIRST_GVAR].prec)
else if (asrc >= MIXSRC_FIRST_GVAR && asrc <= MIXSRC_LAST_GVAR) {
valMax = min<int>(CFN_GVAR_CST_MAX, MODEL_GVAR_MAX(asrc-MIXSRC_FIRST_GVAR));
valMin = max<int>(CFN_GVAR_CST_MIN, MODEL_GVAR_MIN(asrc-MIXSRC_FIRST_GVAR));
if (flags && g_model.gvars[asrc-MIXSRC_FIRST_GVAR].prec)
*flags |= PREC1;
}
#endif
else if (source == MIXSRC_TX_VOLTAGE) {
else if (asrc == MIXSRC_TX_VOLTAGE) {
valMax = 255;
valMin = 0;
if (flags)
*flags |= PREC1;
}
else if (source == MIXSRC_TX_TIME) {
else if (asrc == MIXSRC_TX_TIME) {
valMax = 23 * 60 + 59;
valMin = 0;
}
else if (source >= MIXSRC_FIRST_TIMER && source <= MIXSRC_LAST_TIMER) {
else if (asrc >= MIXSRC_FIRST_TIMER && asrc <= MIXSRC_LAST_TIMER) {
valMax = 9 * 60 * 60 - 1;
valMin = -valMax;
if (flags)
+1 -1
View File
@@ -401,7 +401,7 @@ int expo(int x, int k);
extern void getMixSrcRange(const int source, int16_t & valMin, int16_t & valMax, LcdFlags * flags = nullptr);
void applyExpos(int16_t * anas, uint8_t mode, uint8_t ovwrIdx=0, int16_t ovwrValue=0);
void applyExpos(int16_t * anas, uint8_t mode, int16_t ovwrIdx=0, int16_t ovwrValue=0);
int16_t applyLimits(uint8_t channel, int32_t value);
void evalInputs(uint8_t mode);
+1 -1
View File
@@ -83,7 +83,7 @@ typedef uint16_t event_t;
typedef uint32_t tmr10ms_t;
typedef int32_t rotenc_t;
typedef int32_t getvalue_t;
typedef uint32_t mixsrc_t;
typedef int32_t mixsrc_t;
typedef int32_t swsrc_t;
typedef int16_t safetych_t;
typedef int16_t gvar_t;
@@ -395,7 +395,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -429,7 +429,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -417,6 +417,38 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf,
return true;
}
static uint32_t r_mixSrcRawEx(const YamlNode* node, const char* val, uint8_t val_len)
{
bool invert = false;
if (val[0] == '!') {
invert = true;
val += 1;
val_len -= 1;
}
int32_t rv = r_mixSrcRaw(node, val, val_len);
if (invert)
rv = -rv;
return (uint32_t)rv;
}
static bool w_mixSrcRawExNoQuote(const YamlNode* node, uint32_t val, yaml_writer_func wf, void* opaque)
{
// Check for negative 10 bit value. TODO: handle this better!
val &= 0x3FF;
if (val >= 512) {
if (!wf(opaque, "!", 1)) return false;
val = 1024 - val;
}
return w_mixSrcRaw(node, val, wf, opaque);
}
static bool w_mixSrcRawEx(const YamlNode* node, uint32_t val, yaml_writer_func wf, void* opaque)
{
if (!wf(opaque, "\"", 1)) return false;
if (!w_mixSrcRawExNoQuote(node, val, wf, opaque)) return false;
return wf(opaque, "\"", 1);
}
static void r_rssiDisabled(void* user, uint8_t* data, uint32_t bitoffs,
const char* val, uint8_t val_len)
{
@@ -1459,7 +1491,7 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs,
case FUNC_BACKLIGHT:
case FUNC_PLAY_VALUE:
// find "," and cut val_len
CFN_PARAM(cfn) = r_mixSrcRaw(nullptr, val, l_sep);
CFN_PARAM(cfn) = r_mixSrcRawEx(nullptr, val, l_sep);
break;
case FUNC_PLAY_SOUND:
@@ -1554,10 +1586,10 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs,
CFN_PARAM(cfn) = yaml_str2int(val, l_sep);
break;
case FUNC_ADJUST_GVAR_SOURCE:
CFN_PARAM(cfn) = r_mixSrcRaw(nullptr, val, l_sep);
CFN_PARAM(cfn) = r_mixSrcRawEx(nullptr, val, l_sep);
break;
case FUNC_ADJUST_GVAR_GVAR: {
uint32_t gvar = r_mixSrcRaw(nullptr, val, l_sep);
uint32_t gvar = r_mixSrcRawEx(nullptr, val, l_sep);
if (gvar >= MIXSRC_FIRST_GVAR) {
CFN_PARAM(cfn) = gvar - MIXSRC_FIRST_GVAR;
}
@@ -1680,7 +1712,7 @@ static bool w_customFn(void* user, uint8_t* data, uint32_t bitoffs,
case FUNC_VOLUME:
case FUNC_BACKLIGHT:
case FUNC_PLAY_VALUE:
if (!w_mixSrcRaw(nullptr, CFN_PARAM(cfn), wf, opaque)) return false;
if (!w_mixSrcRawExNoQuote(nullptr, CFN_PARAM(cfn), wf, opaque)) return false;
break;
case FUNC_PLAY_SOUND:
@@ -1739,10 +1771,10 @@ static bool w_customFn(void* user, uint8_t* data, uint32_t bitoffs,
if (!wf(opaque, str, strlen(str))) return false;
break;
case FUNC_ADJUST_GVAR_SOURCE:
if (!w_mixSrcRaw(nullptr, CFN_PARAM(cfn), wf, opaque)) return false;
if (!w_mixSrcRawExNoQuote(nullptr, CFN_PARAM(cfn), wf, opaque)) return false;
break;
case FUNC_ADJUST_GVAR_GVAR:
if (!w_mixSrcRaw(nullptr, CFN_PARAM(cfn) + MIXSRC_FIRST_GVAR, wf, opaque)) return false;
if (!w_mixSrcRawExNoQuote(nullptr, CFN_PARAM(cfn) + MIXSRC_FIRST_GVAR, wf, opaque)) return false;
break;
}
break;
@@ -1837,11 +1869,11 @@ static void r_logicSw(void* user, uint8_t* data, uint32_t bitoffs,
break;
case LS_FAMILY_COMP:
ls->v1 = r_mixSrcRaw(nullptr, val, l_sep);
ls->v1 = r_mixSrcRawEx(nullptr, val, l_sep);
val += l_sep; val_len -= l_sep;
if (!val_len || val[0] != ',') return;
val++; val_len--;
ls->v2 = r_mixSrcRaw(nullptr, val, val_len);
ls->v2 = r_mixSrcRawEx(nullptr, val, val_len);
break;
case LS_FAMILY_TIMER:
@@ -1853,7 +1885,7 @@ static void r_logicSw(void* user, uint8_t* data, uint32_t bitoffs,
break;
default:
ls->v1 = r_mixSrcRaw(nullptr, val, l_sep);
ls->v1 = r_mixSrcRawEx(nullptr, val, l_sep);
val += l_sep; val_len -= l_sep;
if (!val_len || val[0] != ',') return;
val++; val_len--;
@@ -1902,9 +1934,9 @@ static bool w_logicSw(void* user, uint8_t* data, uint32_t bitoffs,
break;
case LS_FAMILY_COMP:
if (!w_mixSrcRaw(nullptr, ls->v1, wf, opaque)) return false;
if (!w_mixSrcRawExNoQuote(nullptr, ls->v1, wf, opaque)) return false;
if (!wf(opaque,",",1)) return false;
if (!w_mixSrcRaw(nullptr, ls->v2, wf, opaque)) return false;
if (!w_mixSrcRawExNoQuote(nullptr, ls->v2, wf, opaque)) return false;
break;
case LS_FAMILY_TIMER:
@@ -1916,7 +1948,7 @@ static bool w_logicSw(void* user, uint8_t* data, uint32_t bitoffs,
break;
default:
if (!w_mixSrcRaw(nullptr, ls->v1, wf, opaque)) return false;
if (!w_mixSrcRawExNoQuote(nullptr, ls->v1, wf, opaque)) return false;
if (!wf(opaque,",",1)) return false;
// TODO?: ls->v1 <= MIXSRC_LAST_CH ? calc100toRESX(ls->v2) : ls->v2
str = yaml_signed2str(ls->v2);
@@ -422,7 +422,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -456,7 +456,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -422,7 +422,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -456,7 +456,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -395,7 +395,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -429,7 +429,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -395,7 +395,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -429,7 +429,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -424,7 +424,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -458,7 +458,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -424,7 +424,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -458,7 +458,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -395,7 +395,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -429,7 +429,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -396,7 +396,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -430,7 +430,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
@@ -398,7 +398,7 @@ static const struct YamlNode struct_CurveRef[] = {
static const struct YamlNode struct_MixData[] = {
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
YAML_UNSIGNED( "destCh", 5 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "carryTrim", 1 ),
YAML_UNSIGNED( "mixWarn", 2 ),
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
@@ -432,7 +432,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_UNSIGNED( "scale", 14 ),
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
YAML_SIGNED( "trimSource", 6 ),
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
YAML_UNSIGNED( "chn", 5 ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
+20 -11
View File
@@ -609,9 +609,17 @@ const char *getPotLabel(uint8_t idx)
// this should be declared in header, but it used so much foreign symbols that
// we declare it in cpp-file and pre-instantiate it for the uses
template <size_t L>
char *getSourceString(char (&dest)[L], mixsrc_t idx)
char *getSourceString(char (&destRef)[L], mixsrc_t idx)
{
size_t dest_len = L;
char* dest = destRef;
if (idx < 0) {
idx = -idx;
dest[0] = '!';
dest += 1;
dest_len -= 1;
}
if (idx == MIXSRC_NONE) {
strncpy(dest, STR_EMPTY, dest_len - 1);
@@ -634,7 +642,7 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx)
#if defined(LUA_INPUTS)
else if (idx <= MIXSRC_LAST_LUA) {
#if defined(LUA_MODEL_SCRIPTS)
div_t qr = div(idx - MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
div_t qr = div((uint16_t)(idx - MIXSRC_FIRST_LUA), MAX_SCRIPT_OUTPUTS);
if (qr.quot < MAX_SCRIPTS &&
qr.rem < scriptInputsOutputs[qr.quot].outputsCount) {
static_assert(L > sizeof(STR_CHAR_LUA) - 1, "dest string too small");
@@ -658,7 +666,7 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx)
}
}
#else
strncpy(dest, "N/A", L - 1);
strncpy(dest, "N/A", dest_len-1);
#endif
}
#endif
@@ -723,7 +731,7 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx)
} else if (idx <= MIXSRC_LAST_CH) {
auto ch = idx - MIXSRC_FIRST_CH;
if (g_model.limitData[ch].name[0] != '\0') {
copyToTerminated(dest, g_model.limitData[ch].name);
strAppend(dest, g_model.limitData[ch].name, LEN_CHANNEL_NAME);
} else {
strAppendStringWithIndex(dest, STR_CH, ch + 1);
}
@@ -759,21 +767,21 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx)
} else if (idx <= MIXSRC_LAST_TIMER) {
idx -= MIXSRC_FIRST_TIMER;
if (g_model.timers[idx].name[0] != '\0') {
copyToTerminated(dest, g_model.timers[idx].name);
strAppend(dest, g_model.timers[idx].name, LEN_TIMER_NAME);
} else {
strAppendStringWithIndex(dest, STR_SRC_TIMER, idx + 1);
}
} else {
idx -= MIXSRC_FIRST_TELEM;
div_t qr = div(idx, 3);
char *pos = strAppend(dest, STR_CHAR_TELEMETRY, 2);
div_t qr = div((uint16_t)idx, 3);
char* pos = strAppend(dest, STR_CHAR_TELEMETRY, 2);
pos = strAppend(pos, g_model.telemetrySensors[qr.quot].label,
sizeof(g_model.telemetrySensors[qr.quot].label));
if (qr.rem) *pos = (qr.rem == 2 ? '+' : '-');
*++pos = '\0';
}
dest[L - 1] = '\0'; // assert the termination
return dest;
destRef[L - 1] = '\0'; // assert the termination
return destRef;
}
// pre-instantiate for use from external
@@ -850,9 +858,10 @@ char *getSensorCustomValueString(char (&dest)[L], uint8_t sensor, int32_t val,
}
template <size_t L>
char *getSourceCustomValueString(char (&dest)[L], source_t source, int32_t val,
char *getSourceCustomValueString(char (&dest)[L], mixsrc_t source, int32_t val,
LcdFlags flags)
{
source = abs(source);
size_t len = L - 1;
if (source >= MIXSRC_FIRST_TELEM) {
source = (source - MIXSRC_FIRST_TELEM) / 3;
@@ -967,7 +976,7 @@ std::string formatNumberAsString(int32_t val, LcdFlags flags, uint8_t len,
return std::string(s);
}
char *getSourceCustomValueString(source_t source, int32_t val, LcdFlags flags)
char *getSourceCustomValueString(mixsrc_t source, int32_t val, LcdFlags flags)
{
return getSourceCustomValueString(_static_str_buffer, source, val, flags);
}
+2 -16
View File
@@ -112,7 +112,7 @@ template <size_t L>
char *getSourceString(char (&dest)[L], mixsrc_t idx);
template <size_t L>
char *getSourceCustomValueString(char (&dest)[L], source_t source, int32_t val,
char *getSourceCustomValueString(char (&dest)[L], mixsrc_t source, int32_t val,
LcdFlags flags);
#endif
@@ -120,7 +120,7 @@ char *getSourceCustomValueString(char (&dest)[L], source_t source, int32_t val,
char *getFlightModeString(char *dest, int8_t idx);
char *getSourceString(mixsrc_t idx);
char *getSourceCustomValueString(source_t source, int32_t val, LcdFlags flags);
char *getSourceCustomValueString(mixsrc_t source, int32_t val, LcdFlags flags);
char *getSwitchPositionName(swsrc_t idx);
char *getCurveString(int idx);
char *getTimerString(int32_t tme, TimerOptions timerOptions = {.options = 0});
@@ -151,20 +151,6 @@ void clearStruct(S &s)
template <size_t N>
using offset_t = std::integral_constant<size_t, N>;
template <size_t DL, size_t SL, size_t O = 0>
void copyToTerminated(char (&dest)[DL], const char (&src)[SL],
const offset_t<O> = offset_t<0>{})
{
// unfortinately std::min() isn't constexpr in C++11
// static constexpr size_t len = std::min(DL - O - 1, SL);
static constexpr size_t dl{DL - O - 1};
static_assert(dl > 0, "wrong sizes or offset");
static constexpr size_t len = (dl < SL) ? dl : SL;
strncpy(&dest[O], &src[0], len);
static_assert((len + O) < DL, "wrong sizes of offset");
dest[len + O] = '\0';
}
template <size_t L1, size_t L2>
int strncasecmp(char (&s1)[L1], const char (&s2)[L2])
{
-2
View File
@@ -22,8 +22,6 @@
#include "themes/etx_lv_theme.h"
#include "translations.h"
constexpr uint32_t MENUS_TOOLBAR_BUTTON_WIDTH = 32;
static const lv_obj_class_t menu_button_class = {
.base_class = &button_class,
.constructor_cb = nullptr,
+2
View File
@@ -21,6 +21,8 @@
#include "button.h"
#include "choice.h"
constexpr uint32_t MENUS_TOOLBAR_BUTTON_WIDTH = 32;
class Menu;
class MenuToolbarButton : public ButtonBase