diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7d846e898..74e6ccca0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ project(OpenTX)
set(VERSION_MAJOR "2")
set(VERSION_MINOR "3")
-set(VERSION_REVISION "11")
+set(VERSION_REVISION "12")
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
diff --git a/CREDITS.txt b/CREDITS.txt
index 11971219f..1666c5fce 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -2080,3 +2080,28 @@ Carl Payne
Adam Sosnowski
Гасак Сергей
SaltCtyRacingFPV
+Georg Bernhardt
+James Mildenhall
+Dave Plummer
+Ivan Mokris
+Patrick Daniels
+Stuart Olson
+Cory Znebel
+Andrey Yarovoy
+Christian Pons
+Burt Pickard-Richardson
+Michal Mesaros
+Conrad Young
+Martin Mathes
+Jens Rainer Hansen
+Mark Trible
+Marc Dubois
+Alan Wilkins
+Daniel Hryciuk
+Thomas Fox
+Sidney B Harden
+Augustas Sereika
+David Belletete
+Karl-Heinz Behn
+Lena Hjort
+Jan Langhorst
diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt
index 3d27550e6..3150a86ca 100644
--- a/companion/src/CMakeLists.txt
+++ b/companion/src/CMakeLists.txt
@@ -345,6 +345,8 @@ elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T12)
set(FLAVOUR t12)
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TX12)
set(FLAVOUR tx12)
+elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T8)
+ set(FLAVOUR t8)
elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)
set(FLAVOUR x9d+2019)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS)
diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc
index fbbacdb48..ca17c812c 100644
--- a/companion/src/companion.qrc
+++ b/companion/src/companion.qrc
@@ -190,6 +190,18 @@
images/simulator/TX12/right-mdl.png
images/simulator/TX12/bottom.png
images/simulator/TX12/top.png
+ images/simulator/T8/left.png
+ images/simulator/T8/left-pageup.png
+ images/simulator/T8/left-pagedn.png
+ images/simulator/T8/left-rtn.png
+ images/simulator/T8/left-sys.png
+ images/simulator/T8/right.png
+ images/simulator/T8/right-ent.png
+ images/simulator/T8/right-mdl.png
+ images/simulator/T8/right-up.png
+ images/simulator/T8/right-dn.png
+ images/simulator/T8/bottom.png
+ images/simulator/T8/top.png
images/simulator/JumperT16/left.png
images/simulator/JumperT16/right.png
images/simulator/JumperT16/top.png
diff --git a/companion/src/datamodels/CMakeLists.txt b/companion/src/datamodels/CMakeLists.txt
index beb7d4d2d..446f161b3 100644
--- a/companion/src/datamodels/CMakeLists.txt
+++ b/companion/src/datamodels/CMakeLists.txt
@@ -1,12 +1,12 @@
set(datamodels_SRCS
- rawitemdatamodels.cpp
- rawitemfilteredmodel.cpp
+ compounditemmodels.cpp
+ filtereditemmodels.cpp
)
set(datamodels_HDRS
- rawitemdatamodels.h
- rawitemfilteredmodel.h
+ compounditemmodels.h
+ filtereditemmodels.h
)
qt5_wrap_cpp(datamodels_SRCS ${datamodels_HDRS})
diff --git a/companion/src/datamodels/compounditemmodels.cpp b/companion/src/datamodels/compounditemmodels.cpp
new file mode 100644
index 000000000..039e90244
--- /dev/null
+++ b/companion/src/datamodels/compounditemmodels.cpp
@@ -0,0 +1,705 @@
+/*
+ * Copyright (C) OpenTX
+ *
+ * Based on code named
+ * th9x - http://code.google.com/p/th9x
+ * er9x - http://code.google.com/p/er9x
+ * gruvin9x - http://code.google.com/p/gruvin9x
+ *
+ * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "compounditemmodels.h"
+#include "generalsettings.h"
+#include "eeprominterface.h"
+#include "modeldata.h"
+#include "adjustmentreference.h"
+
+// static
+QString AbstractItemModel::idToString(const int value)
+{
+ switch (value) {
+ case IMID_Unknown:
+ return "Unknown";
+ case IMID_RawSource:
+ return "RawSource";
+ case IMID_RawSwitch:
+ return "RawSwitch";
+ case IMID_Curve:
+ return "Curve";
+ case IMID_GVarRef:
+ return "GVarRef";
+ case IMID_ThrSource:
+ return "ThrSource";
+ case IMID_CustomFuncAction:
+ return "CustomFuncAction";
+ case IMID_CustomFuncResetParam:
+ return "CustomFuncResetParam";
+ case IMID_TeleSource:
+ return "TeleSource";
+ case IMID_CurveRefType:
+ return "CurveRefType";
+ case IMID_CurveRefFunc:
+ return "CurveRefFunc";
+ default:
+ return "Custom";
+ }
+}
+
+// static
+void AbstractItemModel::dumpItemModelContents(AbstractItemModel * itemModel)
+{
+ if (itemModel) {
+ qDebug() << "id:" << itemModel->getId() << "name:" << itemModel->getName();
+
+ for (int i = 0; i < itemModel->rowCount(); ++i) {
+ qDebug() << "row:" << i
+ << "text:" << itemModel->data(itemModel->index(i, 0), Qt::DisplayRole).toString()
+ << "id:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Id).toInt()
+ << "avail:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Available).toBool()
+ << "flags:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Flags).toInt()
+ << "type:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Type).toInt();
+ }
+ }
+ else
+ qDebug() << "Error: model not of class AbstractItemModel";
+}
+
+//
+// AbstractStaticItemModel
+//
+
+void AbstractStaticItemModel::loadItemList()
+{
+ foreach (const ListItem *item, itemList) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setText(item->text);
+ modelItem->setData(item->id, IMDR_Id);
+ modelItem->setData(item->type, IMDR_Type);
+ modelItem->setData(item->flags, IMDR_Flags);
+ modelItem->setData(item->isAvailable, IMDR_Available);
+ appendRow(modelItem);
+ }
+
+ itemList.clear();
+};
+
+//
+// RawSourceItemModel
+//
+
+RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_RawSource);
+ setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts));
+
+ 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::MaxAnalogs));
+ addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, firmware->getCapability(RotaryEncoders));
+ addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board->getCapability(Board::NumTrims));
+ addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
+ addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board->getCapability(Board::Switches));
+ addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, firmware->getCapability(LogicalSwitches));
+ addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
+ addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, firmware->getCapability(TrainerInputs));
+ addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, firmware->getCapability(Outputs));
+ addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
+ addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, firmware->getCapability(Sensors) * 3);
+ addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, firmware->getCapability(Gvars));
+}
+
+void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
+{
+ item->setText(src.toString(modelData, generalSettings, boardType));
+ item->setData(src.isAvailable(modelData, generalSettings, boardType), IMDR_Available);
+}
+
+void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
+{
+ for (int i = start; i < start + count; i++) {
+ const RawSource src = RawSource(type, i);
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setData(src.toValue(), IMDR_Id);
+ modelItem->setData(type, IMDR_Type);
+ modelItem->setData(group, IMDR_Flags);
+ setDynamicItemData(modelItem, src);
+ appendRow(modelItem);
+ }
+}
+
+void RawSourceItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i)
+ setDynamicItemData(item(i), RawSource(item(i)->data(IMDR_Id).toInt()));
+
+ emit updateComplete();
+ }
+}
+
+//
+// RawSwitchItemModel
+//
+
+RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_RawSwitch);
+ setUpdateMask(IMUE_FlightModes | IMUE_LogicalSwitches | IMUE_TeleSensors);
+
+ // Descending switch direction: NOT (!) switches
+ addItems(SWITCH_TYPE_ACT, -1);
+ addItems(SWITCH_TYPE_SENSOR, -firmware->getCapability(Sensors));
+ addItems(SWITCH_TYPE_TELEMETRY, -1);
+ addItems(SWITCH_TYPE_FLIGHT_MODE, -firmware->getCapability(FlightModes));
+ addItems(SWITCH_TYPE_VIRTUAL, -firmware->getCapability(LogicalSwitches));
+ addItems(SWITCH_TYPE_ROTARY_ENCODER, -firmware->getCapability(RotaryEncoders));
+ addItems(SWITCH_TYPE_TRIM, -board->getCapability(Board::NumTrimSwitches));
+ addItems(SWITCH_TYPE_MULTIPOS_POT, -(board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions)));
+ addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchPositions));
+
+ // Ascending switch direction (including zero)
+ addItems(SWITCH_TYPE_TIMER_MODE, 5);
+ addItems(SWITCH_TYPE_NONE, 1);
+ addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchPositions));
+ addItems(SWITCH_TYPE_MULTIPOS_POT, board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions));
+ addItems(SWITCH_TYPE_TRIM, board->getCapability(Board::NumTrimSwitches));
+ addItems(SWITCH_TYPE_ROTARY_ENCODER, firmware->getCapability(RotaryEncoders));
+ addItems(SWITCH_TYPE_VIRTUAL, firmware->getCapability(LogicalSwitches));
+ addItems(SWITCH_TYPE_FLIGHT_MODE, firmware->getCapability(FlightModes));
+ addItems(SWITCH_TYPE_TELEMETRY, 1);
+ addItems(SWITCH_TYPE_SENSOR, firmware->getCapability(Sensors));
+ addItems(SWITCH_TYPE_ON, 1);
+ addItems(SWITCH_TYPE_ONE, 1);
+ addItems(SWITCH_TYPE_ACT, 1);
+}
+
+void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
+{
+ item->setText(rsw.toString(boardType, generalSettings, modelData));
+ item->setData(rsw.isAvailable(modelData, generalSettings, boardType), IMDR_Available);
+}
+
+void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
+{
+ // Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
+ const static QVector rawSwitchIndexBaseZeroTypes = QVector() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
+ // handle exceptions in RawSwitch() index values
+ const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
+
+ // determine cotext flags
+ int context = RawSwitch::AllSwitchContexts;
+ switch (type) {
+ case SWITCH_TYPE_FLIGHT_MODE:
+ context &= ~RawSwitch::MixesContext;
+ // fallthrough
+ case SWITCH_TYPE_VIRTUAL:
+ case SWITCH_TYPE_SENSOR:
+ context &= ~RawSwitch::GlobalFunctionsContext;
+ break;
+
+ case SWITCH_TYPE_TIMER_MODE:
+ context = RawSwitch::TimersContext;
+ break;
+
+ case SWITCH_TYPE_NONE:
+ context &= ~RawSwitch::TimersContext;
+ break;
+
+ case SWITCH_TYPE_ON:
+ case SWITCH_TYPE_ONE:
+ context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
+ break;
+
+ default:
+ break;
+ }
+
+ int i = (count < 0 ? count : 1);
+ count = (i < 0 ? 0 : count + i);
+ for ( ; i < count; ++i) {
+ RawSwitch rs(type, i + rawIdxAdj);
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setData(rs.toValue(), IMDR_Id);
+ modelItem->setData(type, IMDR_Type);
+ modelItem->setData(context, IMDR_Flags);
+ setDynamicItemData(modelItem, rs);
+ appendRow(modelItem);
+ }
+}
+
+void RawSwitchItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i)
+ setDynamicItemData(item(i), RawSwitch(item(i)->data(IMDR_Id).toInt()));
+
+ emit updateComplete();
+ }
+}
+
+//
+// CurveItemModel
+//
+
+CurveItemModel::CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_Curve);
+
+ if (!modelData)
+ return;
+
+ setUpdateMask(IMUE_Curves);
+
+ const int count = firmware->getCapability(NumCurves);
+
+ for (int i = -count ; i <= count; ++i) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setData(i, IMDR_Id);
+ modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
+ setDynamicItemData(modelItem, i);
+ appendRow(modelItem);
+ }
+}
+
+void CurveItemModel::setDynamicItemData(QStandardItem * item, const int value) const
+{
+ CurveReference cr = CurveReference(CurveReference::CURVE_REF_CUSTOM, value);
+ item->setText(cr.toString(modelData, false));
+ item->setData(cr.isAvailable(), IMDR_Available);
+}
+
+void CurveItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i)
+ setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
+
+ emit updateComplete();
+ }
+}
+
+//
+// GVarReferenceItemModel
+//
+
+GVarReferenceItemModel::GVarReferenceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_GVarRef);
+
+ if (!modelData)
+ return;
+
+ setUpdateMask(IMUE_GVars | IMUE_FlightModes | IMUE_LogicalSwitches);
+
+ const int count = firmware->getCapability(Gvars);
+
+ if (count > 0) {
+ addItems(-count);
+ addItems(count);
+ }
+}
+
+void GVarReferenceItemModel::addItems(int count)
+{
+ int i = (count < 0 ? count : 1);
+ count = (i < 0 ? 0 : count + i);
+ for ( ; i < count; ++i) {
+ QStandardItem * modelItem = new QStandardItem();
+ AdjustmentReference ar(AdjustmentReference::ADJUST_REF_GVAR, i);
+ modelItem->setData(ar.toValue(), IMDR_Id);
+ modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
+ setDynamicItemData(modelItem, ar);
+ appendRow(modelItem);
+ }
+}
+
+void GVarReferenceItemModel::setDynamicItemData(QStandardItem * item, const AdjustmentReference & ar) const
+{
+ item->setText(ar.toString(modelData, false));
+ item->setData(ar.isAvailable(), IMDR_Available);
+}
+
+void GVarReferenceItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i)
+ setDynamicItemData(item(i), AdjustmentReference(item(i)->data(IMDR_Id).toInt()));
+
+ emit updateComplete();
+ }
+}
+
+//
+// ThrottleSourceItemModel
+//
+
+ThrottleSourceItemModel::ThrottleSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_ThrSource);
+
+ if (!modelData)
+ return;
+
+ setUpdateMask(IMUE_Timers | IMUE_Inputs | IMUE_TeleSensors);
+
+ for (int i = 0; i < modelData->thrTraceSrcCount(); i++) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setData(i, IMDR_Id);
+ setDynamicItemData(modelItem, i);
+ appendRow(modelItem);
+ }
+}
+
+void ThrottleSourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
+{
+ item->setText(modelData->thrTraceSrcToString(value));
+ item->setData(modelData->isThrTraceSrcAvailable(generalSettings, value), IMDR_Available);
+}
+
+void ThrottleSourceItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i)
+ setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
+
+ emit updateComplete();
+ }
+}
+
+//
+// CustomFuncActionItemModel
+//
+
+CustomFuncActionItemModel::CustomFuncActionItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_CustomFuncAction);
+ setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts));
+
+ for (int i = 0; i < AssignFunc::FuncCount; i++) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setData(i, IMDR_Id);
+ modelItem->setData(CustomFunctionData::funcContext(i), IMDR_Flags);
+ setDynamicItemData(modelItem, i);
+ appendRow(modelItem);
+ }
+}
+
+void CustomFuncActionItemModel::setDynamicItemData(QStandardItem * item, const int value) const
+{
+ item->setText(CustomFunctionData(AssignFunc(value)).funcToString(modelData));
+ item->setData(CustomFunctionData::isFuncAvailable(value), IMDR_Available);
+}
+
+void CustomFuncActionItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i)
+ setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
+
+ emit updateComplete();
+ }
+}
+
+//
+// CustomFuncResetParamItemModel
+//
+
+CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_CustomFuncResetParam);
+ setUpdateMask(IMUE_TeleSensors);
+
+ for (int i = 0; i < CustomFunctionData::resetParamCount(modelData); i++) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setData(i, IMDR_Id);
+ setDynamicItemData(modelItem, i);
+ appendRow(modelItem);
+ }
+}
+
+void CustomFuncResetParamItemModel::setDynamicItemData(QStandardItem * item, const int value) const
+{
+ CustomFunctionData cfd = CustomFunctionData(AssignFunc::FuncReset);
+ cfd.param = value;
+ item->setText(cfd.paramToString(modelData));
+ item->setData(CustomFunctionData::isResetParamAvailable(modelData, value), IMDR_Available);
+}
+
+void CustomFuncResetParamItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i)
+ setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
+
+ emit updateComplete();
+ }
+}
+
+//
+// TelemetrySourceItemModel
+//
+
+TelemetrySourceItemModel::TelemetrySourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_TeleSource);
+
+ if (!modelData)
+ return;
+
+ setUpdateMask(IMUE_TeleSensors);
+ const int count = firmware->getCapability(Sensors);
+
+ for (int i = -count; i <= count; ++i) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setData(i, IMDR_Id);
+ modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
+ setDynamicItemData(modelItem, i);
+ appendRow(modelItem);
+ }
+}
+
+void TelemetrySourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
+{
+ item->setText(SensorData::sourceToString(modelData, value));
+ item->setData(SensorData::isSourceAvailable(modelData, value), IMDR_Available);
+}
+
+void TelemetrySourceItemModel::update(const int event)
+{
+ if (doUpdate(event)) {
+ emit aboutToBeUpdated();
+
+ for (int i = 0; i < rowCount(); ++i) {
+ setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
+ }
+
+ emit updateComplete();
+ }
+}
+
+//
+// CurveRefTypeItemModel
+//
+
+CurveRefTypeItemModel::CurveRefTypeItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractStaticItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_CurveRefType);
+
+ for (int i = 0; i <= CurveReference::MAX_CURVE_REF_TYPE; i++) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setText(CurveReference::typeToString((CurveReference::CurveRefType)i));
+ modelItem->setData(i, IMDR_Id);
+ modelItem->setData(CurveReference::isTypeAvailable((CurveReference::CurveRefType)i), IMDR_Available);
+ appendRow(modelItem);
+ }
+}
+
+//
+// CurveRefFuncItemModel
+//
+
+CurveRefFuncItemModel::CurveRefFuncItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractStaticItemModel(generalSettings, modelData, firmware, board, boardType)
+{
+ setId(IMID_CurveRefFunc);
+
+ for (int i = 1; i <= CurveReference::functionCount(); i++) {
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setText(CurveReference::functionToString(i));
+ modelItem->setData(i, IMDR_Id);
+ modelItem->setData(CurveReference::isFunctionAvailable(i), IMDR_Available);
+ appendRow(modelItem);
+ }
+}
+
+//
+// PrecisionItemModel
+//
+
+PrecisionItemModel::PrecisionItemModel(const int minDecimals, const int maxDecimals, const QString suffix, const bool placeholders) :
+ AbstractStaticItemModel()
+{
+ for (int i = minDecimals, j = maxDecimals; j >= 0; i++, j--) {
+ QString str = QString("0.%1").arg(QString(i, '0'));
+ if (placeholders)
+ str.append(QString(j, '_'));
+ if (!suffix.isEmpty())
+ str.append(QString(" %1").arg(suffix));
+ QStandardItem * modelItem = new QStandardItem();
+ modelItem->setText(str);
+ modelItem->setData(i, IMDR_Id);
+ modelItem->setData(true, IMDR_Available);
+ appendRow(modelItem);
+ }
+}
+
+//
+// CompoundItemModelFactory
+//
+
+CompoundItemModelFactory::CompoundItemModelFactory(const GeneralSettings * const generalSettings, const ModelData * const modelData) :
+ generalSettings(generalSettings),
+ modelData(modelData)
+{
+ firmware = getCurrentFirmware();
+ board = new Boards(getCurrentBoard());
+ boardType = getCurrentBoard();
+}
+
+CompoundItemModelFactory::~CompoundItemModelFactory()
+{
+ unregisterItemModels();
+ delete board;
+}
+
+void CompoundItemModelFactory::addItemModel(const int id)
+{
+ switch (id) {
+ case AbstractItemModel::IMID_RawSource:
+ registerItemModel(new RawSourceItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_RawSwitch:
+ registerItemModel(new RawSwitchItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_Curve:
+ registerItemModel(new CurveItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_GVarRef:
+ registerItemModel(new GVarReferenceItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_ThrSource:
+ registerItemModel(new ThrottleSourceItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_CustomFuncAction:
+ registerItemModel(new CustomFuncActionItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_CustomFuncResetParam:
+ registerItemModel(new CustomFuncResetParamItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_TeleSource:
+ registerItemModel(new TelemetrySourceItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_CurveRefType:
+ registerItemModel(new CurveRefTypeItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ case AbstractItemModel::IMID_CurveRefFunc:
+ registerItemModel(new CurveRefFuncItemModel(generalSettings, modelData, firmware, board, boardType));
+ break;
+ default:
+ qDebug() << "Error: unknown item model: id";
+ break;
+ }
+}
+
+int CompoundItemModelFactory::registerItemModel(AbstractItemModel * itemModel)
+{
+ if (itemModel) {
+ if (!isItemModelRegistered(itemModel->getId())) {
+ setSourceId(itemModel);
+ registeredItemModels.append(itemModel);
+ return itemModel->getId();
+ }
+ else
+ return itemModel->getId();
+ }
+ return -1;
+}
+
+void CompoundItemModelFactory::unregisterItemModels()
+{
+ foreach (AbstractItemModel *itemModel, registeredItemModels) {
+ delete itemModel;
+ }
+}
+
+void CompoundItemModelFactory::unregisterItemModel(const int id)
+{
+ AbstractItemModel * itemModel = getItemModel(id);
+ if (itemModel)
+ delete itemModel;
+}
+
+AbstractItemModel * CompoundItemModelFactory::getItemModel(const int id) const
+{
+ foreach (AbstractItemModel * itemModel, registeredItemModels) {
+ if (itemModel->getId() == id)
+ return itemModel;
+ }
+
+ return nullptr;
+}
+
+bool CompoundItemModelFactory::isItemModelRegistered(const int id) const
+{
+ foreach (AbstractItemModel * itemModel, registeredItemModels) {
+ if (itemModel->getId() == id)
+ return true;
+ }
+
+ return false;
+}
+
+void CompoundItemModelFactory::update(const int event)
+{
+ foreach (AbstractItemModel * itemModel, registeredItemModels) {
+ itemModel->update(event);
+ }
+}
+
+void CompoundItemModelFactory::dumpAllItemModelContents() const
+{
+ foreach (AbstractItemModel * itemModel, registeredItemModels) {
+ AbstractItemModel::dumpItemModelContents(itemModel);
+ }
+}
+
+void CompoundItemModelFactory::setSourceId(AbstractItemModel * itemModel)
+{
+ if (itemModel && itemModel->getId() == AbstractItemModel::IMID_Unknown)
+ itemModel->setId(AbstractItemModel::IMID_ReservedCount + registeredItemModels.count());
+}
diff --git a/companion/src/datamodels/compounditemmodels.h b/companion/src/datamodels/compounditemmodels.h
new file mode 100644
index 000000000..de32fc902
--- /dev/null
+++ b/companion/src/datamodels/compounditemmodels.h
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) OpenTX
+ *
+ * Based on code named
+ * th9x - http://code.google.com/p/th9x
+ * er9x - http://code.google.com/p/er9x
+ * gruvin9x - http://code.google.com/p/gruvin9x
+ *
+ * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef COMPOUNDITEMMODELS_H
+#define COMPOUNDITEMMODELS_H
+
+#include "rawsource.h"
+#include "rawswitch.h"
+
+#include
+
+class GeneralSettings;
+class ModelData;
+class AdjustmentReference;
+
+class AbstractItemModel: public QStandardItemModel
+{
+ Q_OBJECT
+ public:
+ enum ItemModelId {
+ IMID_Unknown,
+ IMID_RawSource,
+ IMID_RawSwitch,
+ IMID_Curve,
+ IMID_GVarRef,
+ IMID_ThrSource,
+ IMID_CustomFuncAction,
+ IMID_CustomFuncResetParam,
+ IMID_TeleSource,
+ IMID_CurveRefType,
+ IMID_CurveRefFunc,
+ IMID_ReservedCount,
+ IMID_Custom
+ };
+ Q_ENUM(ItemModelId)
+
+ enum ItemModelDataRoles {
+ IMDR_Id = Qt::UserRole,
+ IMDR_Type,
+ IMDR_Flags,
+ IMDR_Available
+ };
+ Q_ENUM(ItemModelDataRoles)
+
+ enum ItemModelDataGroups {
+ IMDG_None = 0x01,
+ IMDG_Negative = 0x02,
+ IMDG_Positive = 0x04
+ };
+ Q_ENUM(ItemModelDataGroups)
+
+ enum ItemModelUpdateEvent {
+ IMUE_None = 0,
+ IMUE_SystemRefresh = 1 << 0,
+ IMUE_Channels = 1 << 1,
+ IMUE_Curves = 1 << 2,
+ IMUE_FlightModes = 1 << 3,
+ IMUE_GVars = 1 << 4,
+ IMUE_Inputs = 1 << 5,
+ IMUE_LogicalSwitches = 1 << 6,
+ IMUE_Scripts = 1 << 7,
+ IMUE_TeleSensors = 1 << 8,
+ IMUE_Timers = 1 << 9,
+ IMUE_All = IMUE_SystemRefresh | IMUE_Channels | IMUE_Curves | IMUE_FlightModes | IMUE_GVars | IMUE_Inputs |
+ IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers
+ };
+ Q_ENUM(ItemModelUpdateEvent)
+
+ explicit AbstractItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ QStandardItemModel(nullptr),
+ generalSettings(generalSettings),
+ modelData(modelData),
+ firmware(firmware),
+ board(board),
+ boardType(boardType),
+ m_id(IMID_Unknown),
+ m_name(""),
+ m_updateMask(IMUE_None)
+ {}
+
+ virtual ~AbstractItemModel() {}
+
+ void setId(int id) { m_id = id; }
+ int getId () const { return m_id; }
+ bool isReservedModelId() const { return m_id > IMID_Unknown && m_id < IMID_ReservedCount; }
+ void setName(QString name) { m_name = name; }
+ QString getName() const { return isReservedModelId() ? idToString(m_id) : m_name; }
+ void setUpdateMask(const int mask) { m_updateMask = mask; }
+ int getUpdateMask() const { return m_updateMask; }
+
+ inline bool doUpdate(const int event) const { return m_updateMask & event; }
+
+ AbstractItemModel * getItemModel(const int id) const;
+
+ static void dumpItemModelContents(AbstractItemModel * itemModel);
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) = 0;
+
+ protected:
+ const GeneralSettings * generalSettings;
+ const ModelData * modelData;
+ Firmware * firmware;
+ const Boards * board;
+ const Board::Type boardType;
+
+ private:
+ int m_id = IMID_Unknown;
+ QString m_name = "";
+ int m_updateMask = IMUE_None;
+
+ static QString idToString(const int value);
+};
+
+class AbstractStaticItemModel: public AbstractItemModel
+{
+ Q_OBJECT
+ public:
+ explicit AbstractStaticItemModel(const GeneralSettings * const generalSettings = nullptr, const ModelData * const modelData = nullptr,
+ Firmware * firmware = nullptr, const Boards * const board = nullptr,
+ const Board::Type boardType = Board::BOARD_UNKNOWN) :
+ AbstractItemModel(generalSettings, modelData, firmware, board, boardType) {}
+ virtual ~AbstractStaticItemModel() {};
+
+ inline void appendToItemList(QString text, int id, bool isAvailable = true, int type = 0, int flags = 0)
+ { itemList.append(new ListItem(text, id, isAvailable, type, flags)); }
+
+ void loadItemList();
+
+ public slots:
+ virtual void update(const int event) override final {}
+
+ protected:
+ struct ListItem
+ {
+ QString text;
+ int id;
+ bool isAvailable;
+ int type;
+ int flags;
+
+ ListItem() {}
+ ListItem(QString p_text, int p_id, bool p_isAvailable, int p_type, int p_flags) :
+ text(p_text), id(p_id), isAvailable(p_isAvailable), type(p_type), flags(p_flags) {}
+ };
+
+ QVector itemList;
+};
+
+class AbstractDynamicItemModel: public AbstractItemModel
+{
+ Q_OBJECT
+ public:
+ explicit AbstractDynamicItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType) :
+ AbstractItemModel(generalSettings, modelData, firmware, board, boardType) {}
+ virtual ~AbstractDynamicItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) {}
+
+ signals:
+ void aboutToBeUpdated();
+ void updateComplete();
+};
+
+class RawSourceItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~RawSourceItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ 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);
+};
+
+class RawSwitchItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~RawSwitchItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ protected:
+ virtual void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
+ void addItems(const RawSwitchType & type, int count);
+};
+
+class CurveItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~CurveItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ protected:
+ virtual void setDynamicItemData(QStandardItem * item, const int value) const;
+};
+
+class GVarReferenceItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit GVarReferenceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~GVarReferenceItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ protected:
+ virtual void setDynamicItemData(QStandardItem * item, const AdjustmentReference & ar) const;
+ void addItems(int count);
+};
+
+class ThrottleSourceItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit ThrottleSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~ThrottleSourceItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ protected:
+ virtual void setDynamicItemData(QStandardItem * item, const int value) const;
+};
+
+class CustomFuncActionItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit CustomFuncActionItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~CustomFuncActionItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ protected:
+ virtual void setDynamicItemData(QStandardItem * item, const int value) const;
+};
+
+class CustomFuncResetParamItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit CustomFuncResetParamItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~CustomFuncResetParamItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ protected:
+ virtual void setDynamicItemData(QStandardItem * item, const int value) const;
+};
+
+class TelemetrySourceItemModel: public AbstractDynamicItemModel
+{
+ Q_OBJECT
+ public:
+ explicit TelemetrySourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~TelemetrySourceItemModel() {};
+
+ public slots:
+ virtual void update(const int event = IMUE_SystemRefresh) override;
+
+ protected:
+ virtual void setDynamicItemData(QStandardItem * item, const int value) const;
+};
+
+class CurveRefTypeItemModel : public AbstractStaticItemModel
+{
+ Q_OBJECT
+ public:
+ explicit CurveRefTypeItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~CurveRefTypeItemModel() {};
+};
+
+class CurveRefFuncItemModel : public AbstractStaticItemModel
+{
+ Q_OBJECT
+ public:
+ explicit CurveRefFuncItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
+ Firmware * firmware, const Boards * const board, const Board::Type boardType);
+ virtual ~CurveRefFuncItemModel() {};
+};
+
+class PrecisionItemModel : public AbstractStaticItemModel
+{
+ Q_OBJECT
+ public:
+ explicit PrecisionItemModel(const int minDecimals, const int maxDecimals, const QString suffix = "", const bool placeholders = false);
+ virtual ~PrecisionItemModel() {};
+};
+
+//
+// CompoundItemModelFactory
+//
+
+class CompoundItemModelFactory
+{
+ public:
+ CompoundItemModelFactory(const GeneralSettings * const generalSettings, const ModelData * const modelData);
+ virtual ~CompoundItemModelFactory();
+
+ void addItemModel(const int id);
+ int registerItemModel(AbstractItemModel * itemModel);
+ void unregisterItemModels();
+ void unregisterItemModel(const int id);
+ bool isItemModelRegistered(const int id) const;
+ AbstractItemModel * getItemModel(const int id) const;
+ void update(const int event = AbstractItemModel::IMUE_SystemRefresh);
+ void dumpAllItemModelContents() const;
+
+ protected:
+ const GeneralSettings * generalSettings;
+ const ModelData * modelData;
+ Firmware * firmware;
+ Boards * board;
+ Board::Type boardType;
+ QVector registeredItemModels;
+
+ private:
+ void setSourceId(AbstractItemModel * itemModel);
+};
+
+#endif // COMPOUNDITEMMODELS_H
diff --git a/companion/src/datamodels/filtereditemmodels.cpp b/companion/src/datamodels/filtereditemmodels.cpp
new file mode 100644
index 000000000..4f4e27262
--- /dev/null
+++ b/companion/src/datamodels/filtereditemmodels.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) OpenTX
+ *
+ * Based on code named
+ * th9x - http://code.google.com/p/th9x
+ * er9x - http://code.google.com/p/er9x
+ * gruvin9x - http://code.google.com/p/gruvin9x
+ *
+ * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "filtereditemmodels.h"
+
+FilteredItemModel::FilteredItemModel(AbstractItemModel * sourceModel, int flags) :
+ QSortFilterProxyModel(nullptr),
+ filterFlags(0),
+ m_id(0),
+ m_name("")
+{
+ setFilterRole(AbstractItemModel::IMDR_Available);
+ setFilterKeyColumn(0);
+ setFilterFlags(flags);
+ setDynamicSortFilter(true);
+ setSourceModel(sourceModel);
+
+ AbstractDynamicItemModel * itemModel = qobject_cast(sourceModel);
+ if (itemModel) {
+ connect(itemModel, &AbstractDynamicItemModel::aboutToBeUpdated, this, &FilteredItemModel::onAboutToBeUpdated);
+ connect(itemModel, &AbstractDynamicItemModel::updateComplete, this, &FilteredItemModel::onUpdateComplete);
+ }
+}
+
+void FilteredItemModel::setFilterFlags(int flags)
+{
+ if (filterFlags != flags) {
+ filterFlags = flags;
+ invalidateFilter();
+ }
+}
+
+bool FilteredItemModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
+{
+ const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
+ if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
+ return false;
+
+ if (!filterFlags)
+ return true;
+
+ bool ok;
+ const int flags = sourceModel()->data(srcIdx, AbstractItemModel::IMDR_Flags).toInt(&ok);
+ return (ok && (!flags || (filterFlags & flags)));
+}
+
+void FilteredItemModel::update() const
+{
+ AbstractDynamicItemModel * itemModel = qobject_cast(sourceModel());
+ if (itemModel)
+ itemModel->update();
+}
+
+void FilteredItemModel::onAboutToBeUpdated()
+{
+ emit aboutToBeUpdated();
+}
+
+void FilteredItemModel::onUpdateComplete()
+{
+ emit updateComplete();
+}
+
+// static
+void FilteredItemModel::dumpItemModelContents(FilteredItemModel * itemModel)
+{
+ if (itemModel) {
+ qDebug() << "id:" << itemModel->getId() << "name:" << itemModel->getName();
+
+ for (int i = 0; i < itemModel->rowCount(); ++i) {
+ qDebug() << "row:" << i
+ << "text:" << itemModel->data(itemModel->index(i, 0), Qt::DisplayRole).toString()
+ << "id:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Id).toInt()
+ << "avail:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Available).toBool()
+ << "flags:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Flags).toInt()
+ << "type:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Type).toInt();
+ }
+ }
+ else
+ qDebug() << "Error: model not of class FilteredItemModel";
+}
+
+//
+// FilteredItemModelFactory
+//
+
+FilteredItemModelFactory::FilteredItemModelFactory()
+{
+}
+
+FilteredItemModelFactory::~FilteredItemModelFactory()
+{
+ unregisterItemModels();
+}
+
+int FilteredItemModelFactory::registerItemModel(FilteredItemModel * itemModel, const QString name, const int id)
+{
+ if (itemModel) {
+ if (isItemModelRegistered(name)) {
+ qDebug() << "Error: item model already registered with name:" << name;
+ return 0;
+ }
+ else if (id > -1 && isItemModelRegistered(id)) {
+ qDebug() << "Error: item model already registered with id:" << id;
+ return 0;
+ }
+ else {
+ int fid = id;
+ if (fid < 0) {
+ fid = registeredItemModels.count() + 1;
+ AbstractItemModel * mdl = qobject_cast(itemModel->sourceModel());
+ if (mdl) {
+ fid += mdl->getId() * 128;
+ }
+ }
+ itemModel->setId(fid);
+ itemModel->setName(name);
+ registeredItemModels.append(itemModel);
+ return fid;
+ }
+ }
+
+ qDebug() << "Error: invalid filtered item model pointer";
+ return 0;
+}
+
+void FilteredItemModelFactory::unregisterItemModels()
+{
+ foreach (FilteredItemModel * itemModel, registeredItemModels) {
+ delete itemModel;
+ }
+}
+
+void FilteredItemModelFactory::unregisterItemModel(const int id)
+{
+ FilteredItemModel * itemModel = getItemModel(id);
+ if (itemModel)
+ delete itemModel;
+}
+
+bool FilteredItemModelFactory::isItemModelRegistered(const int id) const
+{
+ return getItemModel(id);
+}
+
+bool FilteredItemModelFactory::isItemModelRegistered(const QString name) const
+{
+ return getItemModel(name);
+}
+
+FilteredItemModel * FilteredItemModelFactory::getItemModel(const int id) const
+{
+ foreach (FilteredItemModel * itemModel, registeredItemModels) {
+ if (itemModel->getId() == id)
+ return itemModel;
+ }
+
+ return nullptr;
+}
+
+FilteredItemModel * FilteredItemModelFactory::getItemModel(const QString name) const
+{
+ foreach (FilteredItemModel * itemModel, registeredItemModels) {
+ if (itemModel->getName() == name)
+ return itemModel;
+ }
+
+ return nullptr;
+}
+
+void FilteredItemModelFactory::update()
+{
+ foreach (FilteredItemModel * itemModel, registeredItemModels) {
+ itemModel->update();
+ }
+}
+
+void FilteredItemModelFactory::dumpItemModelContents(const int id) const
+{
+ FilteredItemModel::dumpItemModelContents(getItemModel(id));
+}
+
+void FilteredItemModelFactory::dumpItemModelContents(const QString name) const
+{
+ FilteredItemModel::dumpItemModelContents(getItemModel(name));
+}
+
+void FilteredItemModelFactory::dumpAllItemModelContents() const
+{
+ foreach (FilteredItemModel * itemModel, registeredItemModels) {
+ FilteredItemModel::dumpItemModelContents(itemModel);
+ }
+}
+
+//
+// CurveRefFilteredFactory
+//
+
+CurveRefFilteredFactory::CurveRefFilteredFactory(CompoundItemModelFactory * sharedItemModels, const int curveFlags, const int gvarRefFlags)
+{
+ if (!sharedItemModels) {
+ qDebug() << "Error: invalid compound item model factory pointer";
+ return;
+ }
+
+ registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve), curveFlags),
+ fidToString(CRFIM_CURVE), CRFIM_CURVE);
+ registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef), gvarRefFlags),
+ fidToString(CRFIM_GVARREF), CRFIM_GVARREF);
+ registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CurveRefType)),
+ fidToString(CRFIM_TYPE), CRFIM_TYPE);
+ registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CurveRefFunc)),
+ fidToString(CRFIM_FUNC), CRFIM_FUNC);
+}
+
+CurveRefFilteredFactory::~CurveRefFilteredFactory()
+{
+}
+
+// static
+QString CurveRefFilteredFactory::fidToString(const int value)
+{
+ switch(value) {
+ case CRFIM_CURVE:
+ return "Curves";
+ case CRFIM_GVARREF:
+ return "Global Variables";
+ case CRFIM_TYPE:
+ return "Types";
+ case CRFIM_FUNC:
+ return "Functions";
+ default:
+ return CPN_STR_UNKNOWN_ITEM;
+ }
+}
diff --git a/companion/src/datamodels/filtereditemmodels.h b/companion/src/datamodels/filtereditemmodels.h
new file mode 100644
index 000000000..24668704d
--- /dev/null
+++ b/companion/src/datamodels/filtereditemmodels.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) OpenTX
+ *
+ * Based on code named
+ * th9x - http://code.google.com/p/th9x
+ * er9x - http://code.google.com/p/er9x
+ * gruvin9x - http://code.google.com/p/gruvin9x
+ *
+ * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FILTEREDITEMMODELS_H
+#define FILTEREDITEMMODELS_H
+
+#include "compounditemmodels.h"
+
+#include
+#include
+#include
+
+class FilteredItemModel: public QSortFilterProxyModel
+{
+ Q_OBJECT
+ public:
+ enum DataFilters {
+ AllFilter = AbstractItemModel::IMDG_Negative | AbstractItemModel::IMDG_None | AbstractItemModel::IMDG_Positive,
+ AllExcludeNoneFilter = AllFilter &~ AbstractItemModel::IMDG_None,
+ NegativeFilter = AbstractItemModel::IMDG_Negative | AbstractItemModel::IMDG_None,
+ NegativeExcludeNoneFilter = AbstractItemModel::IMDG_Negative,
+ PositiveFilter = AbstractItemModel::IMDG_Positive | AbstractItemModel::IMDG_None,
+ PositiveExcludeNoneFilter = AbstractItemModel::IMDG_Positive
+ };
+ Q_ENUM(DataFilters)
+
+ explicit FilteredItemModel(AbstractItemModel * sourceModel, int flags);
+ explicit FilteredItemModel(AbstractItemModel * sourceModel) :
+ FilteredItemModel(sourceModel, 0) {}
+ virtual ~FilteredItemModel() {};
+
+ void setId(int id) { m_id = id; }
+ int getId() const { return m_id; };
+ void setName(QString name) { m_name = name; }
+ QString getName() const { return m_name; }
+
+ static void dumpItemModelContents(FilteredItemModel * itemModel);
+
+ public slots:
+ void setFilterFlags(int flags);
+ void update() const;
+ void onAboutToBeUpdated();
+ void onUpdateComplete();
+
+ signals:
+ void aboutToBeUpdated();
+ void updateComplete();
+
+ protected:
+ bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
+
+ int filterFlags;
+
+ private:
+ int m_id = 0;
+ QString m_name = "";
+};
+
+class FilteredItemModelFactory
+{
+ public:
+ explicit FilteredItemModelFactory();
+ virtual ~FilteredItemModelFactory();
+
+ int registerItemModel(FilteredItemModel * itemModel, const QString name, const int id = -1);
+ void unregisterItemModels();
+ void unregisterItemModel(const int id);
+ bool isItemModelRegistered(const int id) const;
+ bool isItemModelRegistered(const QString name) const;
+ FilteredItemModel * getItemModel(const int id) const;
+ FilteredItemModel * getItemModel(const QString name) const;
+ void update();
+
+ void dumpItemModelContents(const int id) const;
+ void dumpItemModelContents(const QString name) const;
+ void dumpAllItemModelContents() const;
+
+ protected:
+ QVector registeredItemModels;
+};
+
+class CurveRefFilteredFactory : public FilteredItemModelFactory
+{
+ public:
+ enum FilteredItemModelId {
+ CRFIM_CURVE,
+ CRFIM_GVARREF,
+ CRFIM_TYPE,
+ CRFIM_FUNC
+ };
+
+ explicit CurveRefFilteredFactory(CompoundItemModelFactory * sharedItemModels, const int curveFlags = 0, const int gvarRefFlags = 0);
+ virtual ~CurveRefFilteredFactory();
+
+ static QString fidToString(const int value);
+};
+
+#endif // FILTEREDITEMMODELS_H
diff --git a/companion/src/datamodels/rawitemdatamodels.cpp b/companion/src/datamodels/rawitemdatamodels.cpp
deleted file mode 100644
index d7c1b6682..000000000
--- a/companion/src/datamodels/rawitemdatamodels.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) OpenTX
- *
- * Based on code named
- * th9x - http://code.google.com/p/th9x
- * er9x - http://code.google.com/p/er9x
- * gruvin9x - http://code.google.com/p/gruvin9x
- *
- * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include "rawitemdatamodels.h"
-#include "generalsettings.h"
-#include "eeprominterface.h"
-#include "modeldata.h"
-
-RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
- AbstractRawItemDataModel(generalSettings, modelData, parent)
-{
- const Boards board = Boards(getCurrentBoard());
- Firmware * fw = getCurrentFirmware();
-
- addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
- for (int i = 0; i < fw->getCapability(LuaScripts); i++)
- addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16);
- addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs));
- addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board.getCapability(Board::MaxAnalogs));
- addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, fw->getCapability(RotaryEncoders));
- addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board.getCapability(Board::NumTrims));
- addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
- addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board.getCapability(Board::Switches));
- addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, fw->getCapability(LogicalSwitches));
- addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
- addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs));
- addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs));
- addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
- addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, fw->getCapability(Sensors) * 3);
- addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars));
-}
-
-void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
-{
- Board::Type board = getCurrentBoard();
- item->setText(src.toString(modelData, generalSettings, board));
- item->setData(src.isAvailable(modelData, generalSettings, board), IsAvailableRole);
-}
-
-void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
-{
- for (int i = start; i < start + count; i++) {
- const RawSource src = RawSource(type, i);
- QStandardItem * modelItem = new QStandardItem();
- modelItem->setData(src.toValue(), ItemIdRole);
- modelItem->setData(type, ItemTypeRole);
- modelItem->setData(group, ItemFlagsRole);
- setDynamicItemData(modelItem, src);
- appendRow(modelItem);
- }
-}
-
-void RawSourceItemModel::update()
-{
- emit dataAboutToBeUpdated();
-
- for (int i = 0; i < rowCount(); ++i)
- setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt()));
-
- emit dataUpdateComplete();
-}
-
-
-//
-// RawSwitchItemModel
-//
-
-RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
- AbstractRawItemDataModel(generalSettings, modelData, parent)
-{
- Boards board = Boards(getCurrentBoard());
- Firmware * fw = getCurrentFirmware();
-
- // Descending switch direction: NOT (!) switches
- addItems(SWITCH_TYPE_ACT, -1);
- addItems(SWITCH_TYPE_SENSOR, -fw->getCapability(Sensors));
- addItems(SWITCH_TYPE_TELEMETRY, -1);
- addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes));
- addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches));
- addItems(SWITCH_TYPE_ROTARY_ENCODER, -fw->getCapability(RotaryEncoders));
- addItems(SWITCH_TYPE_TRIM, -board.getCapability(Board::NumTrimSwitches));
- addItems(SWITCH_TYPE_MULTIPOS_POT, -(board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions)));
- addItems(SWITCH_TYPE_SWITCH, -board.getCapability(Board::SwitchPositions));
-
- // Ascending switch direction (including zero)
- addItems(SWITCH_TYPE_TIMER_MODE, 5);
- addItems(SWITCH_TYPE_NONE, 1);
- addItems(SWITCH_TYPE_SWITCH, board.getCapability(Board::SwitchPositions));
- addItems(SWITCH_TYPE_MULTIPOS_POT, board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions));
- addItems(SWITCH_TYPE_TRIM, board.getCapability(Board::NumTrimSwitches));
- addItems(SWITCH_TYPE_ROTARY_ENCODER, fw->getCapability(RotaryEncoders));
- addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches));
- addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes));
- addItems(SWITCH_TYPE_TELEMETRY, 1);
- addItems(SWITCH_TYPE_SENSOR, fw->getCapability(Sensors));
- addItems(SWITCH_TYPE_ON, 1);
- addItems(SWITCH_TYPE_ONE, 1);
- addItems(SWITCH_TYPE_ACT, 1);
-}
-
-void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
-{
- const Board::Type board = getCurrentBoard();
- item->setText(rsw.toString(board, generalSettings, modelData));
- item->setData(rsw.isAvailable(modelData, generalSettings, board), IsAvailableRole);
-}
-
-void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
-{
- // Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
- const static QVector rawSwitchIndexBaseZeroTypes = QVector() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
- // handle exceptions in RawSwitch() index values
- const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
-
- // determine cotext flags
- int context = RawSwitch::AllSwitchContexts;
- switch (type) {
- case SWITCH_TYPE_FLIGHT_MODE:
- context &= ~RawSwitch::MixesContext;
- // fallthrough
- case SWITCH_TYPE_VIRTUAL:
- case SWITCH_TYPE_SENSOR:
- context &= ~RawSwitch::GlobalFunctionsContext;
- break;
-
- case SWITCH_TYPE_TIMER_MODE:
- context = RawSwitch::TimersContext;
- break;
-
- case SWITCH_TYPE_NONE:
- context &= ~RawSwitch::TimersContext;
- break;
-
- case SWITCH_TYPE_ON:
- case SWITCH_TYPE_ONE:
- context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
- break;
-
- default:
- break;
- }
-
- int i = (count < 0 ? count : 1);
- count = (i < 0 ? 0 : count + i);
- for ( ; i < count; ++i) {
- RawSwitch rs(type, i + rawIdxAdj);
- QStandardItem * modelItem = new QStandardItem();
- modelItem->setData(rs.toValue(), ItemIdRole);
- modelItem->setData(type, ItemTypeRole);
- modelItem->setData(context, ItemFlagsRole);
- setDynamicItemData(modelItem, rs);
- appendRow(modelItem);
- }
-}
-
-void RawSwitchItemModel::update()
-{
- emit dataAboutToBeUpdated();
-
- for (int i = 0; i < rowCount(); ++i)
- setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt()));
-
- emit dataUpdateComplete();
-}
-
-//
-// CurveItemModel
-//
-
-CurveItemModel::CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
- AbstractRawItemDataModel(generalSettings, modelData, parent)
-{
- const int count = getCurrentFirmware()->getCapability(NumCurves);
-
- for (int i = -count ; i <= count; ++i) {
- QStandardItem * modelItem = new QStandardItem();
- modelItem->setData(i, ItemIdRole);
- int flags;
- if (i < 0)
- flags = DataGroups::NegativeGroup;
- else if (i > 0)
- flags = DataGroups::PositiveGroup;
- else
- flags = DataGroups::NoneGroup;
- modelItem->setData(flags, ItemFlagsRole);
- setDynamicItemData(modelItem, i);
- appendRow(modelItem);
- }
-}
-
-void CurveItemModel::setDynamicItemData(QStandardItem * item, int index) const
-{
- item->setText(CurveReference(CurveReference::CURVE_REF_CUSTOM, index).toString(modelData, false));
- item->setData(true, IsAvailableRole);
-}
-
-void CurveItemModel::update()
-{
- emit dataAboutToBeUpdated();
-
- for (int i = 0; i < rowCount(); ++i)
- setDynamicItemData(item(i), item(i)->data(ItemIdRole).toInt());
-
- emit dataUpdateComplete();
-}
-
-//
-// CommonItemModels
-//
-
-CommonItemModels::CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
- QObject(parent)
-{
- m_rawSourceItemModel = new RawSourceItemModel(generalSettings, modelData, parent);
- m_rawSwitchItemModel = new RawSwitchItemModel(generalSettings, modelData, parent);
- m_curveItemModel = new CurveItemModel(generalSettings, modelData, parent);
-}
-
-CommonItemModels::~CommonItemModels()
-{
-}
-
-void CommonItemModels::update(const RadioModelObjects radioModelObjects)
-{
- switch (radioModelObjects) {
- case RMO_CHANNELS:
- case RMO_INPUTS:
- case RMO_TELEMETRY_SENSORS:
- case RMO_TIMERS:
- m_rawSourceItemModel->update();
- break;
- case RMO_FLIGHT_MODES:
- case RMO_GLOBAL_VARIABLES:
- case RMO_LOGICAL_SWITCHES:
- m_rawSourceItemModel->update();
- m_rawSwitchItemModel->update();
- break;
- case RMO_CURVES:
- m_curveItemModel->update();
- break;
- case RMO_SCRIPTS:
- // no need to refresh
- break;
- default:
- qDebug() << "Unknown RadioModelObject:" << radioModelObjects;
- }
-}
diff --git a/companion/src/datamodels/rawitemdatamodels.h b/companion/src/datamodels/rawitemdatamodels.h
deleted file mode 100644
index 48cb55fd2..000000000
--- a/companion/src/datamodels/rawitemdatamodels.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) OpenTX
- *
- * Based on code named
- * th9x - http://code.google.com/p/th9x
- * er9x - http://code.google.com/p/er9x
- * gruvin9x - http://code.google.com/p/gruvin9x
- *
- * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef RAWITEMDATAMODELS_H
-#define RAWITEMDATAMODELS_H
-
-#include "rawsource.h"
-#include "rawswitch.h"
-
-#include
-
-class GeneralSettings;
-class ModelData;
-
-class AbstractRawItemDataModel: public QStandardItemModel
-{
- Q_OBJECT
- public:
- enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole };
- Q_ENUM(DataRoles)
-
- enum DataGroups {
- NoneGroup = 0x01,
- NegativeGroup = 0x02,
- PositiveGroup = 0x04
- };
- Q_ENUM(DataGroups)
-
- explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
- QStandardItemModel(parent),
- generalSettings(generalSettings),
- modelData(modelData)
- {}
-
- public slots:
- virtual void update() = 0;
-
- signals:
- void dataAboutToBeUpdated();
- void dataUpdateComplete();
-
- protected:
- const GeneralSettings * generalSettings;
- const ModelData * modelData;
-};
-
-
-class RawSourceItemModel: public AbstractRawItemDataModel
-{
- Q_OBJECT
- public:
- explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
-
- public slots:
- void update() override;
-
- protected:
- void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
- void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
-};
-
-
-class RawSwitchItemModel: public AbstractRawItemDataModel
-{
- Q_OBJECT
- public:
- explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
-
- public slots:
- void update() override;
-
- protected:
- void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
- void addItems(const RawSwitchType & type, int count);
-};
-
-
-class CurveItemModel: public AbstractRawItemDataModel
-{
- Q_OBJECT
- public:
- explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
-
- public slots:
- void update() override;
-
- protected:
- void setDynamicItemData(QStandardItem * item, int index) const;
-};
-
-
-class CommonItemModels: public QObject
-{
- Q_OBJECT
- public:
- enum RadioModelObjects {
- RMO_CHANNELS,
- RMO_CURVES,
- RMO_FLIGHT_MODES,
- RMO_GLOBAL_VARIABLES,
- RMO_INPUTS,
- RMO_LOGICAL_SWITCHES,
- RMO_SCRIPTS,
- RMO_TELEMETRY_SENSORS,
- RMO_TIMERS
- };
- Q_ENUM(RadioModelObjects)
-
- explicit CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
- ~CommonItemModels();
-
- void update(const RadioModelObjects radioModelObjects);
- RawSourceItemModel * rawSourceItemModel() const { return m_rawSourceItemModel; }
- RawSwitchItemModel * rawSwitchItemModel() const { return m_rawSwitchItemModel; }
- CurveItemModel * curveItemModel() const { return m_curveItemModel; }
-
- private:
- RawSourceItemModel *m_rawSourceItemModel;
- RawSwitchItemModel *m_rawSwitchItemModel;
- CurveItemModel *m_curveItemModel;
-};
-
-#endif // RAWITEMDATAMODELS_H
diff --git a/companion/src/datamodels/rawitemfilteredmodel.cpp b/companion/src/datamodels/rawitemfilteredmodel.cpp
deleted file mode 100644
index abe9ca08e..000000000
--- a/companion/src/datamodels/rawitemfilteredmodel.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) OpenTX
- *
- * Based on code named
- * th9x - http://code.google.com/p/th9x
- * er9x - http://code.google.com/p/er9x
- * gruvin9x - http://code.google.com/p/gruvin9x
- *
- * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include "rawitemfilteredmodel.h"
-
-RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) :
- QSortFilterProxyModel(parent),
- filterFlags(0)
-{
- setFilterRole(AbstractRawItemDataModel::IsAvailableRole);
- setFilterKeyColumn(0);
- setFilterFlags(flags);
- setDynamicSortFilter(true);
- setSourceModel(sourceModel);
-
- AbstractRawItemDataModel * itemModel = qobject_cast(sourceModel);
- if (itemModel) {
- connect(itemModel, &AbstractRawItemDataModel::dataAboutToBeUpdated, this, &RawItemFilteredModel::onDataAboutToBeUpdated);
- connect(itemModel, &AbstractRawItemDataModel::dataUpdateComplete, this, &RawItemFilteredModel::onDataUpdateComplete);
- }
-}
-
-void RawItemFilteredModel::setFilterFlags(int flags)
-{
- if (filterFlags != flags) {
- filterFlags = flags;
- invalidateFilter();
- }
-}
-
-bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
-{
- const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
- if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
- return false;
-
- if (!filterFlags)
- return true;
-
- bool ok;
- const int flags = sourceModel()->data(srcIdx, AbstractRawItemDataModel::ItemFlagsRole).toInt(&ok);
- return (ok && (!flags || (filterFlags & flags)));
-}
-
-void RawItemFilteredModel::update() const
-{
- AbstractRawItemDataModel * itemModel = qobject_cast(sourceModel());
- if (itemModel)
- itemModel->update();
-}
-
-void RawItemFilteredModel::onDataAboutToBeUpdated()
-{
- emit dataAboutToBeUpdated();
-}
-
-void RawItemFilteredModel::onDataUpdateComplete()
-{
- emit dataUpdateComplete();
-}
diff --git a/companion/src/datamodels/rawitemfilteredmodel.h b/companion/src/datamodels/rawitemfilteredmodel.h
deleted file mode 100644
index 3274460f7..000000000
--- a/companion/src/datamodels/rawitemfilteredmodel.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) OpenTX
- *
- * Based on code named
- * th9x - http://code.google.com/p/th9x
- * er9x - http://code.google.com/p/er9x
- * gruvin9x - http://code.google.com/p/gruvin9x
- *
- * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef RAWITEMFILTEREDMODEL_H
-#define RAWITEMFILTEREDMODEL_H
-
-#include "rawitemdatamodels.h"
-
-#include
-
-class GeneralSettings;
-class ModelData;
-
-class RawItemFilteredModel: public QSortFilterProxyModel
-{
- Q_OBJECT
- public:
- enum DataFilters {
- AllFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup | AbstractRawItemDataModel::PositiveGroup,
- AllExcludeNoneFilter = AllFilter &~ AbstractRawItemDataModel::NoneGroup,
- NegativeFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup,
- NegativeExcludeNoneFilter = AbstractRawItemDataModel::NegativeGroup,
- PositiveFilter = AbstractRawItemDataModel::PositiveGroup | AbstractRawItemDataModel::NoneGroup,
- PositiveExcludeNoneFilter = AbstractRawItemDataModel::PositiveGroup
- };
- Q_ENUM(DataFilters)
-
- explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr);
- explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {}
-
- public slots:
- void setFilterFlags(int flags);
- void update() const;
- void onDataAboutToBeUpdated();
- void onDataUpdateComplete();
-
- signals:
- void dataAboutToBeUpdated();
- void dataUpdateComplete();
-
- protected:
- bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
-
- int filterFlags;
-};
-#endif // RAWITEMFILTEREDMODEL_H
diff --git a/companion/src/firmwares/adjustmentreference.cpp b/companion/src/firmwares/adjustmentreference.cpp
index 7181e15dd..ae487effa 100644
--- a/companion/src/firmwares/adjustmentreference.cpp
+++ b/companion/src/firmwares/adjustmentreference.cpp
@@ -19,7 +19,7 @@
*/
#include "adjustmentreference.h"
-#include "radiodata.h" // for ModelData
+#include "modeldata.h"
AdjustmentReference::AdjustmentReference(int value)
{
@@ -76,3 +76,8 @@ QString AdjustmentReference::toString(const ModelData * model, const bool sign)
}
return ret;
}
+
+const bool AdjustmentReference::isAvailable() const
+{
+ return true;
+}
diff --git a/companion/src/firmwares/adjustmentreference.h b/companion/src/firmwares/adjustmentreference.h
index 2a7b7e141..9377cd5e8 100644
--- a/companion/src/firmwares/adjustmentreference.h
+++ b/companion/src/firmwares/adjustmentreference.h
@@ -45,6 +45,7 @@ class AdjustmentReference {
bool isSet() const { return type != ADJUST_REF_VALUE || value != 0; }
bool isValid(const int value) const;
QString toString(const ModelData * model = nullptr, const bool sign = false) const;
+ const bool isAvailable() const;
inline const int toValue() const
{
diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp
index 82e645d05..d6c010814 100644
--- a/companion/src/firmwares/boards.cpp
+++ b/companion/src/firmwares/boards.cpp
@@ -87,6 +87,8 @@ uint32_t Boards::getFourCC(Type board)
return 0x3878746F;
case BOARD_RADIOMASTER_TX12:
return 0x4178746F;
+ case BOARD_RADIOMASTER_T8:
+ return 0x4378746F;
case BOARD_UNKNOWN:
break;
}
@@ -114,6 +116,7 @@ int Boards::getEEpromSize(Board::Type board)
case BOARD_TARANIS_X9E:
case BOARD_JUMPER_T12:
case BOARD_RADIOMASTER_TX12:
+ case BOARD_RADIOMASTER_T8:
return EESIZE_TARANIS;
case BOARD_UNKNOWN:
return EESIZE_MAX;
@@ -149,6 +152,7 @@ int Boards::getFlashSize(Type board)
case BOARD_TARANIS_X9E:
case BOARD_JUMPER_T12:
case BOARD_RADIOMASTER_TX12:
+ case BOARD_RADIOMASTER_T8:
return FSIZE_TARANIS;
case BOARD_HORUS_X12S:
case BOARD_X10:
@@ -232,6 +236,16 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
if (index < DIM(switches))
return switches[index];
}
+ else if (IS_RADIOMASTER_T8(board)) {
+ const Board::SwitchInfo switches[] = {
+ {SWITCH_TOGGLE, "SA"},
+ {SWITCH_3POS, "SB"},
+ {SWITCH_3POS, "SC"},
+ {SWITCH_TOGGLE, "SD"}
+ };
+ if (index < DIM(switches))
+ return switches[index];
+ }
else if (IS_JUMPER_T12(board)) {
const Board::SwitchInfo switches[] = {
{SWITCH_3POS, "SA"},
@@ -568,6 +582,8 @@ QString Boards::getBoardName(Board::Type board)
return "Radiomaster TX16S";
case BOARD_RADIOMASTER_TX12:
return "Radiomaster TX12";
+ case BOARD_RADIOMASTER_T8:
+ return "Radiomaster T8";
default:
return tr("Unknown");
}
diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h
index 1e1588485..fe00e77dd 100644
--- a/companion/src/firmwares/boards.h
+++ b/companion/src/firmwares/boards.h
@@ -53,9 +53,10 @@ namespace Board {
BOARD_RADIOMASTER_TX16S,
BOARD_JUMPER_T18,
BOARD_RADIOMASTER_TX12,
+ BOARD_RADIOMASTER_T8,
};
- constexpr int BOARD_TYPE_MAX = BOARD_RADIOMASTER_TX12;
+ constexpr int BOARD_TYPE_MAX = BOARD_RADIOMASTER_T8;
enum PotType
{
@@ -224,6 +225,11 @@ inline bool IS_RADIOMASTER_TX12(Board::Type board)
return board == Board::BOARD_RADIOMASTER_TX12;
}
+inline bool IS_RADIOMASTER_T8(Board::Type board)
+{
+ return board == Board::BOARD_RADIOMASTER_T8;
+}
+
inline bool IS_FAMILY_T16(Board::Type board)
{
return board == Board::BOARD_JUMPER_T16 || board == Board::BOARD_RADIOMASTER_TX16S || board == Board::BOARD_JUMPER_T18;
@@ -231,7 +237,7 @@ inline bool IS_FAMILY_T16(Board::Type board)
inline bool IS_FAMILY_T12(Board::Type board)
{
- return board == Board::BOARD_JUMPER_T12 || board == Board::BOARD_RADIOMASTER_TX12;
+ return board == Board::BOARD_JUMPER_T12 || board == Board::BOARD_RADIOMASTER_TX12 || board == Board::BOARD_RADIOMASTER_T8;
}
inline bool IS_TARANIS_XLITE(Board::Type board)
diff --git a/companion/src/firmwares/curvereference.cpp b/companion/src/firmwares/curvereference.cpp
index 449dc0266..926c2d2ae 100644
--- a/companion/src/firmwares/curvereference.cpp
+++ b/companion/src/firmwares/curvereference.cpp
@@ -22,7 +22,7 @@
#include "adjustmentreference.h"
#include "helpers.h"
#include "modeldata.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
const QString CurveReference::toString(const ModelData * model, bool verbose) const
{
@@ -63,6 +63,11 @@ const bool CurveReference::isValueNumber() const
return (type == CURVE_REF_DIFF || type == CURVE_REF_EXPO) && AdjustmentReference(value).type == AdjustmentReference::ADJUST_REF_VALUE;
}
+const bool CurveReference::isAvailable() const
+{
+ return true;
+}
+
// static
int CurveReference::getDefaultValue(const CurveRefType type, const bool isGVar)
{
@@ -77,7 +82,7 @@ int CurveReference::getDefaultValue(const CurveRefType type, const bool isGVar)
// static
QString CurveReference::typeToString(const CurveRefType type)
{
- const QStringList strl = { "Diff", "Expo" , "Func", "Curve" };
+ const QStringList strl = { tr("Diff"), tr("Expo") , tr("Func"), tr("Curve") };
int idx = (int)type;
if (idx < 0 || idx >= strl.count())
@@ -86,8 +91,6 @@ QString CurveReference::typeToString(const CurveRefType type)
return strl.at(idx);
}
-constexpr int MAX_CURVE_REF_FUNC { 6 };
-
// static
QString CurveReference::functionToString(const int value)
{
@@ -100,76 +103,65 @@ QString CurveReference::functionToString(const int value)
return strl.at(idx);
}
+// static
+bool CurveReference::isTypeAvailable(const CurveRefType type)
+{
+ bool ret = false;
+ Firmware * fw = getCurrentFirmware();
+
+ switch(type) {
+ case CURVE_REF_DIFF:
+ if (fw->getCapability(HasInputDiff))
+ ret = true;
+ break;
+ case CURVE_REF_EXPO:
+ if (fw->getCapability(HasMixerExpo))
+ ret = true;
+ break;
+ case CURVE_REF_FUNC:
+ case CURVE_REF_CUSTOM:
+ ret = true;
+ break;
+ }
+
+ return ret;
+}
+
+// static
+bool CurveReference::isFunctionAvailable(const int value)
+{
+ return true;
+}
+
+// static
+int CurveReference::functionCount()
+{
+ return 6;
+}
+
+
/*
* CurveReferenceUIManager
*/
-constexpr int CURVE_REF_UI_HIDE_DIFF { 0x01 };
-constexpr int CURVE_REF_UI_HIDE_EXPO { 0x02 };
-constexpr int CURVE_REF_UI_HIDE_NEGATIVE_CURVES { 0x04 };
-
-// static
-bool CurveReferenceUIManager::firsttime { true };
-int CurveReferenceUIManager::flags { 0 };
-bool CurveReferenceUIManager::hasCapabilityGvars { false };
-int CurveReferenceUIManager::numCurves { 0 };
-RawItemFilteredModel * CurveReferenceUIManager::curveItemModel { nullptr };
-QStandardItemModel * CurveReferenceUIManager::tempModel { nullptr };
-
-CurveReferenceUIManager::CurveReferenceUIManager(QComboBox * curveValueCB, CurveReference & curve, const ModelData & model,
- RawItemFilteredModel * curveItemModel, QObject * parent) :
- QObject(parent),
- curveTypeCB(nullptr),
- curveGVarCB(nullptr),
- curveValueSB(nullptr),
- curveValueCB(curveValueCB),
- curve(curve),
- model(model),
- lock(false)
-{
- init(curveItemModel);
-}
-
CurveReferenceUIManager::CurveReferenceUIManager(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QSpinBox * curveValueSB,
- QComboBox * curveValueCB, CurveReference & curve, const ModelData & model,
- RawItemFilteredModel * curveItemModel, QObject * parent) :
+ QComboBox * curveValueCB, CurveReference & curveRef, const ModelData & model,
+ CurveRefFilteredFactory * curveRefFilteredFactory, QObject * parent) :
QObject(parent),
curveTypeCB(curveTypeCB),
curveGVarCB(curveGVarCB),
curveValueSB(curveValueSB),
curveValueCB(curveValueCB),
- curve(curve),
+ curveRef(curveRef),
model(model),
- lock(false)
+ lock(false),
+ filteredModelFactory(curveRefFilteredFactory)
{
- init(curveItemModel);
-}
-
-CurveReferenceUIManager::~CurveReferenceUIManager()
-{
- delete tempModel;
-}
-
-void CurveReferenceUIManager::init(RawItemFilteredModel * curveModel)
-{
- tempModel = new QStandardItemModel();
-
- if (firsttime) {
- firsttime = false;
- Firmware * fw = getCurrentFirmware();
- hasCapabilityGvars = fw->getCapability(Gvars);
- numCurves = fw->getCapability(NumCurves);
- curveItemModel = curveModel;
-
- if (!fw->getCapability(HasInputDiff))
- flags |= (CURVE_REF_UI_HIDE_DIFF | CURVE_REF_UI_HIDE_NEGATIVE_CURVES);
-
- if (!fw->getCapability(HasMixerExpo))
- flags |= CURVE_REF_UI_HIDE_EXPO;
- }
+ hasCapabilityGvars = getCurrentFirmware()->getCapability(Gvars);
if (curveTypeCB) {
- populateTypeCB(curveTypeCB, curve);
+ curveTypeCB->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_TYPE));
+ curveTypeCB->setCurrentIndex(curveTypeCB->findData((int)curveRef.type));
connect(curveTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int)));
}
@@ -182,13 +174,20 @@ void CurveReferenceUIManager::init(RawItemFilteredModel * curveModel)
connect(curveValueSB, SIGNAL(editingFinished()), this, SLOT(valueSBChanged()));
}
- curveValueCB->setSizeAdjustPolicy(QComboBox::AdjustToContents);
- curveValueCB->setMaxVisibleItems(10);
- connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valueCBChanged()));
+ if (curveValueCB) {
+ curveValueCB->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+ curveValueCB->setMaxVisibleItems(10);
+ connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valueCBChanged()));
+ }
update();
}
+CurveReferenceUIManager::~CurveReferenceUIManager()
+{
+ delete filteredModelFactory;
+}
+
#define CURVE_REF_UI_GVAR_SHOW (1<<0)
#define CURVE_REF_UI_VALUE_SHOW (1<<1)
#define CURVE_REF_UI_REF_SHOW (1<<2)
@@ -198,12 +197,12 @@ void CurveReferenceUIManager::update()
lock = true;
int widgetsMask = 0;
- if (curve.type == CurveReference::CURVE_REF_DIFF || curve.type == CurveReference::CURVE_REF_EXPO) {
+ if (curveRef.type == CurveReference::CURVE_REF_DIFF || curveRef.type == CurveReference::CURVE_REF_EXPO) {
if (hasCapabilityGvars)
widgetsMask |= CURVE_REF_UI_GVAR_SHOW;
- if (curve.isValueNumber()) {
+ if (curveRef.isValueNumber()) {
curveGVarCB->setChecked(false);
- curveValueSB->setValue(curve.value);
+ curveValueSB->setValue(curveRef.value);
widgetsMask |= CURVE_REF_UI_VALUE_SHOW;
}
else {
@@ -216,7 +215,7 @@ void CurveReferenceUIManager::update()
}
if(curveTypeCB) {
- curveTypeCB->setCurrentIndex(curveTypeCB->findData(curve.type));
+ curveTypeCB->setCurrentIndex(curveTypeCB->findData(curveRef.type));
curveTypeCB->show();
}
if(curveGVarCB)
@@ -224,8 +223,8 @@ void CurveReferenceUIManager::update()
if(curveValueSB)
curveValueSB->setVisible(widgetsMask & CURVE_REF_UI_VALUE_SHOW);
if(curveValueCB) {
- if (curve.isValueReference())
- populateValueCB(curveValueCB, curve, &model);
+ if (curveRef.isValueReference())
+ populateValueCB(curveValueCB);
curveValueCB->setVisible(widgetsMask & CURVE_REF_UI_REF_SHOW);
}
@@ -235,7 +234,7 @@ void CurveReferenceUIManager::update()
void CurveReferenceUIManager::gvarCBChanged(int state)
{
if (!lock) {
- curve.value = CurveReference::getDefaultValue(curve.type, state);
+ curveRef.value = CurveReference::getDefaultValue(curveRef.type, state);
update();
}
}
@@ -244,7 +243,7 @@ void CurveReferenceUIManager::typeChanged(int value)
{
if (!lock) {
CurveReference::CurveRefType type = (CurveReference::CurveRefType)curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt();
- curve = CurveReference(type, CurveReference::getDefaultValue(type));
+ curveRef = CurveReference(type, CurveReference::getDefaultValue(type));
update();
}
}
@@ -252,7 +251,7 @@ void CurveReferenceUIManager::typeChanged(int value)
void CurveReferenceUIManager::valueSBChanged()
{
if (!lock) {
- curve.value = curveValueSB->value();
+ curveRef.value = curveValueSB->value();
update();
}
}
@@ -260,47 +259,24 @@ void CurveReferenceUIManager::valueSBChanged()
void CurveReferenceUIManager::valueCBChanged()
{
if (!lock) {
- curve.value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt();
+ curveRef.value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt();
update();
}
}
-// static
-void CurveReferenceUIManager::populateTypeCB(QComboBox * cb, const CurveReference & curveRef)
+void CurveReferenceUIManager::populateValueCB(QComboBox * cb)
{
if (cb) {
- cb->clear();
- for (int i = 0; i <= CurveReference::MAX_CURVE_REF_TYPE; i++) {
- if ((curveRef.type == CurveReference::CURVE_REF_DIFF && !(flags & CURVE_REF_UI_HIDE_DIFF)) ||
- (curveRef.type == CurveReference::CURVE_REF_EXPO && !(flags & CURVE_REF_UI_HIDE_EXPO)) ||
- (curveRef.type != CurveReference::CURVE_REF_DIFF && curveRef.type != CurveReference::CURVE_REF_EXPO))
- cb->addItem(CurveReference::typeToString((CurveReference::CurveRefType)i), i);
- }
-
- cb->setCurrentIndex(cb->findData((int)curveRef.type));
- }
-}
-
-// static
-void CurveReferenceUIManager::populateValueCB(QComboBox * cb, const CurveReference & curveRef, const ModelData * model)
-{
- if (cb) {
- cb->setModel(tempModel); // do not want to clear/alter the shared curves model and set to nullptr is invalid
-
switch (curveRef.type) {
case CurveReference::CURVE_REF_DIFF:
case CurveReference::CURVE_REF_EXPO:
- cb->clear();
- Helpers::populateGVCB(*cb, curveRef.value, *model);
+ cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_GVARREF));
break;
case CurveReference::CURVE_REF_FUNC:
- cb->clear();
- for (int i = 1; i <= MAX_CURVE_REF_FUNC; i++) {
- cb->addItem(CurveReference::functionToString(i), i);
- }
+ cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_FUNC));
break;
case CurveReference::CURVE_REF_CUSTOM:
- cb->setModel(curveItemModel);
+ cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_CURVE));
break;
default:
break;
diff --git a/companion/src/firmwares/curvereference.h b/companion/src/firmwares/curvereference.h
index 0a1c7a180..c4482c742 100644
--- a/companion/src/firmwares/curvereference.h
+++ b/companion/src/firmwares/curvereference.h
@@ -29,7 +29,7 @@
class ModelData;
-class RawItemFilteredModel;
+class CurveRefFilteredFactory;
class CurveReference {
@@ -63,6 +63,7 @@ class CurveReference {
const bool isValueNumber() const;
const bool isValueReference() const { return !isValueNumber(); }
const QString toString(const ModelData * model = nullptr, bool verbose = true) const;
+ const bool isAvailable() const;
CurveRefType type;
int value;
@@ -78,6 +79,9 @@ class CurveReference {
static int getDefaultValue(const CurveRefType type, const bool isGVar = false);
static QString typeToString(const CurveRefType type);
static QString functionToString(const int value);
+ static bool isTypeAvailable(const CurveRefType type);
+ static bool isFunctionAvailable(const int value);
+ static int functionCount();
};
class CurveReferenceUIManager : public QObject {
@@ -85,38 +89,34 @@ class CurveReferenceUIManager : public QObject {
Q_OBJECT
public:
- CurveReferenceUIManager(QComboBox *curveValueCB, CurveReference & curve, const ModelData & model,
- RawItemFilteredModel * curveItemModel, QObject * parent = nullptr);
- CurveReferenceUIManager(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QSpinBox *curveValueSB, QComboBox *curveValueCB,
- CurveReference & curve, const ModelData & model, RawItemFilteredModel * curveItemModel, QObject * parent = nullptr);
+ explicit CurveReferenceUIManager(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QSpinBox *curveValueSB, QComboBox *curveValueCB,
+ CurveReference & curve, const ModelData & model, CurveRefFilteredFactory * curveRefFilteredFactory,
+ QObject * parent = nullptr);
+
+ explicit CurveReferenceUIManager(QComboBox *curveValueCB, CurveReference & curve, const ModelData & model,
+ CurveRefFilteredFactory * curveRefFilteredFactory, QObject * parent = nullptr) :
+ CurveReferenceUIManager(nullptr, nullptr, nullptr, curveValueCB, curve, model, curveRefFilteredFactory, parent) {}
+
virtual ~CurveReferenceUIManager();
- void init(RawItemFilteredModel * curveModel);
- void update();
protected slots:
void gvarCBChanged(int);
void typeChanged(int);
void valueSBChanged();
void valueCBChanged();
+ void update();
- protected:
+ private:
QComboBox *curveTypeCB;
QCheckBox *curveGVarCB;
QSpinBox *curveValueSB;
QComboBox *curveValueCB;
- CurveReference & curve;
+ CurveReference & curveRef;
const ModelData & model;
bool lock;
-
- static bool firsttime;
- static int flags;
- static bool hasCapabilityGvars;
- static int numCurves;
- static RawItemFilteredModel * curveItemModel;
- static QStandardItemModel * tempModel;
-
- static void populateTypeCB(QComboBox * cb, const CurveReference & curveRef);
- static void populateValueCB(QComboBox * cb, const CurveReference & curveRef, const ModelData * model = nullptr);
+ bool hasCapabilityGvars;
+ CurveRefFilteredFactory *filteredModelFactory;
+ void populateValueCB(QComboBox * cb);
};
#endif // CURVEREFERENCE_H
diff --git a/companion/src/firmwares/customfunctiondata.cpp b/companion/src/firmwares/customfunctiondata.cpp
index d6918e27c..d4942c60c 100644
--- a/companion/src/firmwares/customfunctiondata.cpp
+++ b/companion/src/firmwares/customfunctiondata.cpp
@@ -38,12 +38,12 @@ bool CustomFunctionData::isEmpty() const
QString CustomFunctionData::nameToString(int index, bool globalContext) const
{
- return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index+1, 0, true);
+ return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index + 1, 0, true);
}
QString CustomFunctionData::funcToString(const ModelData * model) const
{
- if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
+ if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast)
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
else if (func == FuncTrainer)
return tr("Trainer Sticks");
@@ -65,8 +65,8 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
return tr("Haptic");
else if (func == FuncReset)
return tr("Reset");
- else if (func >= FuncSetTimer1 && func <= FuncSetTimer3)
- return tr("Set Timer %1").arg(func-FuncSetTimer1+1);
+ else if (func >= FuncSetTimer1 && func <= FuncSetTimerLast)
+ return tr("Set %1").arg(RawSource(SOURCE_TYPE_SPECIAL, SOURCE_TYPE_SPECIAL_TIMER1_IDX + func - FuncSetTimer1).toString(model));
else if (func == FuncVario)
return tr("Vario");
else if (func == FuncPlayPrompt)
@@ -90,7 +90,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
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).toString(model));
else if (func == FuncSetFailsafe)
return tr("Set Failsafe");
else if (func == FuncRangeCheckInternalModule)
@@ -102,7 +102,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
else if (func == FuncBindExternalModule)
return tr("Bind Ext. Module");
else {
- return QString("???"); // Highlight unknown functions with output of question marks.(BTW should not happen that we do not know what a function is)
+ return QString(CPN_STR_UNKNOWN_ITEM);
}
}
@@ -111,11 +111,16 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
int val = 0;
Firmware * firmware = Firmware::getCurrentVariant();
- b->addItem(tr("Timer1"), val++);
- b->addItem(tr("Timer2"), val++);
- b->addItem( tr("Timer3"), val++);
+ for (int i = 0; i < CPN_MAX_TIMERS; i++, val++) {
+ if (i < firmware->getCapability(Timers)) {
+ RawSource item = RawSource(SOURCE_TYPE_SPECIAL, i + SOURCE_TYPE_SPECIAL_TIMER1_IDX);
+ b->addItem(item.toString(model), val);
+ }
+ }
+
b->addItem(tr("Flight"), val++);
b->addItem(tr("Telemetry"), val++);
+
int reCount = firmware->getCapability(RotaryEncoders);
if (reCount == 1) {
b->addItem(tr("Rotary Encoder"), val++);
@@ -124,6 +129,7 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
b->addItem(tr("REa"), val++);
b->addItem(tr("REb"), val++);
}
+
if (model) {
for (int i = 0; i < firmware->getCapability(Sensors); ++i) {
if (model->sensorData[i].isAvailable()) {
@@ -132,6 +138,7 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
}
}
}
+
b->setCurrentIndex(b->findData(value));
}
@@ -153,18 +160,18 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
return QString("%1").arg(param);
}
else if (func == FuncLogs) {
- return QString("%1").arg(param/10.0) + tr("s");
+ return QString("%1").arg(param / 10.0) + tr("s");
}
else if (func == FuncPlaySound) {
CustomFunctionData::populatePlaySoundParams(qs);
- if (param>=0 && param<(int)qs.count())
+ if (param >= 0 && param < (int)qs.count())
return qs.at(param);
else
return tr("Inconsistent parameter");
}
else if (func == FuncPlayHaptic) {
CustomFunctionData::populateHapticParams(qs);
- if (param>=0 && param<(int)qs.count())
+ if (param >= 0 && param < (int)qs.count())
return qs.at(param);
else
return tr("Inconsistent parameter");
@@ -193,7 +200,7 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
else if (func >= FuncAdjustGV1 && func < FuncCount) {
switch (adjustMode) {
case FUNC_ADJUST_GVAR_CONSTANT:
- return tr("Value ")+QString("%1").arg(param);
+ return tr("Value ") + QString("%1").arg(param);
case FUNC_ADJUST_GVAR_SOURCE:
case FUNC_ADJUST_GVAR_GVAR:
return RawSource(param).toString();
@@ -218,16 +225,16 @@ QString CustomFunctionData::repeatToString() const
}
else {
unsigned int step = 1;
- return tr("repeat(%1s)").arg(step*repeatParam);
+ return tr("repeat(%1s)").arg(step * repeatParam);
}
}
QString CustomFunctionData::enabledToString() const
{
- if ((func >= FuncOverrideCH1 && func <= FuncOverrideCH32) ||
+ if ((func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) ||
(func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) ||
(func == FuncReset) ||
- (func >= FuncSetTimer1 && func <= FuncSetTimer2) ||
+ (func >= FuncSetTimer1 && func <= FuncSetTimerLast) ||
(func == FuncVolume) ||
(func == FuncBacklight) ||
(func <= FuncInstantTrim)) {
@@ -238,6 +245,64 @@ QString CustomFunctionData::enabledToString() const
return "";
}
+// static
+bool CustomFunctionData::isFuncAvailable(int index)
+{
+ Firmware * fw = getCurrentFirmware();
+
+ bool ret = (((index >= FuncOverrideCH1 && index <= FuncOverrideCHLast) && !fw->getCapability(SafetyChannelCustomFunction)) ||
+ ((index == FuncVolume || index == FuncBackgroundMusic || index == FuncBackgroundMusicPause) && !fw->getCapability(HasVolume)) ||
+ ((index == FuncPlayScript && !IS_HORUS_OR_TARANIS(fw->getBoard()))) ||
+ ((index == FuncPlayHaptic) && !fw->getCapability(Haptic)) ||
+ ((index == FuncPlayBoth) && !fw->getCapability(HasBeeper)) ||
+ ((index == FuncLogs) && !fw->getCapability(HasSDLogs)) ||
+ ((index >= FuncSetTimer1 && index <= FuncSetTimerLast) && index > FuncSetTimer1 + fw->getCapability(Timers)) ||
+ ((index == FuncScreenshot) && !IS_HORUS_OR_TARANIS(fw->getBoard())) ||
+ ((index >= FuncRangeCheckInternalModule && index <= FuncBindExternalModule) && !fw->getCapability(DangerousFunctions)) ||
+ ((index >= FuncAdjustGV1 && index <= FuncAdjustGVLast) && !fw->getCapability(Gvars))
+ );
+ return !ret;
+}
+
+// static
+int CustomFunctionData::funcContext(int index)
+{
+ int ret = AllFunctionContexts;
+
+ if ((index >= FuncOverrideCH1 && index <= FuncOverrideCHLast) ||
+ (index >= FuncRangeCheckInternalModule && index <= FuncBindExternalModule) ||
+ (index >= FuncAdjustGV1 && index <= FuncAdjustGVLast))
+ ret &= ~GlobalFunctionsContext;
+
+ return ret;
+}
+// static
+int CustomFunctionData::resetParamCount(const ModelData * model)
+{
+ QComboBox cb;
+ CustomFunctionData::populateResetParams(model, &cb);
+ return cb.count();
+}
+
+// static
+bool CustomFunctionData::isResetParamAvailable(const ModelData * model, int index)
+{
+ Firmware * firmware = getCurrentFirmware();
+
+ if (index < CPN_MAX_TIMERS) {
+ if (index < firmware->getCapability(Timers))
+ return true;
+ else
+ return false;
+ }
+ else if (index < CPN_MAX_TIMERS + firmware->getCapability(RotaryEncoders))
+ return true;
+ else if (model && index < CPN_MAX_TIMERS + firmware->getCapability(RotaryEncoders) + firmware->getCapability(Sensors))
+ return model->sensorData[index - CPN_MAX_TIMERS - firmware->getCapability(RotaryEncoders)].isAvailable();
+
+ return false;
+}
+
void CustomFunctionData::convert(RadioDataConversionState & cstate)
{
cstate.setComponent(tr("CFN"), 8);
diff --git a/companion/src/firmwares/customfunctiondata.h b/companion/src/firmwares/customfunctiondata.h
index 93f9969e8..9e597441f 100644
--- a/companion/src/firmwares/customfunctiondata.h
+++ b/companion/src/firmwares/customfunctiondata.h
@@ -35,7 +35,8 @@ class RadioDataConversionState;
enum AssignFunc {
FuncOverrideCH1 = 0,
- FuncOverrideCH32 = FuncOverrideCH1+CPN_MAX_CHNOUT-1,
+ FuncOverrideCHLast = FuncOverrideCH1 + CPN_MAX_CHNOUT - 1,
+ FuncOverrideCH32 = FuncOverrideCHLast, // TODO remove
FuncTrainer,
FuncTrainerRUD,
FuncTrainerELE,
@@ -47,8 +48,9 @@ enum AssignFunc {
FuncPlayHaptic,
FuncReset,
FuncSetTimer1,
- FuncSetTimer2,
- FuncSetTimer3,
+ FuncSetTimer2, // TODO remove
+ FuncSetTimer3, // TODO remove
+ FuncSetTimerLast = FuncSetTimer1 + CPN_MAX_TIMERS - 1,
FuncVario,
FuncPlayPrompt,
FuncPlayBoth,
@@ -61,7 +63,7 @@ enum AssignFunc {
FuncBackgroundMusic,
FuncBackgroundMusicPause,
FuncAdjustGV1,
- FuncAdjustGVLast = FuncAdjustGV1+CPN_MAX_GVARS-1,
+ FuncAdjustGVLast = FuncAdjustGV1 + CPN_MAX_GVARS - 1,
FuncSetFailsafe,
FuncRangeCheckInternalModule,
FuncRangeCheckExternalModule,
@@ -83,7 +85,15 @@ class CustomFunctionData {
Q_DECLARE_TR_FUNCTIONS(CustomFunctionData)
public:
- CustomFunctionData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; }
+ enum CustomFunctionContext
+ {
+ GlobalFunctionsContext = 0x01,
+ SpecialFunctionsContext = 0x02,
+
+ AllFunctionContexts = GlobalFunctionsContext | SpecialFunctionsContext
+ };
+
+ CustomFunctionData(AssignFunc func = FuncOverrideCH1) { clear(); this->func = func; }
RawSwitch swtch;
AssignFunc func;
int param;
@@ -95,7 +105,7 @@ class CustomFunctionData {
void clear();
bool isEmpty() const;
QString nameToString(int index, bool globalContext = false) const;
- QString funcToString(const ModelData * model = NULL) const;
+ QString funcToString(const ModelData * model = nullptr) const;
QString paramToString(const ModelData * model) const;
QString repeatToString() const;
QString enabledToString() const;
@@ -103,6 +113,10 @@ class CustomFunctionData {
static void populateResetParams(const ModelData * model, QComboBox * b, unsigned int value);
static void populatePlaySoundParams(QStringList & qs);
static void populateHapticParams(QStringList & qs);
+ static bool isFuncAvailable(int index);
+ static int funcContext(int index);
+ static int resetParamCount(const ModelData * model);
+ static bool isResetParamAvailable(const ModelData * model, int index);
void convert(RadioDataConversionState & cstate);
diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp
index 930df092c..7657e2798 100644
--- a/companion/src/firmwares/modeldata.cpp
+++ b/companion/src/firmwares/modeldata.cpp
@@ -1439,3 +1439,42 @@ void ModelData::updateResetParam(CustomFunctionData * cfd)
updRefInfo.updcnt++;
}
}
+
+QString ModelData::thrTraceSrcToString() const
+{
+ return thrTraceSrcToString((int)thrTraceSrc);
+}
+
+QString ModelData::thrTraceSrcToString(const int index) const
+{
+ Firmware * firmware = getCurrentFirmware();
+ const Boards board = Boards(getCurrentBoard());
+ const int pscnt = board.getCapability(Board::Pots) + board.getCapability(Board::Sliders);
+
+ if (index == 0)
+ return tr("THR");
+ else if (index <= pscnt)
+ return board.getAnalogInputName(index + board.getCapability(Board::Sticks) - 1);
+ else if (index <= pscnt + firmware->getCapability(Outputs))
+ return RawSource(SOURCE_TYPE_CH, index - pscnt - 1).toString(this);
+
+ return QString(CPN_STR_UNKNOWN_ITEM);
+}
+
+int ModelData::thrTraceSrcCount() const
+{
+ const Boards board = Boards(getCurrentBoard());
+ Firmware * firmware = getCurrentFirmware();
+
+ return 1 + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + firmware->getCapability(Outputs);
+}
+
+bool ModelData::isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const
+{
+ const Boards board = Boards(getCurrentBoard());
+
+ if (index > 0 && index <= board.getCapability(Board::Pots) + board.getCapability(Board::Sliders))
+ return RawSource(SOURCE_TYPE_STICK, index + board.getCapability(Board::Sticks) - 1).isAvailable(this, generalSettings, board.getBoardType());
+ else
+ return true;
+}
diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h
index 7eacdc26d..2b277568f 100644
--- a/companion/src/firmwares/modeldata.h
+++ b/companion/src/firmwares/modeldata.h
@@ -283,6 +283,10 @@ class ModelData {
bool hasExpoChildren(const int index);
bool hasExpoSiblings(const int index);
void removeMix(const int idx);
+ QString thrTraceSrcToString() const;
+ QString thrTraceSrcToString(const int index) const;
+ int thrTraceSrcCount() const;
+ bool isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const;
protected:
void removeGlobalVar(int & var);
diff --git a/companion/src/firmwares/opentx/opentxeeprom.h b/companion/src/firmwares/opentx/opentxeeprom.h
index aabbe2284..fdb5247a5 100644
--- a/companion/src/firmwares/opentx/opentxeeprom.h
+++ b/companion/src/firmwares/opentx/opentxeeprom.h
@@ -37,6 +37,7 @@
#define TARANIS_X9LITES_VARIANT 0x0801
#define JUMPER_T12_VARIANT 0x4001
#define RADIOMASTER_TX12_VARIANT 0x4002
+#define RADIOMASTER_T8_VARIANT 0x4004
class OpenTxGeneralData: public TransformedField {
public:
diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp
index 04f02eb29..f0d50338e 100644
--- a/companion/src/firmwares/opentx/opentxinterface.cpp
+++ b/companion/src/firmwares/opentx/opentxinterface.cpp
@@ -68,6 +68,8 @@ const char * OpenTxEepromInterface::getName()
return "OpenTX for Radiomaster TX16S";
case BOARD_RADIOMASTER_TX12:
return "OpenTX for Radiomaster TX12";
+ case BOARD_RADIOMASTER_T8:
+ return "OpenTX for Radiomaster T8";
case BOARD_TARANIS_X9D:
return "OpenTX for FrSky Taranis X9D";
case BOARD_TARANIS_X9DP:
@@ -339,6 +341,9 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u
else if (IS_RADIOMASTER_TX12(board)) {
variant |= RADIOMASTER_TX12_VARIANT;
}
+ else if (IS_RADIOMASTER_T8(board)) {
+ variant |= RADIOMASTER_T8_VARIANT;
+ }
OpenTxGeneralData generator((GeneralSettings &)radioData.generalSettings, board, version, variant);
// generator.dump();
QByteArray data;
@@ -685,6 +690,8 @@ int OpenTxFirmware::getCapability(::Capability capability)
return JUMPER_T12_VARIANT;
else if (IS_RADIOMASTER_TX12(board))
return RADIOMASTER_TX12_VARIANT;
+ else if (IS_RADIOMASTER_T8(board))
+ return RADIOMASTER_T8_VARIANT;
else
return 0;
case MavlinkTelemetry:
@@ -954,6 +961,11 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
variantError = true;
}
}
+ else if (IS_RADIOMASTER_T8(board)) {
+ if (variant != RADIOMASTER_T8_VARIANT) {
+ variantError = true;
+ }
+ }
else if (IS_TARANIS(board)) {
if (variant != 0) {
variantError = true;
@@ -1294,6 +1306,17 @@ void registerOpenTxFirmwares()
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX);
+ /* Radiomaster T8 board */
+ firmware = new OpenTxFirmware("opentx-t8", QCoreApplication::translate("Firmware", "Radiomaster T8"), BOARD_RADIOMASTER_T8);
+ addOpenTxCommonOptions(firmware);
+ firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support"));
+ firmware->addOption("nogvars", Firmware::tr("Disable Global variables"));
+ firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
+ addOpenTxFontOptions(firmware);
+ registerOpenTxFirmware(firmware);
+ addOpenTxRfOptions(firmware, NONE);
+ firmware->addOption("bindkey", Firmware::tr("Allow bind using bind key"));
+
/* Radiomaster TX16S board */
firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16S / SE / Hall / Masterfire"), BOARD_RADIOMASTER_TX16S);
addOpenTxFrskyOptions(firmware);
diff --git a/companion/src/firmwares/rawsource.cpp b/companion/src/firmwares/rawsource.cpp
index 67a640c33..67ad743b6 100644
--- a/companion/src/firmwares/rawsource.cpp
+++ b/companion/src/firmwares/rawsource.cpp
@@ -143,14 +143,14 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
static const QString rotary[] = { tr("REa"), tr("REb") };
if (index<0) {
- return tr("???");
+ return QString(CPN_STR_UNKNOWN_ITEM);
}
QString result;
int genAryIdx = 0;
switch (type) {
case SOURCE_TYPE_NONE:
- return tr("----");
+ return QString(CPN_STR_NONE_ITEM);
case SOURCE_TYPE_VIRTUAL_INPUT:
{
@@ -161,7 +161,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
}
case SOURCE_TYPE_LUA_OUTPUT:
- return tr("LUA%1%2").arg(index/16+1).arg(QChar('a'+index%16));
+ return tr("LUA%1%2").arg(index / 16 + 1).arg(QChar('a' + index % 16));
case SOURCE_TYPE_STICK:
if (generalSettings) {
@@ -193,10 +193,10 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return result;
case SOURCE_TYPE_CUSTOM_SWITCH:
- return RawSwitch(SWITCH_TYPE_VIRTUAL, index+1).toString();
+ return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1).toString();
case SOURCE_TYPE_CYC:
- return tr("CYC%1").arg(index+1);
+ return tr("CYC%1").arg(index + 1);
case SOURCE_TYPE_PPM:
return RadioData::getElementName(tr("TR", "as in Trainer"), index + 1);
@@ -208,18 +208,15 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return LimitData().nameToString(index);
case SOURCE_TYPE_SPECIAL:
- result = CHECK_IN_ARRAY(special, index);
- // TODO refactor timers into own source type
- if (result.startsWith("Timer")) {
- bool ok;
- int n = result.right(1).toInt(&ok);
- if (ok) {
- if (model)
- result = model->timers[n - 1].nameToString(n - 1);
- else
- result = TimerData().nameToString(n - 1);
- }
+ if (index >= SOURCE_TYPE_SPECIAL_TIMER1_IDX && index <= SOURCE_TYPE_SPECIAL_TIMER1_IDX + CPN_MAX_TIMERS - 1) {
+ if (model)
+ result = model->timers[index - SOURCE_TYPE_SPECIAL_TIMER1_IDX].nameToString(index - SOURCE_TYPE_SPECIAL_TIMER1_IDX);
+ else
+ result = TimerData().nameToString(index - SOURCE_TYPE_SPECIAL_TIMER1_IDX);
}
+ else
+ result = CHECK_IN_ARRAY(special, index);
+
return result;
case SOURCE_TYPE_TELEMETRY:
@@ -241,7 +238,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return GVarData().nameToString(index);
default:
- return tr("???");
+ return QString(CPN_STR_UNKNOWN_ITEM);
}
}
@@ -409,4 +406,3 @@ QStringList RawSource::getSwitchList(Boards board) const
}
return ret;
}
-
diff --git a/companion/src/firmwares/rawsource.h b/companion/src/firmwares/rawsource.h
index 9d0b19450..a7d293173 100644
--- a/companion/src/firmwares/rawsource.h
+++ b/companion/src/firmwares/rawsource.h
@@ -178,6 +178,9 @@ enum RawSourceType {
MAX_SOURCE_TYPE
};
+constexpr int SOURCE_TYPE_STICK_THR_IDX { 3 }; // TODO is there a function to determine index?
+constexpr int SOURCE_TYPE_SPECIAL_TIMER1_IDX { 2 }; // TODO temp const until Timers own source type
+
class RawSourceRange
{
Q_DECLARE_TR_FUNCTIONS(RawSourceRange)
diff --git a/companion/src/firmwares/sensordata.cpp b/companion/src/firmwares/sensordata.cpp
index a9b8d7640..ebcccfa6a 100644
--- a/companion/src/firmwares/sensordata.cpp
+++ b/companion/src/firmwares/sensordata.cpp
@@ -22,6 +22,8 @@
#include "radiodata.h"
#include "modeldata.h"
+#include "eeprominterface.h"
+#include "compounditemmodels.h"
void SensorData::updateUnit()
{
@@ -31,9 +33,18 @@ void SensorData::updateUnit()
}
}
+// TODO depreciated
QString SensorData::unitString() const
{
- switch (unit) {
+ return unitToString(unit);
+}
+
+// static
+QString SensorData::unitToString(const int value)
+{
+ switch (value) {
+ case UNIT_RAW:
+ return tr("Raw (-)");
case UNIT_VOLTS:
return tr("V");
case UNIT_AMPS:
@@ -91,7 +102,7 @@ QString SensorData::unitString() const
case UNIT_US:
return tr("uS");
default:
- return "";
+ return CPN_STR_UNKNOWN_ITEM;
}
}
@@ -118,3 +129,166 @@ bool SensorData::isEmpty() const
{
return (!isAvailable() && type == 0 && id == 0 && subid == 0 && instance == 0 && rxIdx == 0 && moduleIdx == 0 && unit == 0 && ratio == 0 && prec == 0 && offset == 0 && autoOffset == 0 && filter == 0 && onlyPositive == 0 && logs == 0);
}
+
+// static
+QString SensorData::typeToString(const int value)
+{
+ switch(value) {
+ case TELEM_TYPE_CUSTOM:
+ return tr("Custom");
+ case TELEM_TYPE_CALCULATED:
+ return tr("Calculated");
+ default:
+ return CPN_STR_UNKNOWN_ITEM;
+ }
+}
+
+// static
+QString SensorData::formulaToString(const int value)
+{
+ switch(value) {
+ case TELEM_FORMULA_ADD:
+ return tr("Add");
+ case TELEM_FORMULA_AVERAGE:
+ return tr("Average");
+ case TELEM_FORMULA_MIN:
+ return tr("Minimum");
+ case TELEM_FORMULA_MAX:
+ return tr("Maximum");
+ case TELEM_FORMULA_MULTIPLY:
+ return tr("Multiply");
+ case TELEM_FORMULA_TOTALIZE:
+ return tr("Totalize");
+ case TELEM_FORMULA_CELL:
+ return tr("Cell");
+ case TELEM_FORMULA_CONSUMPTION:
+ return tr("Consumption");
+ case TELEM_FORMULA_DIST:
+ return tr("Distance");
+ default:
+ return CPN_STR_UNKNOWN_ITEM;
+ }
+}
+
+// static
+QString SensorData::cellIndexToString(const int value)
+{
+ if (value == TELEM_CELL_INDEX_LOWEST)
+ return tr("Lowest");
+ if (value > TELEM_CELL_INDEX_LOWEST && value < TELEM_CELL_INDEX_HIGHEST)
+ return tr("Cell %1").arg(value - TELEM_CELL_INDEX_LOWEST);
+ if (value== TELEM_CELL_INDEX_HIGHEST)
+ return tr("Highest");
+ if (value == TELEM_CELL_INDEX_DELTA)
+ return tr("Delta");
+ return CPN_STR_UNKNOWN_ITEM;
+}
+
+// static
+QString SensorData::precisionToString(const int value)
+{
+ return QString("0.%1").arg(QString(value, '0'));
+}
+
+// static
+QString SensorData::sourceToString(const ModelData * model, const int index, const bool sign)
+{
+ if (model) {
+ const QString prfx = sign ? index < 0 ? "-" : "+" : "";
+
+ if (abs(index) > 0) {
+ const SensorData &sd = model->sensorData[abs(index) - 1];
+ if (sd.type == SensorData::TELEM_TYPE_CUSTOM)
+ return QString("%1%2 (%3)").arg(prfx).arg(sd.label).arg(sd.getOrigin(model));
+ else
+ return QString("%1%2").arg(prfx).arg(sd.label);
+ }
+ else
+ return CPN_STR_NONE_ITEM;
+ }
+
+ return "";
+}
+
+// static
+bool SensorData::isSourceAvailable(const ModelData * model, const int index)
+{
+ Firmware * firmware = getCurrentFirmware();
+ const int sensorcnt = firmware->getCapability(Sensors);
+ const int i = abs(index);
+
+ if (model && sensorcnt > 0 && i <= sensorcnt) {
+ if (i > 0)
+ return model->sensorData[i - 1].isAvailable();
+ else
+ return true;
+ }
+
+ return false;
+}
+
+// static
+AbstractStaticItemModel * SensorData::typeItemModel()
+{
+ AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
+ mdl->setName("sensordata.type");
+
+ for (int i = 0; i <= TELEM_TYPE_LAST; i++) {
+ mdl->appendToItemList(typeToString(i), i);
+ }
+
+ mdl->loadItemList();
+ return mdl;
+}
+
+// static
+AbstractStaticItemModel * SensorData::formulaItemModel()
+{
+ AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
+ mdl->setName("sensordata.formula");
+
+ for (int i = 0; i <= TELEM_FORMULA_LAST; i++) {
+ mdl->appendToItemList(formulaToString(i), i);
+ }
+
+ mdl->loadItemList();
+ return mdl;
+}
+
+// static
+AbstractStaticItemModel * SensorData::cellIndexItemModel()
+{
+ AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
+ mdl->setName("sensordata.cellindex");
+
+ for (int i = 0; i <= TELEM_CELL_INDEX_LAST; i++) {
+ mdl->appendToItemList(cellIndexToString(i), i);
+ }
+
+ mdl->loadItemList();
+ return mdl;
+}
+
+// static
+AbstractStaticItemModel * SensorData::unitItemModel()
+{
+ AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
+ mdl->setName("sensordata.unit");
+
+ for (int i = 0; i <= UNIT_MAX; i++) {
+ QString str = unitToString(i);
+ if (str != CPN_STR_UNKNOWN_ITEM)
+ mdl->appendToItemList(str, i);
+ }
+
+ mdl->loadItemList();
+ return mdl;
+}
+
+// static
+PrecisionItemModel * SensorData::precisionItemModel()
+{
+ PrecisionItemModel * mdl = new PrecisionItemModel(0, 2);
+ mdl->setName("sensordata.precision");
+ return mdl;
+}
diff --git a/companion/src/firmwares/sensordata.h b/companion/src/firmwares/sensordata.h
index a2b993bcc..afd9d7891 100644
--- a/companion/src/firmwares/sensordata.h
+++ b/companion/src/firmwares/sensordata.h
@@ -27,6 +27,8 @@ constexpr int CPN_MAX_SENSORS = 60;
constexpr int SENSOR_LABEL_LEN = 4;
class ModelData;
+class AbstractStaticItemModel;
+class PrecisionItemModel;
class SensorData {
Q_DECLARE_TR_FUNCTIONS(SensorData)
@@ -36,7 +38,8 @@ class SensorData {
enum
{
TELEM_TYPE_CUSTOM,
- TELEM_TYPE_CALCULATED
+ TELEM_TYPE_CALCULATED,
+ TELEM_TYPE_LAST = TELEM_TYPE_CALCULATED
};
enum
@@ -63,6 +66,7 @@ class SensorData {
TELEM_CELL_INDEX_6,
TELEM_CELL_INDEX_HIGHEST,
TELEM_CELL_INDEX_DELTA,
+ TELEM_CELL_INDEX_LAST = TELEM_CELL_INDEX_DELTA
};
enum
@@ -168,6 +172,20 @@ class SensorData {
QString getOrigin(const ModelData* model) const;
void clear() { memset(this, 0, sizeof(SensorData)); }
bool isEmpty() const;
+
+ static QString sourceToString(const ModelData * model, const int index, const bool sign = false);
+ static bool isSourceAvailable(const ModelData * model, const int index);
+ static QString typeToString(const int value);
+ static QString formulaToString(const int value);
+ static QString cellIndexToString(const int value);
+ static QString unitToString(const int value);
+ static QString precisionToString(const int value);
+
+ static AbstractStaticItemModel * typeItemModel();
+ static AbstractStaticItemModel * formulaItemModel();
+ static AbstractStaticItemModel * cellIndexItemModel();
+ static AbstractStaticItemModel * unitItemModel();
+ static PrecisionItemModel * precisionItemModel();
};
#endif // SENSORDATA_H
diff --git a/companion/src/generaledit/generaledit.cpp b/companion/src/generaledit/generaledit.cpp
index bff9d3f83..e80038f9f 100644
--- a/companion/src/generaledit/generaledit.cpp
+++ b/companion/src/generaledit/generaledit.cpp
@@ -28,7 +28,7 @@
#include "hardware.h"
#include "../modeledit/customfunctions.h"
#include "verticalscrollarea.h"
-#include "rawitemdatamodels.h"
+#include "compounditemmodels.h"
GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) :
QDialog(parent),
@@ -56,10 +56,14 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
}
}
- commonItemModels = new CommonItemModels(&generalSettings, nullptr, this);
+ sharedItemModels = new CompoundItemModelFactory(&generalSettings, nullptr);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSource);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSwitch);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam);
addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup"));
- addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, commonItemModels), tr("Global Functions"));
+ addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, sharedItemModels), tr("Global Functions"));
addTab(new TrainerPanel(this, generalSettings, firmware), tr("Trainer"));
addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware"));
addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration"));
@@ -70,6 +74,7 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
GeneralEdit::~GeneralEdit()
{
delete ui;
+ delete sharedItemModels;
}
void GeneralEdit::closeEvent(QCloseEvent *event)
diff --git a/companion/src/generaledit/generaledit.h b/companion/src/generaledit/generaledit.h
index 3f73a9e01..b2e6caa82 100644
--- a/companion/src/generaledit/generaledit.h
+++ b/companion/src/generaledit/generaledit.h
@@ -25,7 +25,7 @@
#include "eeprominterface.h"
#include "genericpanel.h"
-class CommonItemModels;
+class CompoundItemModelFactory;
namespace Ui {
class GeneralEdit;
@@ -73,7 +73,7 @@ class GeneralEdit : public QDialog
QVector panels;
void addTab(GenericPanel *panel, QString text);
void closeEvent(QCloseEvent *event);
- CommonItemModels *commonItemModels;
+ CompoundItemModelFactory *sharedItemModels;
};
#endif // _GENERALEDIT_H_
diff --git a/companion/src/images/simulator/T8/bottom.png b/companion/src/images/simulator/T8/bottom.png
new file mode 100644
index 000000000..055c7db62
Binary files /dev/null and b/companion/src/images/simulator/T8/bottom.png differ
diff --git a/companion/src/images/simulator/T8/left-pagedn.png b/companion/src/images/simulator/T8/left-pagedn.png
new file mode 100644
index 000000000..6b290e368
Binary files /dev/null and b/companion/src/images/simulator/T8/left-pagedn.png differ
diff --git a/companion/src/images/simulator/T8/left-pageup.png b/companion/src/images/simulator/T8/left-pageup.png
new file mode 100644
index 000000000..c155649a1
Binary files /dev/null and b/companion/src/images/simulator/T8/left-pageup.png differ
diff --git a/companion/src/images/simulator/T8/left-rtn.png b/companion/src/images/simulator/T8/left-rtn.png
new file mode 100644
index 000000000..95cc700f6
Binary files /dev/null and b/companion/src/images/simulator/T8/left-rtn.png differ
diff --git a/companion/src/images/simulator/T8/left-sys.png b/companion/src/images/simulator/T8/left-sys.png
new file mode 100644
index 000000000..7943ed93d
Binary files /dev/null and b/companion/src/images/simulator/T8/left-sys.png differ
diff --git a/companion/src/images/simulator/T8/left.png b/companion/src/images/simulator/T8/left.png
new file mode 100644
index 000000000..ff25c9543
Binary files /dev/null and b/companion/src/images/simulator/T8/left.png differ
diff --git a/companion/src/images/simulator/T8/right-dn.png b/companion/src/images/simulator/T8/right-dn.png
new file mode 100644
index 000000000..82a383576
Binary files /dev/null and b/companion/src/images/simulator/T8/right-dn.png differ
diff --git a/companion/src/images/simulator/T8/right-ent.png b/companion/src/images/simulator/T8/right-ent.png
new file mode 100644
index 000000000..8c3be3a56
Binary files /dev/null and b/companion/src/images/simulator/T8/right-ent.png differ
diff --git a/companion/src/images/simulator/T8/right-mdl.png b/companion/src/images/simulator/T8/right-mdl.png
new file mode 100644
index 000000000..f385c652e
Binary files /dev/null and b/companion/src/images/simulator/T8/right-mdl.png differ
diff --git a/companion/src/images/simulator/T8/right-up.png b/companion/src/images/simulator/T8/right-up.png
new file mode 100644
index 000000000..5e3bd39ed
Binary files /dev/null and b/companion/src/images/simulator/T8/right-up.png differ
diff --git a/companion/src/images/simulator/T8/right.png b/companion/src/images/simulator/T8/right.png
new file mode 100644
index 000000000..1016d8de5
Binary files /dev/null and b/companion/src/images/simulator/T8/right.png differ
diff --git a/companion/src/images/simulator/T8/top.png b/companion/src/images/simulator/T8/top.png
new file mode 100644
index 000000000..962119223
Binary files /dev/null and b/companion/src/images/simulator/T8/top.png differ
diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp
index 9d490da39..23c5f71b7 100644
--- a/companion/src/mainwindow.cpp
+++ b/companion/src/mainwindow.cpp
@@ -1585,7 +1585,7 @@ void MainWindow::updateWindowActions()
QString scut;
if (++count < 10)
scut = tr("Alt+%1").arg(count);
- QAction * act = addActToGroup(windowsListActions, "", "", "window_ptr", qVariantFromValue(win), QVariant(), scut);
+ QAction * act = addActToGroup(windowsListActions, "", "", "window_ptr", QVariant::fromValue(win), QVariant(), scut);
act->setChecked(win == mdiArea->activeSubWindow());
updateWindowActionTitle(win, act);
}
diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp
index d2818368e..27374a8c4 100644
--- a/companion/src/modeledit/channels.cpp
+++ b/companion/src/modeledit/channels.cpp
@@ -20,7 +20,7 @@
#include "channels.h"
#include "helpers.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel):
firmware(firmware),
@@ -96,16 +96,15 @@ void LimitsGroup::updateMinMax(int max)
}
}
}
-ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
- commonItemModels(commonItemModels)
+ sharedItemModels(sharedItemModels)
{
chnCapability = firmware->getCapability(Outputs);
int channelNameMaxLen = firmware->getCapability(ChannelsName);
- curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this);
- connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &ChannelsPanel::onModelDataAboutToBeUpdated);
- connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &ChannelsPanel::onModelDataUpdateComplete);
+ curveFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve));
+ connectItemModelEvents(curveFilteredModel);
QStringList headerLabels;
headerLabels << "#";
@@ -214,6 +213,7 @@ ChannelsPanel::~ChannelsPanel()
delete centerSB[i];
delete symlimitsChk[i];
}
+ delete curveFilteredModel;
}
void ChannelsPanel::symlimitsEdited()
@@ -474,12 +474,18 @@ void ChannelsPanel::swapData(int idx1, int idx2)
}
}
-void ChannelsPanel::onModelDataAboutToBeUpdated()
+void ChannelsPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &ChannelsPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &ChannelsPanel::onItemModelUpdateComplete);
+}
+
+void ChannelsPanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
-void ChannelsPanel::onModelDataUpdateComplete()
+void ChannelsPanel::onItemModelUpdateComplete()
{
update();
lock = false;
@@ -487,5 +493,5 @@ void ChannelsPanel::onModelDataUpdateComplete()
void ChannelsPanel::updateItemModels()
{
- commonItemModels->update(CommonItemModels::RMO_CHANNELS);
+ sharedItemModels->update(AbstractItemModel::IMUE_Channels);
}
diff --git a/companion/src/modeledit/channels.h b/companion/src/modeledit/channels.h
index a481feec2..2a65f497a 100644
--- a/companion/src/modeledit/channels.h
+++ b/companion/src/modeledit/channels.h
@@ -26,8 +26,8 @@
#include
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel";
@@ -57,8 +57,8 @@ class ChannelsPanel : public ModelPanel
Q_OBJECT
public:
- ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
- ~ChannelsPanel();
+ ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
+ virtual ~ChannelsPanel();
public slots:
void refreshExtendedLimits();
@@ -81,8 +81,8 @@ class ChannelsPanel : public ModelPanel
void cmClear(bool prompt = true);
void cmClearAll();
void onCustomContextMenuRequested(QPoint pos);
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
bool hasClipboardData(QByteArray * data = nullptr) const;
@@ -100,9 +100,10 @@ class ChannelsPanel : public ModelPanel
QCheckBox *symlimitsChk[CPN_MAX_CHNOUT];
int selectedIndex;
int chnCapability;
- CommonItemModels * commonItemModels;
- RawItemFilteredModel *curveFilteredModel;
+ CompoundItemModelFactory *sharedItemModels;
+ FilteredItemModel *curveFilteredModel;
void updateItemModels();
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _CHANNELS_H_
diff --git a/companion/src/modeledit/curves.cpp b/companion/src/modeledit/curves.cpp
index 9e60f30c3..7f8b80219 100644
--- a/companion/src/modeledit/curves.cpp
+++ b/companion/src/modeledit/curves.cpp
@@ -23,7 +23,7 @@
#include "node.h"
#include "edge.h"
#include "helpers.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
#define GFX_MARGIN 16
@@ -109,11 +109,12 @@ float curveSymmetricalX(float x, float coeff, float yMin, float yMid, float yMax
return y;
}
-CurvesPanel::CurvesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+CurvesPanel::CurvesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
+ CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Curves),
currentCurve(0),
- commonItemModels(commonItemModels)
+ sharedItemModels(sharedItemModels)
{
ui->setupUi(this);
@@ -812,7 +813,7 @@ void CurvesPanel::swapData(int idx1, int idx2)
void CurvesPanel::updateItemModels()
{
- commonItemModels->update(CommonItemModels::RMO_CURVES);
+ sharedItemModels->update(AbstractItemModel::IMUE_Curves);
}
CustomScene::CustomScene(QGraphicsView * view) :
diff --git a/companion/src/modeledit/curves.h b/companion/src/modeledit/curves.h
index 8df3a8528..c66f79cb7 100644
--- a/companion/src/modeledit/curves.h
+++ b/companion/src/modeledit/curves.h
@@ -26,7 +26,7 @@
#include
#include
-class CommonItemModels;
+class CompoundItemModelFactory;
constexpr char MIMETYPE_CURVE[] = "application/x-companion-curve";
@@ -61,7 +61,7 @@ class CurvesPanel : public ModelPanel
Q_OBJECT
public:
- CurvesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
+ CurvesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~CurvesPanel();
virtual void update();
@@ -121,7 +121,7 @@ class CurvesPanel : public ModelPanel
bool moveDownAllowed() const;
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
- CommonItemModels * commonItemModels;
+ CompoundItemModelFactory * sharedItemModels;
void updateItemModels();
};
diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp
index c3ee895b7..5c15bd538 100644
--- a/companion/src/modeledit/customfunctions.cpp
+++ b/companion/src/modeledit/customfunctions.cpp
@@ -19,7 +19,7 @@
*/
#include "customfunctions.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
#include "helpers.h"
#include "appdata.h"
@@ -66,10 +66,10 @@ void RepeatComboBox::update()
setCurrentIndex(value);
}
-CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware,
+ CompoundItemModelFactory * sharedItemModels):
GenericPanel(parent, model, generalSettings, firmware),
functions(model ? model->customFn : generalSettings.customFn),
- commonItemModels(commonItemModels),
mediaPlayerCurrent(-1),
mediaPlayer(nullptr),
modelsUpdateCnt(0)
@@ -77,21 +77,18 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
lock = true;
fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
- rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
+ rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
+ model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext);
+ connectItemModelEvents(rawSwitchFilteredModel);
- rawSourceAllModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this);
- connect(rawSourceAllModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
- connect(rawSourceAllModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
+ rawSourceAllModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource));
+ connectItemModelEvents(rawSourceAllModel);
- rawSourceInputsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this);
- connect(rawSourceInputsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
- connect(rawSourceInputsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
+ rawSourceInputsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::InputSourceGroups);
+ connectItemModelEvents(rawSourceInputsModel);
- rawSourceGVarsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::GVarsGroup, this);
- connect(rawSourceGVarsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
- connect(rawSourceGVarsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
+ rawSourceGVarsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::GVarsGroup);
+ connectItemModelEvents(rawSourceGVarsModel);
if (!firmware->getCapability(VoicesAsNumbers)) {
tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength));
@@ -253,6 +250,10 @@ CustomFunctionsPanel::~CustomFunctionsPanel()
{
if (mediaPlayer)
stopSound(mediaPlayerCurrent);
+ delete rawSwitchFilteredModel;
+ delete rawSourceAllModel;
+ delete rawSourceInputsModel;
+ delete rawSourceGVarsModel;
}
void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state)
@@ -827,13 +828,19 @@ bool CustomFunctionsPanel::moveUpAllowed() const
return selectedIndex > 0;
}
-void CustomFunctionsPanel::onModelDataAboutToBeUpdated()
+void CustomFunctionsPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &CustomFunctionsPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &CustomFunctionsPanel::onItemModelUpdateComplete);
+}
+
+void CustomFunctionsPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
-void CustomFunctionsPanel::onModelDataUpdateComplete()
+void CustomFunctionsPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h
index 9b3e3d238..e41baf672 100644
--- a/companion/src/modeledit/customfunctions.h
+++ b/companion/src/modeledit/customfunctions.h
@@ -26,8 +26,8 @@
#include
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
class TimerEdit;
constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function";
@@ -55,8 +55,8 @@ class CustomFunctionsPanel : public GenericPanel
Q_OBJECT
public:
- CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
- ~CustomFunctionsPanel();
+ CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
+ virtual ~CustomFunctionsPanel();
virtual void update();
@@ -83,8 +83,8 @@ class CustomFunctionsPanel : public GenericPanel
void cmInsert();
void cmClear(bool prompt = true);
void cmClearAll();
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
void populateFuncCB(QComboBox *b, unsigned int value);
@@ -96,11 +96,12 @@ class CustomFunctionsPanel : public GenericPanel
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
void resetCBsAndRefresh(int idx);
- CommonItemModels * commonItemModels;
- RawItemFilteredModel * rawSwitchFilteredModel;
- RawItemFilteredModel * rawSourceAllModel;
- RawItemFilteredModel * rawSourceInputsModel;
- RawItemFilteredModel * rawSourceGVarsModel;
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
+
+ FilteredItemModel * rawSwitchFilteredModel;
+ FilteredItemModel * rawSourceAllModel;
+ FilteredItemModel * rawSourceInputsModel;
+ FilteredItemModel * rawSourceGVarsModel;
QSet tracksSet;
QSet scriptsSet;
diff --git a/companion/src/modeledit/expodialog.cpp b/companion/src/modeledit/expodialog.cpp
index afebbeb27..808cff7ba 100644
--- a/companion/src/modeledit/expodialog.cpp
+++ b/companion/src/modeledit/expodialog.cpp
@@ -20,12 +20,11 @@
#include "expodialog.h"
#include "ui_expodialog.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
#include "helpers.h"
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings,
- Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceModel,
- RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel) :
+ Firmware * firmware, QString & inputName, CompoundItemModelFactory * sharedItemModels) :
QDialog(parent),
ui(new Ui::ExpoDialog),
model(model),
@@ -38,6 +37,9 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
{
ui->setupUi(this);
+ dialogFilteredItemModels = new FilteredItemModelFactory();
+ int id;
+
QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 };
QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 };
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
@@ -50,9 +52,15 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100);
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100);
- curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, ed->curve, model, curveItemModel, this);
- ui->switchesCB->setModel(rawSwitchModel);
+ curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
+ firmware->getCapability(HasInputDiff) ? 0 : FilteredItemModel::PositiveFilter);
+ curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, ed->curve, model,
+ curveRefFilteredItemModels, this);
+
+ id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
+ RawSwitch::MixesContext), "RawSwitch");
+ ui->switchesCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue()));
ui->sideCB->setCurrentIndex(ed->mode - 1);
@@ -83,7 +91,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
if (firmware->getCapability(VirtualInputs)) {
ui->inputName->setMaxLength(firmware->getCapability(InputsLength));
- ui->sourceCB->setModel(rawSourceModel);
+ id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
+ (RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup)),
+ "RawSource");
+ ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue()));
ui->inputName->setValidator(new QRegExpValidator(rx, this));
ui->inputName->setText(inputName);
@@ -135,9 +146,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
ExpoDialog::~ExpoDialog()
{
+ delete ui;
delete gvWeightGroup;
delete gvOffsetGroup;
- delete ui;
+ delete dialogFilteredItemModels;
}
void ExpoDialog::updateScale()
diff --git a/companion/src/modeledit/expodialog.h b/companion/src/modeledit/expodialog.h
index b77d55852..f4980d344 100644
--- a/companion/src/modeledit/expodialog.h
+++ b/companion/src/modeledit/expodialog.h
@@ -26,7 +26,9 @@
#include "modelprinter.h"
class GVarGroup;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModelFactory;
+class CurveRefFilteredFactory;
class CurveReferenceUIManager;
namespace Ui {
@@ -37,9 +39,8 @@ class ExpoDialog : public QDialog {
Q_OBJECT
public:
ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings,
- Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceItemModel,
- RawItemFilteredModel * rawSwitchItemModel, RawItemFilteredModel * curveItemModel);
- ~ExpoDialog();
+ Firmware * firmware, QString & inputName, CompoundItemModelFactory * sharedItemModels);
+ virtual ~ExpoDialog();
protected:
void updateScale();
@@ -65,6 +66,8 @@ class ExpoDialog : public QDialog {
ModelPrinter modelPrinter;
bool lock;
QCheckBox * cb_fp[CPN_MAX_FLIGHT_MODES];
+ FilteredItemModelFactory *dialogFilteredItemModels;
+ CurveRefFilteredFactory *curveRefFilteredItemModels;
};
#endif // _EXPODIALOG_H_
diff --git a/companion/src/modeledit/flightmodes.cpp b/companion/src/modeledit/flightmodes.cpp
index 32188feea..224d69965 100644
--- a/companion/src/modeledit/flightmodes.cpp
+++ b/companion/src/modeledit/flightmodes.cpp
@@ -20,19 +20,19 @@
#include "flightmodes.h"
#include "ui_flightmode.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
#include "helpers.h"
#include "customdebug.h"
-FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel):
+FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware,
+ FilteredItemModel * rawSwitchFilteredModel):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::FlightMode),
phaseIdx(phaseIdx),
phase(model.flightModeData[phaseIdx])
{
ui->setupUi(this);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &FlightModePanel::onModelDataAboutToBeUpdated);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &FlightModePanel::onModelDataUpdateComplete);
+ connectItemModelEvents(rawSwitchFilteredModel);
ui->labelName->setContextMenuPolicy(Qt::CustomContextMenu);
ui->labelName->setToolTip(tr("Popup menu available"));
@@ -1361,12 +1361,18 @@ void FlightModePanel::gvSwapData(int idx1, int idx2)
}
}
-void FlightModePanel::onModelDataAboutToBeUpdated()
+void FlightModePanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &FlightModePanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &FlightModePanel::onItemModelUpdateComplete);
+}
+
+void FlightModePanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
-void FlightModePanel::onModelDataUpdateComplete()
+void FlightModePanel::onItemModelUpdateComplete()
{
update();
lock = false;
@@ -1374,11 +1380,14 @@ void FlightModePanel::onModelDataUpdateComplete()
/**********************************************************/
-FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
+ CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
- commonItemModels(commonItemModels)
+ sharedItemModels(sharedItemModels)
{
- rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
+ rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::MixesContext);
+ connectItemModelEvents(rawSwitchFilteredModel);
+
modesCount = firmware->getCapability(FlightModes);
QGridLayout * gridLayout = new QGridLayout(this);
@@ -1403,6 +1412,7 @@ FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralS
FlightModesPanel::~FlightModesPanel()
{
+ delete rawSwitchFilteredModel;
}
QString FlightModesPanel::getTabName(int index)
@@ -1431,10 +1441,24 @@ void FlightModesPanel::update()
emit updated();
}
+void FlightModesPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &FlightModesPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &FlightModesPanel::onItemModelUpdateComplete);
+}
+
+void FlightModesPanel::onItemModelAboutToBeUpdated()
+{
+}
+
+void FlightModesPanel::onItemModelUpdateComplete()
+{
+}
+
void FlightModesPanel::updateItemModels()
{
- commonItemModels->update(CommonItemModels::RMO_FLIGHT_MODES);
- commonItemModels->update(CommonItemModels::RMO_GLOBAL_VARIABLES);
+ sharedItemModels->update(AbstractItemModel::IMUE_FlightModes);
+ sharedItemModels->update(AbstractItemModel::IMUE_GVars);
}
void FlightModesPanel::onTabIndexChanged(int index)
diff --git a/companion/src/modeledit/flightmodes.h b/companion/src/modeledit/flightmodes.h
index ca3619c6c..33fd87e8a 100644
--- a/companion/src/modeledit/flightmodes.h
+++ b/companion/src/modeledit/flightmodes.h
@@ -24,8 +24,8 @@
#include "modeledit.h"
#include "eeprominterface.h"
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode";
constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params";
@@ -41,7 +41,8 @@ class FlightModePanel : public ModelPanel
Q_OBJECT
public:
- FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel);
+ FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware,
+ FilteredItemModel * rawSwitchFilteredModel);
virtual ~FlightModePanel();
virtual void update();
@@ -90,8 +91,8 @@ class FlightModePanel : public ModelPanel
void gvCmPaste();
void gvCmMoveDown();
void gvCmMoveUp();
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
Ui::FlightMode *ui;
@@ -138,6 +139,7 @@ class FlightModePanel : public ModelPanel
bool gvMoveDownAllowed() const;
bool gvMoveUpAllowed() const;
void gvSwapData(int idx1, int idx2);
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class FlightModesPanel : public ModelPanel
@@ -145,7 +147,7 @@ class FlightModesPanel : public ModelPanel
Q_OBJECT
public:
- FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
+ FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~FlightModesPanel();
public slots:
@@ -157,16 +159,19 @@ class FlightModesPanel : public ModelPanel
private slots:
void onPhaseNameChanged();
void onTabIndexChanged(int index);
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
QString getTabName(int index);
int modesCount;
QTabWidget *tabWidget;
- CommonItemModels *commonItemModels;
- RawItemFilteredModel *rawSwitchFilteredModel;
+ CompoundItemModelFactory *sharedItemModels;
+ FilteredItemModel *rawSwitchFilteredModel;
QVector panels;
void updateItemModels();
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _FLIGHTMODES_H_
diff --git a/companion/src/modeledit/heli.cpp b/companion/src/modeledit/heli.cpp
index 1b8607799..ef86c5793 100644
--- a/companion/src/modeledit/heli.cpp
+++ b/companion/src/modeledit/heli.cpp
@@ -21,18 +21,16 @@
#include "heli.h"
#include "ui_heli.h"
#include "helpers.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
-HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
- ui(new Ui::Heli),
- commonItemModels(commonItemModels)
+ ui(new Ui::Heli)
{
ui->setupUi(this);
- rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &HeliPanel::onModelDataAboutToBeUpdated);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &HeliPanel::onModelDataUpdateComplete);
+ rawSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::InputSourceGroups);
+ connectItemModelEvents(rawSourceFilteredModel);
connect(ui->swashType, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
connect(ui->swashRingVal, SIGNAL(editingFinished()), this, SLOT(edited()));
@@ -71,6 +69,7 @@ HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & gener
HeliPanel::~HeliPanel()
{
delete ui;
+ delete rawSourceFilteredModel;
}
void HeliPanel::update()
@@ -118,12 +117,18 @@ void HeliPanel::edited()
}
}
-void HeliPanel::onModelDataAboutToBeUpdated()
+void HeliPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &HeliPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &HeliPanel::onItemModelUpdateComplete);
+}
+
+void HeliPanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
-void HeliPanel::onModelDataUpdateComplete()
+void HeliPanel::onItemModelUpdateComplete()
{
update();
lock = false;
diff --git a/companion/src/modeledit/heli.h b/companion/src/modeledit/heli.h
index ee9a3ac36..eb3c7d54e 100644
--- a/companion/src/modeledit/heli.h
+++ b/companion/src/modeledit/heli.h
@@ -23,8 +23,8 @@
#include "modeledit.h"
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
namespace Ui {
class Heli;
@@ -35,19 +35,19 @@ class HeliPanel : public ModelPanel
Q_OBJECT
public:
- HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
- ~HeliPanel();
+ HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
+ virtual ~HeliPanel();
void update();
private slots:
void edited();
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
Ui::Heli *ui;
- CommonItemModels * commonItemModels;
- RawItemFilteredModel * rawSourceFilteredModel;
+ FilteredItemModel * rawSourceFilteredModel;
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _HELI_H_
diff --git a/companion/src/modeledit/inputs.cpp b/companion/src/modeledit/inputs.cpp
index ee2347aee..f48d7d916 100644
--- a/companion/src/modeledit/inputs.cpp
+++ b/companion/src/modeledit/inputs.cpp
@@ -21,25 +21,19 @@
#include "inputs.h"
#include "expodialog.h"
#include "helpers.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
-InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
expoInserted(false),
modelPrinter(firmware, generalSettings, model),
- commonItemModels(commonItemModels)
+ sharedItemModels(sharedItemModels),
+ modelsUpdateCnt(0)
{
- rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), (RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup), this);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
-
- rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
-
- curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this);
- connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
- connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
+ connectItemModelEvents(AbstractItemModel::IMID_RawSource);
+ connectItemModelEvents(AbstractItemModel::IMID_RawSwitch);
+ connectItemModelEvents(AbstractItemModel::IMID_Curve);
+ connectItemModelEvents(AbstractItemModel::IMID_GVarRef);
inputsCount = firmware->getCapability(VirtualInputs);
if (inputsCount == 0)
@@ -194,7 +188,7 @@ void InputsPanel::gm_openExpo(int index)
if (firmware->getCapability(VirtualInputs))
inputName = model->inputNames[ed.chn];
- ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, rawSourceFilteredModel, rawSwitchFilteredModel, curveFilteredModel);
+ ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, sharedItemModels);
if (dlg->exec()) {
model->expoData[index] = ed;
if (firmware->getCapability(VirtualInputs))
@@ -730,18 +724,31 @@ int InputsPanel::getInputIndexFromSelected()
return idx;
}
-void InputsPanel::onModelDataAboutToBeUpdated()
+void InputsPanel::connectItemModelEvents(const int id)
{
- lock = true;
+ AbstractDynamicItemModel * itemModel = qobject_cast(sharedItemModels->getItemModel(id));
+ if (itemModel) {
+ connect(itemModel, &AbstractDynamicItemModel::aboutToBeUpdated, this, &InputsPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &AbstractDynamicItemModel::updateComplete, this, &InputsPanel::onItemModelUpdateComplete);
+ }
}
-void InputsPanel::onModelDataUpdateComplete()
+void InputsPanel::onItemModelAboutToBeUpdated()
{
- update();
- lock = false;
+ lock = true;
+ modelsUpdateCnt++;
+}
+
+void InputsPanel::onItemModelUpdateComplete()
+{
+ modelsUpdateCnt--;
+ if (modelsUpdateCnt < 1) {
+ update();
+ lock = false;
+ }
}
void InputsPanel::updateItemModels()
{
- commonItemModels->update(CommonItemModels::RMO_INPUTS);
+ sharedItemModels->update(AbstractItemModel::IMUE_Inputs);
}
diff --git a/companion/src/modeledit/inputs.h b/companion/src/modeledit/inputs.h
index ea1243213..9b360ec19 100644
--- a/companion/src/modeledit/inputs.h
+++ b/companion/src/modeledit/inputs.h
@@ -25,8 +25,8 @@
#include "mixerslistwidget.h"
#include "modelprinter.h"
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
constexpr char MIMETYPE_EXPO[] = "application/x-companion-expo";
@@ -35,7 +35,7 @@ class InputsPanel : public ModelPanel
Q_OBJECT
public:
- InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
+ InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~InputsPanel();
virtual void update();
@@ -62,8 +62,8 @@ class InputsPanel : public ModelPanel
void cmInputInsert();
void cmInputMoveDown();
void cmInputMoveUp();
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
bool expoInserted;
@@ -72,10 +72,8 @@ class InputsPanel : public ModelPanel
ModelPrinter modelPrinter;
int selectedIdx;
int inputIdx;
- CommonItemModels * commonItemModels;
- RawItemFilteredModel *rawSourceFilteredModel;
- RawItemFilteredModel *rawSwitchFilteredModel;
- RawItemFilteredModel *curveFilteredModel;
+ CompoundItemModelFactory *sharedItemModels;
+ int modelsUpdateCnt;
int getExpoIndex(unsigned int dch);
bool gm_insertExpo(int idx);
@@ -97,6 +95,7 @@ class InputsPanel : public ModelPanel
int getIndexFromSelected();
int getInputIndexFromSelected();
void updateItemModels();
+ void connectItemModelEvents(const int id);
};
#endif // _INPUTS_H_
diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp
index cacd5c6fd..499df9e49 100644
--- a/companion/src/modeledit/logicalswitches.cpp
+++ b/companion/src/modeledit/logicalswitches.cpp
@@ -19,25 +19,25 @@
*/
#include "logicalswitches.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
#include "helpers.h"
#include
-LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
+ CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
- commonItemModels(commonItemModels),
+ sharedItemModels(sharedItemModels),
selectedIndex(0),
modelsUpdateCnt(0)
{
- rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::LogicalSwitchesContext, this);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete);
+ rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
+ RawSwitch::LogicalSwitchesContext);
+ connectItemModelEvents(rawSwitchFilteredModel);
const int srcGroups = firmware->getCapability(GvarsInCS) ? 0 : (RawSource::AllSourceGroups & ~RawSource::GVarsGroup);
- rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), srcGroups, this);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete);
+ rawSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), srcGroups);
+ connectItemModelEvents(rawSourceFilteredModel);
lsCapability = firmware->getCapability(LogicalSwitches);
lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt);
@@ -161,6 +161,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
LogicalSwitchesPanel::~LogicalSwitchesPanel()
{
+ delete rawSourceFilteredModel;
+ delete rawSwitchFilteredModel;
}
void LogicalSwitchesPanel::onFunctionChanged()
@@ -644,16 +646,22 @@ void LogicalSwitchesPanel::swapData(int idx1, int idx2)
void LogicalSwitchesPanel::updateItemModels()
{
lock = true;
- commonItemModels->update(CommonItemModels::RMO_LOGICAL_SWITCHES);
+ sharedItemModels->update(AbstractItemModel::IMUE_LogicalSwitches);
}
-void LogicalSwitchesPanel::onModelDataAboutToBeUpdated()
+void LogicalSwitchesPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &LogicalSwitchesPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &LogicalSwitchesPanel::onItemModelUpdateComplete);
+}
+
+void LogicalSwitchesPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
-void LogicalSwitchesPanel::onModelDataUpdateComplete()
+void LogicalSwitchesPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
diff --git a/companion/src/modeledit/logicalswitches.h b/companion/src/modeledit/logicalswitches.h
index 87a360408..f1c2f8397 100644
--- a/companion/src/modeledit/logicalswitches.h
+++ b/companion/src/modeledit/logicalswitches.h
@@ -24,8 +24,8 @@
#include "modeledit.h"
#include "radiodata.h"
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
class TimerEdit;
constexpr char MIMETYPE_LOGICAL_SWITCH[] = "application/x-companion-logical-switch";
@@ -35,7 +35,7 @@ class LogicalSwitchesPanel : public ModelPanel
Q_OBJECT
public:
- LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
+ LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~LogicalSwitchesPanel();
virtual void update();
@@ -60,8 +60,8 @@ class LogicalSwitchesPanel : public ModelPanel
void cmInsert();
void cmClear(bool prompt = true);
void cmClearAll();
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES];
@@ -74,9 +74,9 @@ class LogicalSwitchesPanel : public ModelPanel
QDoubleSpinBox * dsbDelay[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource1[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource2[CPN_MAX_LOGICAL_SWITCHES];
- CommonItemModels * commonItemModels;
- RawItemFilteredModel * rawSwitchFilteredModel;
- RawItemFilteredModel * rawSourceFilteredModel;
+ CompoundItemModelFactory * sharedItemModels;
+ FilteredItemModel * rawSwitchFilteredModel;
+ FilteredItemModel * rawSourceFilteredModel;
int selectedIndex;
void populateFunctionCB(QComboBox *b);
void updateTimerParam(QDoubleSpinBox *sb, int timer, double minimum=0);
@@ -89,6 +89,7 @@ class LogicalSwitchesPanel : public ModelPanel
bool moveUpAllowed() const;
int modelsUpdateCnt;
void updateItemModels();
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _LOGICALSWITCHES_H_
diff --git a/companion/src/modeledit/mixerdialog.cpp b/companion/src/modeledit/mixerdialog.cpp
index 00d2badc8..67b01f8f6 100644
--- a/companion/src/modeledit/mixerdialog.cpp
+++ b/companion/src/modeledit/mixerdialog.cpp
@@ -21,11 +21,11 @@
#include "mixerdialog.h"
#include "ui_mixerdialog.h"
#include "radiodata.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
#include "helpers.h"
MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware,
- RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel) :
+ CompoundItemModelFactory * sharedItemModels) :
QDialog(parent),
ui(new Ui::MixerDialog),
model(model),
@@ -36,6 +36,9 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
{
ui->setupUi(this);
+ dialogFilteredItemModels = new FilteredItemModelFactory();
+ int id;
+
QRegExp rx(CHAR_FOR_NAMES_REGEX);
QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 };
QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 };
@@ -45,14 +48,20 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh - 1).toString(&model, &generalSettings)));
- ui->sourceCB->setModel(rawSourceModel);
+ id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
+ ((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup)),
+ "RawSource");
+ ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
int limit = firmware->getCapability(OffsetWeight);
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, md->weight, model, 100, -limit, limit);
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, md->sOffset, model, 0, -limit, limit);
- curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model, curveItemModel, this);
+ curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
+ firmware->getCapability(HasMixerExpo) ? 0 : FilteredItemModel::PositiveFilter);
+ curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model,
+ curveRefFilteredItemModels, this);
ui->MixDR_CB->setChecked(md->noExpo == 0);
@@ -104,7 +113,9 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
}
}
- ui->switchesCB->setModel(rawSwitchModel);
+ id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
+ RawSwitch::MixesContext), "RawSwitch");
+ ui->switchesCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue()));
ui->warningCB->setCurrentIndex(md->mixWarn);
ui->mltpxCB->setCurrentIndex(md->mltpx);
@@ -150,6 +161,7 @@ MixerDialog::~MixerDialog()
delete ui;
delete gvWeightGroup;
delete gvOffsetGroup;
+ delete dialogFilteredItemModels;
}
void MixerDialog::changeEvent(QEvent *e)
diff --git a/companion/src/modeledit/mixerdialog.h b/companion/src/modeledit/mixerdialog.h
index 6d2131de2..04ff1aeaf 100644
--- a/companion/src/modeledit/mixerdialog.h
+++ b/companion/src/modeledit/mixerdialog.h
@@ -25,7 +25,9 @@
#include "eeprominterface.h"
class GVarGroup;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModelFactory;
+class CurveRefFilteredFactory;
class CurveReferenceUIManager;
namespace Ui {
@@ -36,7 +38,7 @@ class MixerDialog : public QDialog {
Q_OBJECT
public:
MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware,
- RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel);
+ CompoundItemModelFactory * sharedItemModels);
~MixerDialog();
protected:
@@ -61,6 +63,8 @@ class MixerDialog : public QDialog {
GVarGroup * gvOffsetGroup;
CurveReferenceUIManager * curveGroup;
QCheckBox * cb_fp[CPN_MAX_FLIGHT_MODES];
+ FilteredItemModelFactory *dialogFilteredItemModels;
+ CurveRefFilteredFactory *curveRefFilteredItemModels;
};
#endif // _MIXERDIALOG_H_
diff --git a/companion/src/modeledit/mixes.cpp b/companion/src/modeledit/mixes.cpp
index f02a57417..3d95bd04d 100644
--- a/companion/src/modeledit/mixes.cpp
+++ b/companion/src/modeledit/mixes.cpp
@@ -20,26 +20,20 @@
#include "mixes.h"
#include "helpers.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
-MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,CommonItemModels * commonItemModels):
+MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
mixInserted(false),
highlightedSource(0),
modelPrinter(firmware, generalSettings, model),
- commonItemModels(commonItemModels)
+ sharedItemModels(sharedItemModels),
+ modelsUpdateCnt(0)
{
- rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), ((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup), this);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
- connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
-
- rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
-
- curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this);
- connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
- connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
+ connectItemModelEvents(AbstractItemModel::IMID_RawSource);
+ connectItemModelEvents(AbstractItemModel::IMID_RawSwitch);
+ connectItemModelEvents(AbstractItemModel::IMID_Curve);
+ connectItemModelEvents(AbstractItemModel::IMID_GVarRef);
QGridLayout * mixesLayout = new QGridLayout(this);
@@ -189,7 +183,7 @@ void MixesPanel::gm_openMix(int index)
MixData mixd(model->mixData[index]);
- MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, rawSourceFilteredModel, rawSwitchFilteredModel, curveFilteredModel);
+ MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, sharedItemModels);
if(dlg->exec()) {
model->mixData[index] = mixd;
emit modified();
@@ -545,13 +539,26 @@ void MixesPanel::clearMixes()
}
}
-void MixesPanel::onModelDataAboutToBeUpdated()
+void MixesPanel::connectItemModelEvents(const int id)
{
- lock = true;
+ AbstractDynamicItemModel * itemModel = qobject_cast(sharedItemModels->getItemModel(id));
+ if (itemModel) {
+ connect(itemModel, &AbstractDynamicItemModel::aboutToBeUpdated, this, &MixesPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &AbstractDynamicItemModel::updateComplete, this, &MixesPanel::onItemModelUpdateComplete);
+ }
}
-void MixesPanel::onModelDataUpdateComplete()
+void MixesPanel::onItemModelAboutToBeUpdated()
{
- update();
- lock = false;
+ lock = true;
+ modelsUpdateCnt++;
+}
+
+void MixesPanel::onItemModelUpdateComplete()
+{
+ modelsUpdateCnt--;
+ if (modelsUpdateCnt < 1) {
+ update();
+ lock = false;
+ }
}
diff --git a/companion/src/modeledit/mixes.h b/companion/src/modeledit/mixes.h
index 014786b74..c298df11a 100644
--- a/companion/src/modeledit/mixes.h
+++ b/companion/src/modeledit/mixes.h
@@ -26,15 +26,15 @@
#include "mixerdialog.h"
#include "modelprinter.h"
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
class MixesPanel : public ModelPanel
{
Q_OBJECT
public:
- MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
+ MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~MixesPanel();
virtual void update();
@@ -60,18 +60,16 @@ class MixesPanel : public ModelPanel
void mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action);
void pasteMixerMimeData(const QMimeData * mimeData, int destIdx);
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
MixersListWidget * mixersListWidget;
bool mixInserted;
unsigned int highlightedSource;
ModelPrinter modelPrinter;
- CommonItemModels * commonItemModels;
- RawItemFilteredModel *rawSourceFilteredModel;
- RawItemFilteredModel *rawSwitchFilteredModel;
- RawItemFilteredModel *curveFilteredModel;
+ CompoundItemModelFactory *sharedItemModels;
+ int modelsUpdateCnt;
int getMixerIndex(unsigned int dch);
bool gm_insertMix(int idx);
@@ -83,6 +81,7 @@ class MixesPanel : public ModelPanel
void setSelectedByMixList(QList list);
void AddMixerLine(int dest);
QString getMixerText(int dest, bool newChannel);
+ void connectItemModelEvents(const int id);
};
#endif // _MIXES_H_
diff --git a/companion/src/modeledit/modeledit.cpp b/companion/src/modeledit/modeledit.cpp
index 41989ba53..3577be7ae 100644
--- a/companion/src/modeledit/modeledit.cpp
+++ b/companion/src/modeledit/modeledit.cpp
@@ -33,7 +33,7 @@
#include "customfunctions.h"
#include "telemetry.h"
#include "appdata.h"
-#include "rawitemdatamodels.h"
+#include "compounditemmodels.h"
ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) :
QDialog(parent),
@@ -53,42 +53,53 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
GeneralSettings &generalSettings = radioData.generalSettings;
ModelData &model = radioData.models[modelId];
- commonItemModels = new CommonItemModels(&generalSettings, &model, this);
+ sharedItemModels = new CompoundItemModelFactory(&generalSettings, &model);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSource);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSwitch);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_Curve);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_GVarRef);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_ThrSource);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_TeleSource);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefType);
+ sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefFunc);
+
s1.report("Init");
- SetupPanel * setupPanel = new SetupPanel(this, model, generalSettings, firmware, commonItemModels);
+ SetupPanel * setupPanel = new SetupPanel(this, model, generalSettings, firmware, sharedItemModels);
addTab(setupPanel, tr("Setup"));
s1.report("Setup");
if (firmware->getCapability(Heli)) {
- addTab(new HeliPanel(this, model, generalSettings, firmware, commonItemModels), tr("Heli"));
+ addTab(new HeliPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Heli"));
s1.report("Heli");
}
- addTab(new FlightModesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Flight Modes"));
+ addTab(new FlightModesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Flight Modes"));
s1.report("Flight Modes");
- addTab(new InputsPanel(this, model, generalSettings, firmware, commonItemModels), tr("Inputs"));
+ addTab(new InputsPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Inputs"));
s1.report("Inputs");
- addTab(new MixesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Mixes"));
+ addTab(new MixesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Mixes"));
s1.report("Mixes");
- ChannelsPanel * channelsPanel = new ChannelsPanel(this, model, generalSettings, firmware, commonItemModels);
+ ChannelsPanel * channelsPanel = new ChannelsPanel(this, model, generalSettings, firmware, sharedItemModels);
addTab(channelsPanel, tr("Outputs"));
s1.report("Outputs");
- addTab(new CurvesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Curves"));
+ addTab(new CurvesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Curves"));
s1.report("Curves");
- addTab(new LogicalSwitchesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Logical Switches"));
+ addTab(new LogicalSwitchesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Logical Switches"));
s1.report("Logical Switches");
- addTab(new CustomFunctionsPanel(this, &model, generalSettings, firmware, commonItemModels), tr("Special Functions"));
+ addTab(new CustomFunctionsPanel(this, &model, generalSettings, firmware, sharedItemModels), tr("Special Functions"));
s1.report("Special Functions");
if (firmware->getCapability(Telemetry)) {
- addTab(new TelemetryPanel(this, model, generalSettings, firmware, commonItemModels), tr("Telemetry"));
+ addTab(new TelemetryPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Telemetry"));
s1.report("Telemetry");
}
@@ -104,6 +115,7 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
ModelEdit::~ModelEdit()
{
delete ui;
+ delete sharedItemModels;
}
void ModelEdit::closeEvent(QCloseEvent *event)
diff --git a/companion/src/modeledit/modeledit.h b/companion/src/modeledit/modeledit.h
index 9095101bf..0bd4af9d8 100644
--- a/companion/src/modeledit/modeledit.h
+++ b/companion/src/modeledit/modeledit.h
@@ -25,7 +25,7 @@
#include "genericpanel.h"
class RadioData;
-class CommonItemModels;
+class CompoundItemModelFactory;
namespace Ui {
class ModelEdit;
@@ -60,12 +60,12 @@ class ModelEdit : public QDialog
private:
Ui::ModelEdit *ui;
int modelId;
- RadioData & radioData;
- Firmware * firmware;
+ RadioData &radioData;
+ Firmware *firmware;
QVector panels;
- CommonItemModels * commonItemModels;
+ CompoundItemModelFactory *sharedItemModels;
- void addTab(GenericPanel *panel, QString text);
+ void addTab(GenericPanel * panel, QString text);
void launchSimulation();
};
diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp
index e4f67178d..25cd576ec 100644
--- a/companion/src/modeledit/setup.cpp
+++ b/companion/src/modeledit/setup.cpp
@@ -22,7 +22,7 @@
#include "ui_setup.h"
#include "ui_setup_timer.h"
#include "ui_setup_module.h"
-#include "rawitemfilteredmodel.h"
+#include "filtereditemmodels.h"
#include "appdata.h"
#include "modelprinter.h"
#include "multiprotocols.h"
@@ -31,14 +31,14 @@
#include
-TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawItemFilteredModel * rawSwitchFilteredModel):
+TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
+ QWidget * prevFocus, FilteredItemModel * rawSwitchFilteredModel):
ModelPanel(parent, model, generalSettings, firmware),
timer(timer),
ui(new Ui::Timer)
{
ui->setupUi(this);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TimerPanel::onModelDataAboutToBeUpdated);
- connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &TimerPanel::onModelDataUpdateComplete);
+ connectItemModelEvents(rawSwitchFilteredModel);
lock = true;
@@ -172,12 +172,18 @@ void TimerPanel::on_name_editingFinished()
}
}
-void TimerPanel::onModelDataAboutToBeUpdated()
+void TimerPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TimerPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &TimerPanel::onItemModelUpdateComplete);
+}
+
+void TimerPanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
-void TimerPanel::onModelDataUpdateComplete()
+void TimerPanel::onItemModelUpdateComplete()
{
update();
lock = false;
@@ -991,13 +997,19 @@ void ModulePanel::onClearAccessRxClicked()
/******************************************************************************/
-SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
+ CompoundItemModelFactory * sharedItemModels) :
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Setup),
- commonItemModels(commonItemModels)
+ sharedItemModels(sharedItemModels)
{
ui->setupUi(this);
- rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::TimersContext, this);
+
+ rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::TimersContext);
+ connectItemModelEvents(rawSwitchFilteredModel);
+
+ thrSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_ThrSource));
+ connectItemModelEvents(thrSourceFilteredModel);
Board::Type board = firmware->getBoard();
@@ -1248,6 +1260,8 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
SetupPanel::~SetupPanel()
{
delete ui;
+ delete rawSwitchFilteredModel;
+ delete thrSourceFilteredModel;
}
void SetupPanel::on_extendedLimits_toggled(bool checked)
@@ -1750,7 +1764,21 @@ void SetupPanel::onTimerNameChanged()
updateItemModels();
}
+void SetupPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &SetupPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &SetupPanel::onItemModelUpdateComplete);
+}
+
+void SetupPanel::onItemModelAboutToBeUpdated()
+{
+}
+
+void SetupPanel::onItemModelUpdateComplete()
+{
+}
+
void SetupPanel::updateItemModels()
{
- commonItemModels->update(CommonItemModels::RMO_TIMERS);
+ sharedItemModels->update(AbstractItemModel::IMUE_Timers);
}
diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h
index c56e63ea1..c931f9dd7 100644
--- a/companion/src/modeledit/setup.h
+++ b/companion/src/modeledit/setup.h
@@ -26,8 +26,8 @@
constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer";
-class CommonItemModels;
-class RawItemFilteredModel;
+class CompoundItemModelFactory;
+class FilteredItemModel;
namespace Ui {
class Setup;
@@ -40,7 +40,8 @@ class TimerPanel : public ModelPanel
Q_OBJECT
public:
- TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawItemFilteredModel * switchModel);
+ TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
+ QWidget *prevFocus, FilteredItemModel * switchModel);
virtual ~TimerPanel();
virtual void update();
@@ -51,8 +52,8 @@ class TimerPanel : public ModelPanel
void on_value_editingFinished();
void on_minuteBeep_toggled(bool checked);
void on_name_editingFinished();
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
signals:
void nameChanged();
@@ -60,6 +61,7 @@ class TimerPanel : public ModelPanel
private:
TimerData & timer;
Ui::Timer * ui;
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class ModulePanel : public ModelPanel
@@ -131,7 +133,7 @@ class SetupPanel : public ModelPanel
Q_OBJECT
public:
- SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
+ SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~SetupPanel();
virtual void update();
@@ -170,6 +172,8 @@ class SetupPanel : public ModelPanel
void cmTimerMoveDown();
void cmTimerMoveUp();
void onTimerNameChanged();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
Ui::Setup *ui;
@@ -191,9 +195,11 @@ class SetupPanel : public ModelPanel
bool moveTimerDownAllowed() const;
bool moveTimerUpAllowed() const;
void swapTimerData(int idx1, int idx2);
- CommonItemModels * commonItemModels;
- RawItemFilteredModel * rawSwitchFilteredModel;
+ CompoundItemModelFactory * sharedItemModels;
+ FilteredItemModel * rawSwitchFilteredModel;
+ FilteredItemModel * thrSourceFilteredModel;
void updateItemModels();
- };
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
+};
#endif // _SETUP_H_
diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp
index e980c3943..423e10e5d 100644
--- a/companion/src/modeledit/telemetry.cpp
+++ b/companion/src/modeledit/telemetry.cpp
@@ -24,24 +24,36 @@
#include "ui_telemetry_sensor.h"
#include "helpers.h"
#include "appdata.h"
-#include "rawitemfilteredmodel.h"
#include
-TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel):
+constexpr char FIM_RAWSOURCE[] {"Raw Source"};
+constexpr char FIM_TELEALLSRC[] {"Tele All Source"};
+constexpr char FIM_TELEPOSSRC[] {"Tele Pos Source"};
+constexpr char FIM_SENSORTYPE[] {"Sensor.Type"};
+constexpr char FIM_SENSORFORMULA[] {"Sensor.Formula"};
+constexpr char FIM_SENSORCELLINDEX[] {"Sensor.CellIndex"};
+constexpr char FIM_SENSORUNIT[] {"Sensor.Unit"};
+constexpr char FIM_SENSORPRECISION[] {"Sensor.Precision"};
+
+TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings,
+ Firmware * firmware, const bool & parentLock, FilteredItemModelFactory * panelFilteredItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetryCustomScreen),
- screen(screen)
+ screen(screen),
+ modelsUpdateCnt(0),
+ parentLock(parentLock)
{
ui->setupUi(this);
- connect(rawSourceModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TelemetryCustomScreen::onModelDataAboutToBeUpdated);
- connect(rawSourceModel, &RawItemFilteredModel::dataUpdateComplete, this, &TelemetryCustomScreen::onModelDataUpdateComplete);
+
+ FilteredItemModel * rawSourceFilteredModel = panelFilteredItemModels->getItemModel(FIM_RAWSOURCE);
+ connectItemModelEvents(rawSourceFilteredModel);
for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) {
for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) {
fieldsCB[l][c] = new QComboBox(this);
fieldsCB[l][c]->setProperty("index", c + (l << 8));
- fieldsCB[l][c]->setModel(rawSourceModel);
+ fieldsCB[l][c]->setModel(rawSourceFilteredModel);
ui->screenNumsLayout->addWidget(fieldsCB[l][c], l, c, 1, 1);
connect(fieldsCB[l][c], SIGNAL(activated(int)), this, SLOT(customFieldChanged(int)));
}
@@ -50,7 +62,7 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model,
for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) {
barsCB[l] = new QComboBox(this);
barsCB[l]->setProperty("index", l);
- barsCB[l]->setModel(rawSourceModel);
+ barsCB[l]->setModel(rawSourceFilteredModel);
connect(barsCB[l], SIGNAL(activated(int)), this, SLOT(barSourceChanged(int)));
ui->screenBarsLayout->addWidget(barsCB[l], l, 0, 1, 1);
@@ -203,7 +215,7 @@ void TelemetryCustomScreen::updateBar(int line)
void TelemetryCustomScreen::on_screenType_currentIndexChanged(int index)
{
- if (!lock) {
+ if (!isLocked()) {
memset(reinterpret_cast(&screen.body), 0, sizeof(screen.body));
update();
emit modified();
@@ -212,7 +224,7 @@ void TelemetryCustomScreen::on_screenType_currentIndexChanged(int index)
void TelemetryCustomScreen::scriptNameEdited()
{
- if (!lock) {
+ if (!isLocked()) {
lock = true;
Helpers::getFileComboBoxValue(ui->scriptName, screen.body.script.filename, 8);
emit modified();
@@ -222,7 +234,7 @@ void TelemetryCustomScreen::scriptNameEdited()
void TelemetryCustomScreen::customFieldChanged(int value)
{
- if (lock || !sender() || !qobject_cast(sender()))
+ if (isLocked() || !sender() || !qobject_cast(sender()))
return;
bool ok;
@@ -238,7 +250,7 @@ void TelemetryCustomScreen::customFieldChanged(int value)
void TelemetryCustomScreen::barSourceChanged(int value)
{
- if (lock || !sender() || !qobject_cast(sender()))
+ if (isLocked() || !sender() || !qobject_cast(sender()))
return;
bool ok;
@@ -256,7 +268,7 @@ void TelemetryCustomScreen::barSourceChanged(int value)
void TelemetryCustomScreen::barMinChanged(double value)
{
- if (!lock) {
+ if (!isLocked()) {
int line = sender()->property("index").toInt();
screen.body.bars[line].barMin = round(value / minSB[line]->singleStep());
// TODO set min (maxSB)
@@ -266,7 +278,7 @@ void TelemetryCustomScreen::barMinChanged(double value)
void TelemetryCustomScreen::barMaxChanged(double value)
{
- if (!lock) {
+ if (!isLocked()) {
int line = sender()->property("index").toInt();
screen.body.bars[line].barMax = round((value) / maxSB[line]->singleStep());
// TODO set max (minSB)
@@ -276,7 +288,7 @@ void TelemetryCustomScreen::barMaxChanged(double value)
void TelemetryCustomScreen::barTimeChanged()
{
- if (!lock) {
+ if (!isLocked()) {
int line = sender()->property("index").toInt();
int & valRef = (sender()->property("type").toString() == "min" ? screen.body.bars[line].barMin : screen.body.bars[line].barMax);
TimerEdit * te = qobject_cast(sender());
@@ -289,29 +301,51 @@ void TelemetryCustomScreen::barTimeChanged()
}
}
-void TelemetryCustomScreen::onModelDataAboutToBeUpdated()
+void TelemetryCustomScreen::connectItemModelEvents(const FilteredItemModel * itemModel)
{
- lock = true;
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TelemetryCustomScreen::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &TelemetryCustomScreen::onItemModelUpdateComplete);
}
-void TelemetryCustomScreen::onModelDataUpdateComplete()
+void TelemetryCustomScreen::onItemModelAboutToBeUpdated()
{
- update();
- lock = false;
+ lock = true;
+ modelsUpdateCnt++;
+}
+
+void TelemetryCustomScreen::onItemModelUpdateComplete()
+{
+ modelsUpdateCnt--;
+ if (modelsUpdateCnt < 1) {
+ // leave updating to parent
+ lock = false;
+ }
}
/******************************************************/
-TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
+TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model,
+ GeneralSettings & generalSettings, Firmware * firmware, const bool & parentLock,
+ FilteredItemModelFactory * panelFilteredItemModels) :
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetrySensor),
sensor(sensor),
- lock(false),
sensorIndex(sensorIndex),
selectedIndex(0),
- sensorCapability(sensorCapability)
+ sensorCapability(sensorCapability),
+ modelsUpdateCnt(0),
+ parentLock(parentLock)
{
+ // TODO ui definition housekeeping
+ // - remove all predefined combobox lists leaving to code
+ // - use Auto types for consistency
ui->setupUi(this);
+ FilteredItemModel * fltmdl;
+
+ connectItemModelEvents(panelFilteredItemModels->getItemModel(FIM_TELEALLSRC));
+ connectItemModelEvents(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
+
+ lock = true;
ui->numLabel->setText(tr("TELE%1").arg(sensorIndex + 1));
ui->numLabel->setProperty("index", sensorIndex);
ui->numLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
@@ -326,6 +360,9 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor,
connect(ui->numLabel, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(on_customContextMenuRequested(QPoint)));
ui->id->setField(sensor.id, this);
ui->instance->setField(sensor.instance, this);
+ ui->type->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORTYPE));
+ ui->formula->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORFORMULA));
+ ui->unit->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORUNIT));
ui->ratio->setField(sensor.ratio, this);
ui->offset->setField(sensor.offset, this);
ui->autoOffset->setField(sensor.autoOffset, this);
@@ -333,21 +370,29 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor,
ui->logs->setField(sensor.logs, this);
ui->persistent->setField(sensor.persistent, this);
ui->onlyPositive->setField(sensor.onlyPositive, this);
+ fltmdl = panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC);
+ ui->gpsSensor->setModel(fltmdl);
ui->gpsSensor->setField(sensor.gps, this);
+ ui->altSensor->setModel(fltmdl);
ui->altSensor->setField(sensor.alt, this);
+ ui->ampsSensor->setModel(fltmdl);
ui->ampsSensor->setField(sensor.amps, this);
+ ui->cellsSensor->setModel(fltmdl);
ui->cellsSensor->setField(sensor.source, this);
- ui->cellsIndex->addItem(tr("Lowest"), SensorData::TELEM_CELL_INDEX_LOWEST);
- for (int i = SensorData::TELEM_CELL_INDEX_LOWEST + 1; i < SensorData::TELEM_CELL_INDEX_HIGHEST; i++)
- ui->cellsIndex->addItem(tr("Cell %1").arg(i), i);
- ui->cellsIndex->addItem(tr("Highest"), SensorData::TELEM_CELL_INDEX_HIGHEST);
- ui->cellsIndex->addItem(tr("Delta"), SensorData::TELEM_CELL_INDEX_DELTA);
+ ui->cellsIndex->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORCELLINDEX));
ui->cellsIndex->setField(sensor.index);
+ fltmdl = panelFilteredItemModels->getItemModel(FIM_TELEALLSRC);
+ ui->source1->setModel(fltmdl);
ui->source1->setField(sensor.sources[0], this);
+ ui->source2->setModel(fltmdl);
ui->source2->setField(sensor.sources[1], this);
+ ui->source3->setModel(fltmdl);
ui->source3->setField(sensor.sources[2], this);
+ ui->source4->setModel(fltmdl);
ui->source4->setField(sensor.sources[3], this);
- ui->prec->setField(sensor.prec, 0, 2, false, "", this);
+ ui->prec->setField(sensor.prec, 0, 2, false, "", this); // TODO replace autoprecisioncombobox with autocombobox and filtereditemmodel
+ lock = false;
+
update();
}
@@ -358,6 +403,7 @@ TelemetrySensorPanel::~TelemetrySensorPanel()
void TelemetrySensorPanel::update()
{
+ // TODO use bit mask
bool isConfigurable = false;
bool gpsFieldsDisplayed = false;
bool cellsFieldsDisplayed = false;
@@ -369,8 +415,8 @@ void TelemetrySensorPanel::update()
lock = true;
ui->name->setText(sensor.label);
- ui->type->setCurrentIndex(sensor.type);
- ui->unit->setCurrentIndex(sensor.unit);
+ ui->type->setCurrentIndex(ui->type->findData(sensor.type));
+ ui->unit->setCurrentIndex(ui->unit->findData(sensor.unit));
ui->id->updateValue();
ui->instance->updateValue();
ui->ratio->updateValue();
@@ -396,7 +442,7 @@ void TelemetrySensorPanel::update()
ui->originLabel->hide();
ui->origin->hide();
ui->formula->show();
- ui->formula->setCurrentIndex(sensor.formula);
+ ui->formula->setCurrentIndex(ui->formula->findData(sensor.formula));
isConfigurable = (sensor.formula < SensorData::TELEM_FORMULA_CELL);
gpsFieldsDisplayed = (sensor.formula == SensorData::TELEM_FORMULA_DIST);
cellsFieldsDisplayed = (sensor.formula == SensorData::TELEM_FORMULA_CELL);
@@ -404,14 +450,10 @@ void TelemetrySensorPanel::update()
sources12FieldsDisplayed = (sensor.formula <= SensorData::TELEM_FORMULA_MULTIPLY);
sources34FieldsDisplayed = (sensor.formula < SensorData::TELEM_FORMULA_MULTIPLY);
totalizeFieldsDisplayed = (sensor.formula == SensorData::TELEM_FORMULA_TOTALIZE);
- updateSourcesComboBox(ui->source1, true);
- updateSourcesComboBox(ui->source2, true);
- updateSourcesComboBox(ui->source3, true);
- updateSourcesComboBox(ui->source4, true);
- updateSourcesComboBox(ui->gpsSensor, false);
- updateSourcesComboBox(ui->altSensor, false);
- updateSourcesComboBox(ui->ampsSensor, false);
- updateSourcesComboBox(ui->cellsSensor, false);
+ ui->source1->updateValue();
+ ui->source2->updateValue();
+ ui->source3->updateValue();
+ ui->source4->updateValue();
}
else {
ui->idLabel->show();
@@ -483,40 +525,9 @@ void TelemetrySensorPanel::update()
lock = false;
}
-void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model, bool negative)
-{
- cb->clear();
- if (negative) {
- for (int i = -CPN_MAX_SENSORS; i < 0; ++i) {
- const SensorData& sensor = model->sensorData[-i - 1];
- if (sensor.isAvailable()) {
- if (sensor.type == SensorData::TELEM_TYPE_CUSTOM)
- cb->addItem(QString("-%1 (%2)").arg(sensor.label, sensor.getOrigin(model)), i);
- else
- cb->addItem(QString("-%1").arg(sensor.label), i);
- }
- }
- }
- cb->addItem("---", 0);
- for (unsigned i = 1; i <= CPN_MAX_SENSORS; ++i) {
- const SensorData& sensor = model->sensorData[i-1];
- if (sensor.isAvailable()) {
- if (sensor.type == SensorData::TELEM_TYPE_CUSTOM)
- cb->addItem(QString("%1 (%2)").arg(sensor.label, sensor.getOrigin(model)), i);
- else
- cb->addItem(QString("%1").arg(sensor.label), i);
- }
- }
-}
-
-void TelemetrySensorPanel::updateSourcesComboBox(AutoComboBox * cb, bool negative)
-{
- populateTelemetrySourcesComboBox(cb, model, negative);
-}
-
void TelemetrySensorPanel::on_name_editingFinished()
{
- if (!lock) {
+ if (!isLocked() && (sensor.label != ui->name->text().toLatin1())) {
strcpy(sensor.label, ui->name->text().toLatin1());
emit dataModified();
}
@@ -524,8 +535,8 @@ void TelemetrySensorPanel::on_name_editingFinished()
void TelemetrySensorPanel::on_type_currentIndexChanged(int index)
{
- if (!lock) {
- sensor.type = index;
+ if (!isLocked()) {
+ sensor.type = ui->type->itemData(index).toInt();
update();
emit modified();
}
@@ -533,8 +544,8 @@ void TelemetrySensorPanel::on_type_currentIndexChanged(int index)
void TelemetrySensorPanel::on_formula_currentIndexChanged(int index)
{
- if (!lock) {
- sensor.formula = index;
+ if (!isLocked()) {
+ sensor.formula = ui->formula->itemData(index).toInt();
if (sensor.formula == SensorData::TELEM_FORMULA_CELL) {
sensor.prec = 2;
sensor.unit = SensorData::UNIT_VOLTS;
@@ -553,8 +564,8 @@ void TelemetrySensorPanel::on_formula_currentIndexChanged(int index)
void TelemetrySensorPanel::on_unit_currentIndexChanged(int index)
{
- if (!lock) {
- sensor.unit = index;
+ if (!isLocked()) {
+ sensor.unit = ui->unit->itemData(index).toInt();
if (sensor.unit == SensorData::UNIT_FAHRENHEIT) {
sensor.prec = 0;
}
@@ -565,7 +576,7 @@ void TelemetrySensorPanel::on_unit_currentIndexChanged(int index)
void TelemetrySensorPanel::on_prec_valueChanged()
{
- if (!lock) {
+ if (!isLocked()) {
update();
}
}
@@ -686,15 +697,69 @@ void TelemetrySensorPanel::cmMoveDown()
emit moveDownSensor(selectedIndex);
}
+void TelemetrySensorPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
+{
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TelemetrySensorPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &TelemetrySensorPanel::onItemModelUpdateComplete);
+}
+
+void TelemetrySensorPanel::onItemModelAboutToBeUpdated()
+{
+ lock = true;
+ modelsUpdateCnt++;
+}
+
+void TelemetrySensorPanel::onItemModelUpdateComplete()
+{
+ modelsUpdateCnt--;
+ if (modelsUpdateCnt < 1) {
+ // leave updating to parent
+ lock = false;
+ }
+}
+
/******************************************************/
-TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
+TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
+ CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Telemetry),
- commonItemModels(commonItemModels)
+ sharedItemModels(sharedItemModels),
+ modelsUpdateCnt(0)
{
ui->setupUi(this);
- rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this);
+
+ panelItemModels = new CompoundItemModelFactory(&generalSettings, &model);
+ panelFilteredItemModels = new FilteredItemModelFactory();
+ int id;
+
+ id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource)),
+ FIM_RAWSOURCE);
+ connectItemModelEvents(id);
+
+ id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_TeleSource)),
+ FIM_TELEALLSRC);
+ connectItemModelEvents(id);
+
+ id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_TeleSource),
+ FilteredItemModel::PositiveFilter),
+ FIM_TELEPOSSRC);
+ connectItemModelEvents(id);
+
+ id = panelItemModels->registerItemModel(SensorData::typeItemModel());
+ panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORTYPE);
+
+ id = panelItemModels->registerItemModel(SensorData::formulaItemModel());
+ panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORFORMULA);
+
+ id = panelItemModels->registerItemModel(SensorData::cellIndexItemModel());
+ panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORCELLINDEX);
+
+ id = panelItemModels->registerItemModel(SensorData::unitItemModel());
+ panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORUNIT);
+
+ id = panelItemModels->registerItemModel(SensorData::precisionItemModel());
+ panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORPRECISION);
sensorCapability = firmware->getCapability(Sensors);
if (sensorCapability > CPN_MAX_SENSORS) // TODO should be role of getCapability
@@ -704,13 +769,15 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
model.frsky.usrProto = 1;
}
+ ui->varioSource->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->varioSource->setField(model.frsky.varioSource, this);
ui->varioCenterSilent->setField(model.frsky.varioCenterSilent, this);
ui->A1GB->hide();
ui->A2GB->hide();
for (int i = 0; i < sensorCapability; ++i) {
- TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware);
+ TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings,
+ firmware, lock, panelFilteredItemModels);
ui->sensorsLayout->addWidget(panel);
sensorPanels[i] = panel;
connect(panel, SIGNAL(dataModified()), this, SLOT(on_dataModifiedSensor()));
@@ -723,7 +790,9 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
}
if (IS_TARANIS_X9(firmware->getBoard())) {
+ ui->voltsSource->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->voltsSource->setField(model.frsky.voltsSource, this);
+ ui->altitudeSource->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->altitudeSource->setField(model.frsky.altitudeSource, this);
}
else {
@@ -731,7 +800,8 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
}
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) {
- TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, rawSourceFilteredModel);
+ TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, lock,
+ panelFilteredItemModels);
ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i + 1));
telemetryCustomScreens[i] = tab;
connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified);
@@ -745,10 +815,14 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
TelemetryPanel::~TelemetryPanel()
{
delete ui;
+ delete panelFilteredItemModels;
+ delete panelItemModels;
}
void TelemetryPanel::update()
{
+ lock = true;
+
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
if (model->moduleData[0].protocol == PULSES_OFF && model->moduleData[1].protocol == PULSES_PPM) {
ui->telemetryProtocol->setEnabled(true);
@@ -758,10 +832,10 @@ void TelemetryPanel::update()
ui->telemetryProtocol->setCurrentIndex(0);
}
- populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
- populateTelemetrySourcesComboBox(ui->voltsSource, model, false);
- populateTelemetrySourcesComboBox(ui->altitudeSource, model, false);
- populateTelemetrySourcesComboBox(ui->varioSource, model, false);
+ ui->rssiSourceCB->updateValue();
+ ui->voltsSource->updateValue();
+ ui->altitudeSource->updateValue();
+ ui->varioSource->updateValue();
}
for (int i = 0; i < sensorCapability; ++i) {
@@ -771,6 +845,8 @@ void TelemetryPanel::update()
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) {
telemetryCustomScreens[i]->update();
}
+
+ lock = false;
}
void TelemetryPanel::setup()
@@ -792,9 +868,9 @@ void TelemetryPanel::setup()
ui->rssiSourceLabel->show();
ui->rssiSourceLabel->setText(tr("Source"));
+ ui->rssiSourceCB->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->rssiSourceCB->setField(model->rssiSource, this);
ui->rssiSourceCB->show();
- populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
ui->rssiAlarmWarningCB->hide();
ui->rssiAlarmCriticalCB->hide();
@@ -842,44 +918,9 @@ void TelemetryPanel::setup()
lock = false;
}
-void TelemetryPanel::populateVarioSource()
-{
- AutoComboBox * cb = ui->varioSource;
- cb->setField(model->frsky.varioSource, this);
- cb->addItem(tr("Alti"), TELEMETRY_VARIO_SOURCE_ALTI);
- cb->addItem(tr("Alti+"), TELEMETRY_VARIO_SOURCE_ALTI_PLUS);
- cb->addItem(tr("VSpeed"), TELEMETRY_VARIO_SOURCE_VSPEED);
- cb->addItem(tr("A1"), TELEMETRY_VARIO_SOURCE_A1);
- cb->addItem(tr("A2"), TELEMETRY_VARIO_SOURCE_A2);
-}
-
-void TelemetryPanel::populateVoltsSource()
-{
- AutoComboBox * cb = ui->frskyVoltCB;
- cb->setField(model->frsky.voltsSource, this);
- cb->addItem(tr("A1"), TELEMETRY_VOLTS_SOURCE_A1);
- cb->addItem(tr("A2"), TELEMETRY_VOLTS_SOURCE_A2);
- cb->addItem(tr("A3"), TELEMETRY_VOLTS_SOURCE_A3);
- cb->addItem(tr("A4"), TELEMETRY_VOLTS_SOURCE_A4);
- cb->addItem(tr("FAS"), TELEMETRY_VOLTS_SOURCE_FAS);
- cb->addItem(tr("Cells"), TELEMETRY_VOLTS_SOURCE_CELLS);
-}
-
-void TelemetryPanel::populateCurrentSource()
-{
- AutoComboBox * cb = ui->frskyCurrentCB;
- cb->setField(model->frsky.currentSource, this);
- cb->addItem(tr("---"), TELEMETRY_CURRENT_SOURCE_NONE);
- cb->addItem(tr("A1"), TELEMETRY_CURRENT_SOURCE_A1);
- cb->addItem(tr("A2"), TELEMETRY_CURRENT_SOURCE_A2);
- cb->addItem(tr("A3"), TELEMETRY_CURRENT_SOURCE_A3);
- cb->addItem(tr("A4"), TELEMETRY_CURRENT_SOURCE_A4);
- cb->addItem(tr("FAS"), TELEMETRY_CURRENT_SOURCE_FAS);
-}
-
void TelemetryPanel::on_telemetryProtocol_currentIndexChanged(int index)
{
- if (!lock) {
+ if (!isLocked()) {
model->telemetryProtocol = index;
emit modified();
}
@@ -892,7 +933,7 @@ void TelemetryPanel::onModified()
void TelemetryPanel::on_bladesCount_editingFinished()
{
- if (!lock) {
+ if (!isLocked()) {
model->frsky.blades = ui->bladesCount->value();
emit modified();
}
@@ -900,7 +941,7 @@ void TelemetryPanel::on_bladesCount_editingFinished()
void TelemetryPanel::on_frskyProtoCB_currentIndexChanged(int index)
{
- if (!lock) {
+ if (!isLocked()) {
model->frsky.usrProto = index;
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++)
telemetryCustomScreens[i]->update();
@@ -910,31 +951,39 @@ void TelemetryPanel::on_frskyProtoCB_currentIndexChanged(int index)
void TelemetryPanel::on_rssiAlarmWarningSB_editingFinished()
{
- model->rssiAlarms.warning= ui->rssiAlarmWarningSB->value();
- emit modified();
+ if (!isLocked()) {
+ model->rssiAlarms.warning= ui->rssiAlarmWarningSB->value();
+ emit modified();
+ }
}
void TelemetryPanel::on_rssiAlarmCriticalSB_editingFinished()
{
- model->rssiAlarms.critical = ui->rssiAlarmCriticalSB->value();
- emit modified();
+ if (!isLocked()) {
+ model->rssiAlarms.critical = ui->rssiAlarmCriticalSB->value();
+ emit modified();
+ }
}
void TelemetryPanel::on_varioLimitMin_DSB_editingFinished()
{
- model->frsky.varioMin = round(ui->varioLimitMin_DSB->value() + 10);
- emit modified();
+ if (!isLocked()) {
+ model->frsky.varioMin = round(ui->varioLimitMin_DSB->value() + 10);
+ emit modified();
+ }
}
void TelemetryPanel::on_varioLimitMax_DSB_editingFinished()
{
- model->frsky.varioMax = round(ui->varioLimitMax_DSB->value() - 10);
- emit modified();
+ if (!isLocked()) {
+ model->frsky.varioMax = round(ui->varioLimitMax_DSB->value() - 10);
+ emit modified();
+ }
}
void TelemetryPanel::on_varioLimitCenterMin_DSB_editingFinished()
{
- if (!lock) {
+ if (!isLocked()) {
if (ui->varioLimitCenterMin_DSB->value() > ui->varioLimitCenterMax_DSB->value()) {
ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value());
}
@@ -945,7 +994,7 @@ void TelemetryPanel::on_varioLimitCenterMin_DSB_editingFinished()
void TelemetryPanel::on_varioLimitCenterMax_DSB_editingFinished()
{
- if (!lock) {
+ if (!isLocked()) {
if (ui->varioLimitCenterMin_DSB->value() > ui->varioLimitCenterMax_DSB->value()) {
ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value());
}
@@ -956,21 +1005,27 @@ void TelemetryPanel::on_varioLimitCenterMax_DSB_editingFinished()
void TelemetryPanel::on_fasOffset_DSB_editingFinished()
{
- model->frsky.fasOffset = ui->fasOffset_DSB->value() * 10;
- emit modified();
+ if (!isLocked()) {
+ model->frsky.fasOffset = ui->fasOffset_DSB->value() * 10;
+ emit modified();
+ }
}
void TelemetryPanel::on_mahCount_SB_editingFinished()
{
- model->frsky.storedMah = ui->mahCount_SB->value();
- emit modified();
+ if (!isLocked()) {
+ model->frsky.storedMah = ui->mahCount_SB->value();
+ emit modified();
+ }
}
void TelemetryPanel::on_mahCount_ChkB_toggled(bool checked)
{
- model->frsky.mAhPersistent = checked;
- ui->mahCount_SB->setDisabled(!checked);
- emit modified();
+ if (!isLocked()) {
+ model->frsky.mAhPersistent = checked;
+ ui->mahCount_SB->setDisabled(!checked);
+ emit modified();
+ }
}
void TelemetryPanel::on_clearAllSensors()
@@ -980,9 +1035,7 @@ void TelemetryPanel::on_clearAllSensors()
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i);
}
- updateItemModels();
- update();
- emit modified();
+ on_dataModifiedSensor();
}
void TelemetryPanel::on_insertSensor(int selectedIndex)
@@ -990,10 +1043,7 @@ void TelemetryPanel::on_insertSensor(int selectedIndex)
memmove(&model->sensorData[selectedIndex + 1], &model->sensorData[selectedIndex], (CPN_MAX_SENSORS - (selectedIndex + 1)) * sizeof(SensorData));
model->sensorData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
-
- updateItemModels();
- update();
- emit modified();
+ on_dataModifiedSensor();
}
void TelemetryPanel::on_deleteSensor(int selectedIndex)
@@ -1004,10 +1054,7 @@ void TelemetryPanel::on_deleteSensor(int selectedIndex)
memmove(&model->sensorData[selectedIndex], &model->sensorData[selectedIndex + 1], (CPN_MAX_SENSORS - (selectedIndex + 1)) * sizeof(SensorData));
model->sensorData[CPN_MAX_SENSORS - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
-
- updateItemModels();
- update();
- emit modified();
+ on_dataModifiedSensor();
}
void TelemetryPanel::on_moveUpSensor(int selectedIndex)
@@ -1029,20 +1076,34 @@ void TelemetryPanel::swapData(int idx1, int idx2)
memcpy(sd2, sd1, sizeof(SensorData));
memcpy(sd1, &sdtmp, sizeof(SensorData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
- updateItemModels();
- update();
- emit modified();
+ on_dataModifiedSensor();
}
}
void TelemetryPanel::on_dataModifiedSensor()
{
- updateItemModels();
- update();
+ sharedItemModels->update(AbstractItemModel::IMUE_TeleSensors);
emit modified();
}
-void TelemetryPanel::updateItemModels()
+void TelemetryPanel::connectItemModelEvents(const int id)
{
- commonItemModels->update(CommonItemModels::RMO_TELEMETRY_SENSORS);
+ FilteredItemModel * itemModel = panelFilteredItemModels->getItemModel(id);
+ connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TelemetryPanel::onItemModelAboutToBeUpdated);
+ connect(itemModel, &FilteredItemModel::updateComplete, this, &TelemetryPanel::onItemModelUpdateComplete);
+}
+
+void TelemetryPanel::onItemModelAboutToBeUpdated()
+{
+ lock = true;
+ modelsUpdateCnt++;
+}
+
+void TelemetryPanel::onItemModelUpdateComplete()
+{
+ modelsUpdateCnt--;
+ if (modelsUpdateCnt < 1) {
+ update();
+ lock = false;
+ }
}
diff --git a/companion/src/modeledit/telemetry.h b/companion/src/modeledit/telemetry.h
index 9719c7df6..224f88020 100644
--- a/companion/src/modeledit/telemetry.h
+++ b/companion/src/modeledit/telemetry.h
@@ -23,12 +23,11 @@
#include "modeledit.h"
#include "eeprominterface.h"
+#include "filtereditemmodels.h"
-constexpr char MIMETYPE_TELE_SENSOR[] = "application/x-companion-tele-sensor";
+constexpr char MIMETYPE_TELE_SENSOR[] {"application/x-companion-tele-sensor"};
class AutoComboBox;
-class CommonItemModels;
-class RawItemFilteredModel;
class TimerEdit;
namespace Ui {
@@ -42,7 +41,8 @@ class TelemetryCustomScreen: public ModelPanel
Q_OBJECT
public:
- TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel);
+ TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware,
+ const bool & parentLock, FilteredItemModelFactory * panelFilteredItemModels);
~TelemetryCustomScreen();
void update();
@@ -54,8 +54,8 @@ class TelemetryCustomScreen: public ModelPanel
void barMinChanged(double value);
void barMaxChanged(double value);
void barTimeChanged();
- void onModelDataAboutToBeUpdated();
- void onModelDataUpdateComplete();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
void updateBar(int line);
@@ -67,6 +67,11 @@ class TelemetryCustomScreen: public ModelPanel
QDoubleSpinBox * maxSB[4];
TimerEdit * minTime[4];
TimerEdit * maxTime[4];
+ int modelsUpdateCnt;
+ const bool &parentLock;
+
+ inline bool isLocked() { return lock | parentLock; }
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class TelemetrySensorPanel: public ModelPanel
@@ -74,7 +79,9 @@ class TelemetrySensorPanel: public ModelPanel
Q_OBJECT
public:
- TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
+ TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model,
+ GeneralSettings & generalSettings, Firmware * firmware, const bool & parentLock,
+ FilteredItemModelFactory * panelFilteredItemModels);
~TelemetrySensorPanel();
void update();
@@ -86,7 +93,6 @@ class TelemetrySensorPanel: public ModelPanel
void moveUpSensor(int index);
void moveDownSensor(int index);
-
protected slots:
void on_name_editingFinished();
void on_type_currentIndexChanged(int index);
@@ -104,20 +110,23 @@ class TelemetrySensorPanel: public ModelPanel
void cmDelete();
void cmMoveUp();
void cmMoveDown();
-
- protected:
- void updateSourcesComboBox(AutoComboBox * cb, bool negative);
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
Ui::TelemetrySensor * ui;
SensorData & sensor;
- bool lock = false;
int sensorIndex = 0;
int selectedIndex = 0;
int sensorCapability;
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
+ int modelsUpdateCnt;
+ const bool &parentLock;
+
+ inline bool isLocked() { return lock | parentLock; }
+ void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class TelemetryPanel : public ModelPanel
@@ -125,7 +134,8 @@ class TelemetryPanel : public ModelPanel
Q_OBJECT
public:
- TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
+ TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
+ CompoundItemModelFactory * sharedItemModels);
virtual ~TelemetryPanel();
virtual void update();
@@ -152,22 +162,24 @@ class TelemetryPanel : public ModelPanel
void on_moveUpSensor(int index);
void on_moveDownSensor(int index);
void on_dataModifiedSensor();
+ void onItemModelAboutToBeUpdated();
+ void onItemModelUpdateComplete();
private:
Ui::Telemetry *ui;
- TelemetryCustomScreen * telemetryCustomScreens[4];
- TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS];
+ TelemetryCustomScreen *telemetryCustomScreens[4];
+ TelemetrySensorPanel *sensorPanels[CPN_MAX_SENSORS];
int sensorCapability;
- CommonItemModels * commonItemModels;
- RawItemFilteredModel * rawSourceFilteredModel;
+ CompoundItemModelFactory *sharedItemModels;
+ CompoundItemModelFactory *panelItemModels;
+ FilteredItemModelFactory *panelFilteredItemModels;
+ int modelsUpdateCnt;
void setup();
void telBarUpdate();
- void populateVoltsSource();
- void populateCurrentSource();
- void populateVarioSource();
void swapData(int idx1, int idx2);
- void updateItemModels();
+ void connectItemModelEvents(const int id);
+ inline bool isLocked() { return lock; }
};
#endif // _TELEMETRY_H_
diff --git a/companion/src/shared/autocombobox.h b/companion/src/shared/autocombobox.h
index fcb1845ac..158352f97 100644
--- a/companion/src/shared/autocombobox.h
+++ b/companion/src/shared/autocombobox.h
@@ -37,30 +37,37 @@ class AutoComboBox: public QComboBox
void clear()
{
- lock = true;
- QComboBox::clear();
- next = 0;
- lock = false;
+ if (!hasModel) {
+ lock = true;
+ QComboBox::clear();
+ next = 0;
+ lock = false;
+ }
}
virtual void insertItems(int index, const QStringList & items)
{
- foreach(QString item, items) {
- addItem(item);
+ if (!hasModel) {
+ foreach(QString item, items) {
+ addItem(item);
+ }
}
}
virtual void addItem(const QString & item)
{
- addItem(item, next++);
+ if (!hasModel)
+ addItem(item, next++);
}
virtual void addItem(const QString & item, int value)
{
- lock = true;
- QComboBox::addItem(item, value);
- lock = false;
- updateValue();
+ if (!hasModel) {
+ lock = true;
+ QComboBox::addItem(item, value);
+ lock = false;
+ updateValue();
+ }
}
void setField(unsigned int & field, GenericPanel * panel=nullptr)
@@ -77,11 +84,22 @@ class AutoComboBox: public QComboBox
updateValue();
}
+ void setModel(QAbstractItemModel * model)
+ {
+ lock = true;
+ QComboBox::setModel(model);
+ lock = false;
+ hasModel = true;
+ updateValue();
+ }
+
void setAutoIndexes()
{
- for (int i=0; imodified();
+ if (panel && panel->lock)
+ return;
+ if (index > -1) {
+ const int val = itemData(index).toInt();
+ if (field && !lock) {
+ *field = val;
+ if (panel)
+ emit panel->modified();
+ }
+ emit currentDataChanged(val);
}
- emit currentDataChanged(val);
}
protected:
@@ -113,6 +135,7 @@ class AutoComboBox: public QComboBox
GenericPanel * panel = nullptr;
int next = 0;
bool lock = false;
+ bool hasModel = false;
};
#endif // _AUTOCOMBOBOX_H_
diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt
index 9b9cbc130..c2707a5ca 100644
--- a/companion/src/simulation/CMakeLists.txt
+++ b/companion/src/simulation/CMakeLists.txt
@@ -16,6 +16,7 @@ set(simulation_SRCS
simulateduiwidgetJumperT16.cpp
simulateduiwidgetJumperT18.cpp
simulateduiwidgetTX12.cpp
+ simulateduiwidgetT8.cpp
simulateduiwidgetTX16S.cpp
simulatorinterface.cpp
simulatormainwindow.cpp
@@ -43,6 +44,7 @@ set(simulation_UIS
simulateduiwidgetJumperT16.ui
simulateduiwidgetJumperT18.ui
simulateduiwidgetTX12.ui
+ simulateduiwidgetT8.ui
simulateduiwidgetTX16S.ui
simulatormainwindow.ui
simulatorstartupdialog.ui
diff --git a/companion/src/simulation/simulateduiwidget.h b/companion/src/simulation/simulateduiwidget.h
index 66939f429..af965684f 100644
--- a/companion/src/simulation/simulateduiwidget.h
+++ b/companion/src/simulation/simulateduiwidget.h
@@ -116,6 +116,7 @@ namespace Ui {
class SimulatedUIWidgetJumperT18;
class SimulatedUIWidgetTX16S;
class SimulatedUIWidgetTX12;
+ class SimulatedUIWidgetT8;
}
class SimulatedUIWidget9X: public SimulatedUIWidget
@@ -278,6 +279,17 @@ class SimulatedUIWidgetTX12: public SimulatedUIWidget
Ui::SimulatedUIWidgetTX12 * ui;
};
+class SimulatedUIWidgetT8: public SimulatedUIWidget
+{
+Q_OBJECT
+
+public:
+ explicit SimulatedUIWidgetT8(SimulatorInterface * simulator, QWidget * parent = nullptr);
+ virtual ~SimulatedUIWidgetT8();
+
+private:
+ Ui::SimulatedUIWidgetT8 * ui;
+};
class SimulatedUIWidgetTX16S: public SimulatedUIWidget
{
diff --git a/companion/src/simulation/simulateduiwidgetT8.cpp b/companion/src/simulation/simulateduiwidgetT8.cpp
new file mode 100644
index 000000000..ed86889d7
--- /dev/null
+++ b/companion/src/simulation/simulateduiwidgetT8.cpp
@@ -0,0 +1,67 @@
+#include "simulateduiwidget.h"
+#include "ui_simulateduiwidgetT8.h"
+
+// NOTE: RadioUiAction(NUMBER,...): NUMBER relates to enum EnumKeys in the specific board.h
+
+SimulatedUIWidgetT8::SimulatedUIWidgetT8(SimulatorInterface *simulator, QWidget * parent):
+ SimulatedUIWidget(simulator, parent),
+ ui(new Ui::SimulatedUIWidgetT8)
+{
+ RadioUiAction * act;
+
+ ui->setupUi(this);
+
+ // add actions in order of appearance on the help menu
+
+ act = new RadioUiAction(5, QList() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL);
+ addRadioWidget(ui->rightbuttons->addArea(QRect(25, 40, 35, 20), "T8/right-mdl.png", act));
+
+ act = new RadioUiAction(6, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_UP);
+ addRadioWidget(ui->rightbuttons->addArea(QRect(25, 90, 35, 20), "T8/right-up.png", act));
+
+ act = new RadioUiAction(7, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_DN);
+ addRadioWidget(ui->rightbuttons->addArea(QRect(25, 135, 35, 20), "T8/right-dn.png", act));
+
+ act = new RadioUiAction(1, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ENT);
+ addRadioWidget(ui->rightbuttons->addArea(QRect(25, 180, 35, 20), "T8/right-ent.png", act));
+
+ act = new RadioUiAction(4, QList() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS);
+ addRadioWidget(ui->leftbuttons->addArea(QRect(60, 45, 35, 20), "T8/left-sys.png", act));
+
+ act = new RadioUiAction(0, QList() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT);
+ addRadioWidget(ui->leftbuttons->addArea(QRect(60, 85, 35, 20), "T8/left-rtn.png", act));
+
+ act = new RadioUiAction(3, QList() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN);
+ addRadioWidget(ui->leftbuttons->addArea(QRect(60, 135, 35, 20), "T8/left-pagedn.png", act));
+
+ act = new RadioUiAction(2, QList() << Qt::Key_PageUp, SIMU_STR_HLP_KEY_PGUP, SIMU_STR_HLP_ACT_PGUP);
+ addRadioWidget(ui->leftbuttons->addArea(QRect(60, 180, 35, 20), "T8/left-pageup.png", act));
+
+
+ m_backlightColors << QColor(215, 243, 255); // X7 Blue
+ m_backlightColors << QColor(166,247,159);
+ m_backlightColors << QColor(247,159,166);
+ m_backlightColors << QColor(255,195,151);
+ m_backlightColors << QColor(247,242,159);
+
+ setLcd(ui->lcd);
+
+ QString css = "#radioUiWidget {"
+ "background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1,"
+ "stop:0 rgba(255, 255, 255, 255),"
+ "stop:0.757062 rgba(241, 238, 238, 255),"
+ "stop:1 rgba(247, 245, 245, 255));"
+ "}";
+
+ QTimer * tim = new QTimer(this);
+ tim->setSingleShot(true);
+ connect(tim, &QTimer::timeout, [this, css]() {
+ emit customStyleRequest(css);
+ });
+ tim->start(100);
+}
+
+SimulatedUIWidgetT8::~SimulatedUIWidgetT8()
+{
+ delete ui;
+}
diff --git a/companion/src/simulation/simulateduiwidgetT8.ui b/companion/src/simulation/simulateduiwidgetT8.ui
new file mode 100644
index 000000000..6370888ea
--- /dev/null
+++ b/companion/src/simulation/simulateduiwidgetT8.ui
@@ -0,0 +1,258 @@
+
+
+ SimulatedUIWidgetT8
+
+
+
+ 0
+ 0
+ 480
+ 300
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 480
+ 300
+
+
+
+
+ 480
+ 300
+
+
+
+ Radiomaster T8 Simulator
+
+
+ background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:0.757062 rgba(241, 238, 238, 255), stop:1 rgba(247, 245, 245, 255));
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 113
+ 280
+
+
+
+
+ 113
+ 280
+
+
+
+ background:url(:/images/simulator/T8/left.png);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 254
+ 158
+
+
+
+
+ 254
+ 158
+
+
+
+ background-color: rgb(215, 243, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 113
+ 280
+
+
+
+
+ 113
+ 280
+
+
+
+ background:url(:/images/simulator/T8/right.png)
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 254
+ 35
+
+
+
+
+ 254
+ 35
+
+
+
+ background:url(:/images/simulator/T8/top.png)
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 254
+ 113
+
+
+
+
+ 254
+ 113
+
+
+
+ background:url(:/images/simulator/T8/bottom.png)
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 10
+
+
+
+
+ 16777215
+ 12
+
+
+
+
+ 0
+ 12
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 10
+
+
+
+
+ 16777215
+ 10
+
+
+
+ background-color: rgb(247, 245, 245);
+
+
+
+
+
+
+
+
+
+
+ LcdWidget
+ QWidget
+
+ 1
+
+
+ ButtonsWidget
+ QWidget
+
+ 1
+
+
+
+
+
diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp
index cab7600d4..0b2b6b853 100644
--- a/companion/src/simulation/simulatorwidget.cpp
+++ b/companion/src/simulation/simulatorwidget.cpp
@@ -100,6 +100,9 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato
case Board::BOARD_RADIOMASTER_TX12:
radioUiWidget = new SimulatedUIWidgetTX12(simulator, this);
break;
+ case Board::BOARD_RADIOMASTER_T8:
+ radioUiWidget = new SimulatedUIWidgetT8(simulator, this);
+ break;
case Board::BOARD_RADIOMASTER_TX16S:
radioUiWidget = new SimulatedUIWidgetTX16S(simulator, this);
break;
diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt
index 39ea7e52e..b71d572ba 100644
--- a/radio/src/CMakeLists.txt
+++ b/radio/src/CMakeLists.txt
@@ -345,6 +345,10 @@ if(RADIOMASTER_RELEASE)
add_definitions(-DRADIOMASTER_RELEASE)
endif()
+if(RADIOMASTER_RTF_RELEASE)
+ add_definitions(-DRADIOMASTER_RTF_RELEASE)
+endif()
+
if(TBS_RELEASE)
add_definitions(-DTBS_RELEASE)
endif()
diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h
index dcdd6e5c8..005fbec56 100644
--- a/radio/src/dataconstants.h
+++ b/radio/src/dataconstants.h
@@ -208,7 +208,11 @@ enum TrainerMode {
};
#endif
-#if defined(RADIO_T16) && !defined(INTERNAL_MODULE_MULTI)
+#define TRAINER_MODE_MIN() TRAINER_MODE_MASTER_TRAINER_JACK
+
+#if !defined(HARDWARE_EXTERNAL_MODULE)
+ #define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE
+#elif defined(RADIO_T16) && !defined(INTERNAL_MODULE_MULTI)
#if defined(BLUETOOTH)
#define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE_BLUETOOTH
#else
diff --git a/radio/src/gui/128x64/lcd.h b/radio/src/gui/128x64/lcd.h
index c6b32dd3d..3a94f2365 100644
--- a/radio/src/gui/128x64/lcd.h
+++ b/radio/src/gui/128x64/lcd.h
@@ -181,8 +181,9 @@ uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint8_t width, ui
#if defined(BOOT)
#define BLINK_ON_PHASE (0)
#else
- #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
+ #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
+ #define FAST_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<4))
#endif
inline display_t getPixel(uint8_t x, uint8_t y)
diff --git a/radio/src/gui/128x64/model_curve_edit.cpp b/radio/src/gui/128x64/model_curve_edit.cpp
index 66f153b4d..c2168ed02 100644
--- a/radio/src/gui/128x64/model_curve_edit.cpp
+++ b/radio/src/gui/128x64/model_curve_edit.cpp
@@ -165,7 +165,7 @@ void menuModelCurveOne(event_t event)
}
break;
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_MDL)
case EVT_KEY_FIRST(KEY_MODEL):
pushMenu(menuChannelsView);
killEvents(event);
diff --git a/radio/src/gui/128x64/model_input_edit.cpp b/radio/src/gui/128x64/model_input_edit.cpp
index 840e41a82..ce76e0a89 100644
--- a/radio/src/gui/128x64/model_input_edit.cpp
+++ b/radio/src/gui/128x64/model_input_edit.cpp
@@ -49,7 +49,7 @@ enum ExposFields {
void menuModelExpoOne(event_t event)
{
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_MDL)
if (event == EVT_KEY_FIRST(KEY_MODEL)) {
pushMenu(menuChannelsView);
killEvents(event);
diff --git a/radio/src/gui/128x64/model_mix_edit.cpp b/radio/src/gui/128x64/model_mix_edit.cpp
index 92e10ee69..281256f46 100644
--- a/radio/src/gui/128x64/model_mix_edit.cpp
+++ b/radio/src/gui/128x64/model_mix_edit.cpp
@@ -85,7 +85,7 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md)
void menuModelMixOne(event_t event)
{
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_MDL)
if (event == EVT_KEY_FIRST(KEY_MODEL)) {
pushMenu(menuChannelsView);
killEvents(event);
diff --git a/radio/src/gui/128x64/model_select.cpp b/radio/src/gui/128x64/model_select.cpp
index cf6410d63..bcf04117d 100644
--- a/radio/src/gui/128x64/model_select.cpp
+++ b/radio/src/gui/128x64/model_select.cpp
@@ -203,7 +203,7 @@ void menuModelSelect(event_t event)
}
break;
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_FIRST(KEY_PAGEUP):
chainMenu(menuTabModel[DIM(menuTabModel)-1]);
killEvents(event);
@@ -212,7 +212,7 @@ void menuModelSelect(event_t event)
case EVT_KEY_FIRST(KEY_PAGEDN):
chainMenu(menuModelSetup);
break;
-#elif defined(NAVIGATION_X7)
+#elif defined(KEYS_GPIO_REG_PAGE)
case EVT_KEY_LONG(KEY_PAGE):
chainMenu(menuTabModel[DIM(menuTabModel)-1]);
killEvents(event);
@@ -244,7 +244,7 @@ void menuModelSelect(event_t event)
#endif
#endif
-#if defined(NAVIGATION_X7)
+#if defined(ROTARY_ENCODER) && defined(NAVIGATION_X7)
case EVT_ROTARY_LEFT:
case EVT_ROTARY_RIGHT:
#endif
diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp
index 41af5720f..468597b29 100644
--- a/radio/src/gui/128x64/model_setup.cpp
+++ b/radio/src/gui/128x64/model_setup.cpp
@@ -111,7 +111,7 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3,
#endif
-
+#if defined(HARDWARE_EXTERNAL_MODULE)
ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE,
#if defined(MULTIMODULE)
@@ -156,6 +156,7 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_EXTRA_MODULE_CHANNELS,
ITEM_MODEL_SETUP_EXTRA_MODULE_BIND,
#endif
+#endif
#if defined(PCBTARANIS)
ITEM_MODEL_SETUP_TRAINER_LABEL,
@@ -183,13 +184,16 @@ enum MenuModelSetupItems {
#define REGISTRATION_ID_ROWS
#endif
-#if defined(HARDWARE_INTERNAL_MODULE)
+#if defined(HARDWARE_INTERNAL_MODULE) && defined(HARDWARE_EXTERNAL_MODULE)
#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)
#define CURRENT_RECEIVER_EDITED(k) (k - (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1 : ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1))
#elif defined(PCBSKY9X)
- #define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE)
+ #define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE)
+#elif defined(HARDWARE_INTERNAL_MODULE)
+ #define CURRENT_MODULE_EDITED(k) (INTERNAL_MODULE)
+ #define CURRENT_RECEIVER_EDITED(k) (k - ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1)
#else
- #define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE)
+ #define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE)
#define CURRENT_RECEIVER_EDITED(k) (k - ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1)
#endif
@@ -335,6 +339,32 @@ void onBluetoothConnectMenu(const char * result)
#define INTERNAL_MODULE_ROWS
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
+ #define EXTERNAL_MODULE_ROWS \
+ LABEL(ExternalModule), \
+ MODULE_TYPE_ROWS(EXTERNAL_MODULE), \
+ MULTIMODULE_TYPE_ROWS(EXTERNAL_MODULE) /* PROTOCOL */ \
+ MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) /* SUBTYPE */ \
+ MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) \
+ AFHDS3_PROTOCOL_ROW(EXTERNAL_MODULE) \
+ AFHDS3_MODE_ROWS(EXTERNAL_MODULE) \
+ MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), \
+ IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), /* line reused for PPM: PPM settings */ \
+ IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* RxNum */ \
+ AFHDS3_MODULE_ROWS(EXTERNAL_MODULE) \
+ MODULE_POWER_ROW(EXTERNAL_MODULE), \
+ IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)), \
+ MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE) \
+ FAILSAFE_ROWS(EXTERNAL_MODULE), /* ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE */ \
+ IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), /* Range check and Register buttons */ \
+ IF_PXX2_MODULE(EXTERNAL_MODULE, 0), /* Module options */ \
+ IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* Receiver 1 */ \
+ IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* Receiver 2 */ \
+ IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* Receiver 3 */
+#else
+ #define EXTERNAL_MODULE_ROWS
+#endif
+
void menuModelSetup(event_t event)
{
int8_t old_editMode = s_editMode;
@@ -370,26 +400,7 @@ void menuModelSetup(event_t event)
INTERNAL_MODULE_ROWS
- LABEL(ExternalModule),
- MODULE_TYPE_ROWS(EXTERNAL_MODULE),
- MULTIMODULE_TYPE_ROWS(EXTERNAL_MODULE) // PROTOCOL
- MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) // SUBTYPE
- MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE)
- AFHDS3_PROTOCOL_ROW(EXTERNAL_MODULE)
- AFHDS3_MODE_ROWS(EXTERNAL_MODULE)
- MODULE_CHANNELS_ROWS(EXTERNAL_MODULE),
- IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings
- IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum
- AFHDS3_MODULE_ROWS(EXTERNAL_MODULE)
- MODULE_POWER_ROW(EXTERNAL_MODULE),
- IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)),
- MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE)
- FAILSAFE_ROWS(EXTERNAL_MODULE), //ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE
- IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons
- IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options
- IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1
- IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2
- IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 3
+ EXTERNAL_MODULE_ROWS
TRAINER_ROWS
});
@@ -857,7 +868,7 @@ void menuModelSetup(event_t event)
#if !defined(INTERNAL_MODULE_MULTI)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE:
{
- lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
+ lcdDrawText(INDENT_WIDTH, y, STR_MODE);
#if defined(INTERNAL_MODULE_PXX1)
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_INTERNAL_MODULE_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0);
if (isModuleXJT(INTERNAL_MODULE))
@@ -912,14 +923,18 @@ void menuModelSetup(event_t event)
break;
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL:
lcdDrawTextAlignedLeft(y, STR_EXTERNALRF);
break;
+#endif
#if defined(INTERNAL_MODULE_MULTI)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE:
+#endif
lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, moduleIdx == EXTERNAL_MODULE ? reusableBuffer.moduleSetup.newType : g_model.moduleData[moduleIdx].type, menuHorizontalPosition==0 ? attr : 0);
if (isModuleXJT(moduleIdx))
@@ -1013,7 +1028,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PROTOCOL:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PROTOCOL:
+#endif
{
lcdDrawTextAlignedLeft(y, TR_TYPE);
int multi_rfProto = g_model.moduleData[moduleIdx].getMultiProtocol();
@@ -1052,7 +1069,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_SUBTYPE:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SUBTYPE:
+#endif
{
lcdDrawTextAlignedLeft(y, STR_SUBTYPE);
lcdDrawMultiSubProtocolString(MODEL_SETUP_2ND_COLUMN, y, moduleIdx, g_model.moduleData[moduleIdx].subType, attr);
@@ -1073,7 +1092,7 @@ void menuModelSetup(event_t event)
#if defined(AFHDS3)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS_PROTOCOL:
- lcdDrawTextAlignedLeft(y, TR_PROTO);
+ lcdDrawText(INDENT_WIDTH, y, STR_PROTOCOL);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_AFHDS3_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].subType, attr);
if (attr && s_editMode > 0 && menuHorizontalPosition == 0) {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, AFHDS_SUBTYPE_FIRST, AFHDS_SUBTYPE_LAST);
@@ -1095,7 +1114,7 @@ void menuModelSetup(event_t event)
lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerData.mode, attr);
if (attr) {
- g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable);
+ g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, TRAINER_MODE_MIN(), TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable);
#if defined(BLUETOOTH)
if (checkIncDec_Ret) {
bluetooth.state = BLUETOOTH_STATE_OFF;
@@ -1182,7 +1201,9 @@ void menuModelSetup(event_t event)
#if defined(PCBSKY9X)
case ITEM_MODEL_SETUP_EXTRA_MODULE_CHANNELS:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS:
+#endif
{
ModuleData & moduleData = g_model.moduleData[moduleIdx];
lcdDrawTextAlignedLeft(y, STR_CHANNELRANGE);
@@ -1308,7 +1329,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
+#endif
{
ModuleData & moduleData = g_model.moduleData[moduleIdx];
if (isModulePPM(moduleIdx)) {
@@ -1462,7 +1485,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE:
+#endif
{
ModuleData &moduleData = g_model.moduleData[moduleIdx];
lcdDrawTextAlignedLeft(y, STR_FAILSAFE);
@@ -1523,7 +1548,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS:
+#endif
{
#if defined(MULTIMODULE)
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
@@ -1602,7 +1629,9 @@ void menuModelSetup(event_t event)
#if defined(INTERNAL_MODULE_MULTI)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_POWER:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER:
+#endif
{
auto & module = g_model.moduleData[moduleIdx];
// Lite FCC / Lite FLEX / Lite Pro Flex
@@ -1687,7 +1716,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND:
+#endif
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) {
int8_t value = (g_model.moduleData[moduleIdx].multi.optionValue & 0x02) >> 1;
lcdDrawText(INDENT_WIDTH, y, STR_MULTI_SERVOFREQ);
@@ -1708,13 +1739,17 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_TELEM:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM:
+#endif
g_model.moduleData[moduleIdx].multi.disableTelemetry = editCheckBox(g_model.moduleData[moduleIdx].multi.disableTelemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_TELEM, attr, event);
break;
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_MAPPING:
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING:
+#endif
g_model.moduleData[moduleIdx].multi.disableMapping = editCheckBox(g_model.moduleData[moduleIdx].multi.disableMapping, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_CH_MAP, attr, event);
break;
#endif
@@ -1739,7 +1774,10 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS:
#endif
- case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS: {
+#if defined(HARDWARE_EXTERNAL_MODULE)
+ case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS:
+#endif
+ {
lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS);
char statusText[64];
@@ -1750,7 +1788,10 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS:
#endif
- case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS: {
+#if defined(HARDWARE_EXTERNAL_MODULE)
+ case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS:
+#endif
+ {
lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC);
char statusText[64];
getModuleSyncStatusString(moduleIdx, statusText);
@@ -1848,11 +1889,13 @@ void menuModelSetup(event_t event)
checkModelIdUnique(g_eeGeneral.currModel, EXTRA_MODULE);
break;
#endif
+#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM:
if (menuHorizontalPosition == 0)
checkModelIdUnique(g_eeGeneral.currModel, EXTERNAL_MODULE);
break;
+#endif
}
}
}
diff --git a/radio/src/gui/128x64/radio_diagkeys.cpp b/radio/src/gui/128x64/radio_diagkeys.cpp
index a3d058c3e..803ff7eb7 100644
--- a/radio/src/gui/128x64/radio_diagkeys.cpp
+++ b/radio/src/gui/128x64/radio_diagkeys.cpp
@@ -49,10 +49,15 @@ void menuRadioDiagKeys(event_t event)
displayKeyState(i&1? 20*FW : 18*FW, y, TRM_BASE+i);
}
- if (i <= KEY_MAX) {
- y = MENU_HEADER_HEIGHT + 1 + FH*i;
+ if (i == 7) {
+ y = MENU_HEADER_HEIGHT + 1 + FH * 6;
+ lcdDrawTextAtIndex(8, y, STR_VKEYS, i, 0);
+ displayKeyState(lcdNextPos + 10, y, i);
+ }
+ else if (i <= KEY_MAX) {
+ y = MENU_HEADER_HEIGHT + 1 + FH * i;
lcdDrawTextAtIndex(0, y, STR_VKEYS, i, 0);
- displayKeyState(5*FW+2, y, i);
+ displayKeyState(5 * FW + 2, y, i);
}
#if defined(PCBSKY9X)
diff --git a/radio/src/gui/128x64/radio_setup.cpp b/radio/src/gui/128x64/radio_setup.cpp
index e3fd06bb3..26b80cb0f 100644
--- a/radio/src/gui/128x64/radio_setup.cpp
+++ b/radio/src/gui/128x64/radio_setup.cpp
@@ -79,13 +79,13 @@ enum {
ITEM_RADIO_SETUP_MEMORY_WARNING,
ITEM_RADIO_SETUP_ALARM_WARNING,
ITEM_RADIO_SETUP_RSSI_POWEROFF_ALARM,
- ITEM_RADIO_SETUP_BACKLIGHT_LABEL,
- ITEM_RADIO_SETUP_BACKLIGHT_MODE,
- ITEM_RADIO_SETUP_BACKLIGHT_DELAY,
- ITEM_RADIO_SETUP_BRIGHTNESS,
+ CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_LABEL)
+ CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_MODE)
+ CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_DELAY)
+ CASE_BACKLIGHT(ITEM_RADIO_SETUP_BRIGHTNESS)
CASE_PWM_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_BRIGHTNESS_OFF)
CASE_PWM_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_BRIGHTNESS_ON)
- ITEM_RADIO_SETUP_FLASH_BEEP,
+ CASE_BACKLIGHT(ITEM_RADIO_SETUP_FLASH_BEEP)
CASE_SPLASH_PARAM(ITEM_RADIO_SETUP_DISABLE_SPLASH)
CASE_PWR_BUTTON_PRESS(ITEM_RADIO_SETUP_PWR_ON_SPEED)
CASE_PWR_BUTTON_PRESS(ITEM_RADIO_SETUP_PWR_OFF_SPEED)
@@ -152,10 +152,14 @@ void menuRadioSetup(event_t event)
CASE_GYRO(0)
CASE_GYRO(0)
0, LABEL(ALARMS), 0, CASE_CAPACITY(0)
- 0, 0, 0, 0,
- LABEL(BACKLIGHT), 0, 0, 0, CASE_PWM_BACKLIGHT(0)
+ 0, 0, 0, 0, /* ITEM_RADIO_SETUP_INACTIVITY_ALARM ITEM_RADIO_SETUP_MEMORY_WARNING ITEM_RADIO_SETUP_ALARM_WARNING ITEM_RADIO_SETUP_RSSI_POWEROFF_ALARM */
+ CASE_BACKLIGHT(LABEL(BACKLIGHT))
+ CASE_BACKLIGHT(0)
+ CASE_BACKLIGHT(0)
+ CASE_BACKLIGHT(0)
CASE_PWM_BACKLIGHT(0)
- 0,
+ CASE_PWM_BACKLIGHT(0)
+ CASE_BACKLIGHT(0)
CASE_SPLASH_PARAM(0)
CASE_PWR_BUTTON_PRESS(0)
CASE_PWR_BUTTON_PRESS(0)
@@ -251,7 +255,7 @@ void menuRadioSetup(event_t event)
putsVolts(lcdLastRightPos+FW, y, 120+g_eeGeneral.vBatMax, (menuHorizontalPosition>0 ? attr : 0)|LEFT|NO_UNIT);
if (attr && s_editMode>0) {
if (menuHorizontalPosition==0)
- CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMin, -50, g_eeGeneral.vBatMax+29); // min=4.0V
+ CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMin, -60, g_eeGeneral.vBatMax+29); // min=3.0V
else
CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMax, g_eeGeneral.vBatMin-29, +40); // max=16.0V
}
@@ -411,7 +415,7 @@ void menuRadioSetup(event_t event)
case ITEM_RADIO_SETUP_BATTERY_WARNING:
lcdDrawTextAlignedLeft(y, STR_BATTERYWARNING);
putsVolts(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.vBatWarn, attr|LEFT);
- if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 40, 120); //4-12V
+ if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 30, 120); //3-12V
break;
case ITEM_RADIO_SETUP_MEMORY_WARNING:
@@ -450,6 +454,7 @@ void menuRadioSetup(event_t event)
if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes
break;
+#if defined(BACKLIGHT_GPIO)
case ITEM_RADIO_SETUP_BACKLIGHT_LABEL:
lcdDrawTextAlignedLeft(y, STR_BACKLIGHT_LABEL);
break;
@@ -478,6 +483,7 @@ void menuRadioSetup(event_t event)
g_eeGeneral.backlightBright = 100 - b;
}
break;
+#endif
#if defined(PWM_BACKLIGHT)
case ITEM_RADIO_SETUP_BACKLIGHT_BRIGHTNESS_OFF:
diff --git a/radio/src/gui/128x64/view_about.cpp b/radio/src/gui/128x64/view_about.cpp
index 02e8e4508..b168f91fb 100644
--- a/radio/src/gui/128x64/view_about.cpp
+++ b/radio/src/gui/128x64/view_about.cpp
@@ -42,7 +42,7 @@ enum AboutScreens {
#define ABOUT_X 2
#define ABOUT_INDENT 4
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEDN)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGEDN)
#elif defined(NAVIGATION_X7)
diff --git a/radio/src/gui/128x64/view_channels.cpp b/radio/src/gui/128x64/view_channels.cpp
index f71d833c1..ffb4d9b33 100644
--- a/radio/src/gui/128x64/view_channels.cpp
+++ b/radio/src/gui/128x64/view_channels.cpp
@@ -26,7 +26,12 @@ constexpr coord_t CHANNEL_GAUGE_OFFSET = CHANNEL_VALUE_OFFSET;
constexpr coord_t CHANNEL_BAR_WIDTH = 70;
constexpr coord_t CHANNEL_PROPERTIES_OFFSET = CHANNEL_GAUGE_OFFSET + CHANNEL_BAR_WIDTH + 2;
-#if defined(NAVIGATION_X7_TX12)
+#if defined(RADIO_T8)
+#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
+#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGEDN)
+#define EVT_KEY_NEXT_PAGE EVT_KEY_BREAK(KEY_PLUS)
+#define EVT_KEY_PREVIOUS_PAGE EVT_KEY_BREAK(KEY_MINUS)
+#elif defined(NAVIGATION_X7_TX12)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGEDN)
#define EVT_KEY_NEXT_PAGE EVT_ROTARY_RIGHT
diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp
index ee486269b..b3cea8de7 100644
--- a/radio/src/gui/128x64/view_main.cpp
+++ b/radio/src/gui/128x64/view_main.cpp
@@ -93,8 +93,9 @@ void doMainScreenGraphics()
if (g_model.throttleReversed && CONVERT_MODE(2) == THR_STICK)
calibStickVert = -calibStickVert;
drawStick(RBOX_CENTERX, calibratedAnalogs[CONVERT_MODE(3)], calibStickVert);
-
+#if defined(HARDWARE_POT1)
drawPotsBars();
+#endif
}
void displayTrims(uint8_t phase)
@@ -213,7 +214,16 @@ void displayVoltageOrAlarm()
#define displayVoltageOrAlarm() displayBattVoltage()
#endif
-#if defined(NAVIGATION_X7_TX12)
+#if defined(RADIO_T8)
+#define EVT_KEY_CONTEXT_MENU EVT_KEY_LONG(KEY_ENTER)
+#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
+#define EVT_KEY_NEXT_VIEW EVT_KEY_FIRST(KEY_PAGEDN)
+#define EVT_KEY_NEXT_PAGE EVT_KEY_FIRST(KEY_PLUS)
+#define EVT_KEY_PREVIOUS_PAGE EVT_KEY_FIRST(KEY_MINUS)
+#define EVT_KEY_MODEL_MENU EVT_KEY_LONG(KEY_MODEL)
+#define EVT_KEY_GENERAL_MENU EVT_KEY_LONG(KEY_SYS)
+#define EVT_KEY_TELEMETRY EVT_KEY_LONG(KEY_PAGEUP)
+#elif defined(NAVIGATION_X7_TX12)
#define EVT_KEY_CONTEXT_MENU EVT_KEY_LONG(KEY_ENTER)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_FIRST(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_FIRST(KEY_PAGEDN)
@@ -410,6 +420,7 @@ void menuMainView(event_t event)
killEvents(event);
break;
+
case EVT_KEY_FIRST(KEY_EXIT):
#if defined(GVARS)
if (gvarDisplayTimer > 0) {
diff --git a/radio/src/gui/128x64/view_statistics.cpp b/radio/src/gui/128x64/view_statistics.cpp
index 2b46be36e..0765cf9b6 100644
--- a/radio/src/gui/128x64/view_statistics.cpp
+++ b/radio/src/gui/128x64/view_statistics.cpp
@@ -31,7 +31,7 @@ void menuStatisticsView(event_t event)
switch (event) {
case EVT_KEY_FIRST(KEY_UP):
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_BREAK(KEY_PAGEDN):
#elif defined(NAVIGATION_X7)
case EVT_KEY_BREAK(KEY_PAGE):
@@ -41,7 +41,7 @@ void menuStatisticsView(event_t event)
break;
case EVT_KEY_FIRST(KEY_DOWN):
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEUP)
case EVT_KEY_BREAK(KEY_PAGEUP):
killEvents(event);
chainMenu(menuStatisticsDebug2);
@@ -140,7 +140,7 @@ void menuStatisticsDebug(event_t event)
break;
case EVT_KEY_FIRST(KEY_UP):
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_BREAK(KEY_PAGEDN):
disableVBatBridge();
chainMenu(menuStatisticsDebug2);
@@ -153,7 +153,7 @@ void menuStatisticsDebug(event_t event)
#endif
case EVT_KEY_FIRST(KEY_DOWN):
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEUP)
case EVT_KEY_BREAK(KEY_PAGEUP):
#elif defined(NAVIGATION_X7)
case EVT_KEY_LONG(KEY_PAGE):
@@ -278,7 +278,7 @@ void menuStatisticsDebug2(event_t event)
break;
case EVT_KEY_FIRST(KEY_UP):
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_BREAK(KEY_PAGEDN):
#elif defined(NAVIGATION_X7)
case EVT_KEY_BREAK(KEY_PAGE):
@@ -287,7 +287,7 @@ void menuStatisticsDebug2(event_t event)
return;
case EVT_KEY_FIRST(KEY_DOWN):
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEUP)
case EVT_KEY_BREAK(KEY_PAGEUP):
#elif defined(NAVIGATION_X7)
case EVT_KEY_LONG(KEY_PAGE):
diff --git a/radio/src/gui/480x272/model_receiver_options.cpp b/radio/src/gui/480x272/model_receiver_options.cpp
index 38e46728c..0a2e2e4e6 100644
--- a/radio/src/gui/480x272/model_receiver_options.cpp
+++ b/radio/src/gui/480x272/model_receiver_options.cpp
@@ -47,8 +47,7 @@ enum {
ITEM_RECEIVER_SETTINGS_PWM_RATE,
ITEM_RECEIVER_SETTINGS_TELEMETRY,
ITEM_RECEIVER_SETTINGS_TELEMETRY_25MW,
- ITEM_RECEIVER_SETTINGS_SPORT_FPORT,
- ITEM_RECEIVER_SETTINGS_FPORT2,
+ ITEM_RECEIVER_SETTINGS_SPORT_MODE,
ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1,
ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED2,
ITEM_RECEIVER_SETTINGS_PINMAP_FIRST
@@ -60,6 +59,15 @@ enum {
#define CH_ENABLE_SPORT 4
#define CH_ENABLE_SBUS 5
+bool isSPortModeAvailable(int mode)
+{
+ uint8_t receiverId = reusableBuffer.hardwareAndSettings.receiverSettings.receiverId;
+ if (mode == 2 && !IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT2)) {
+ return false;
+ }
+ return true;
+}
+
bool menuModelReceiverOptions(event_t event)
{
const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2;
@@ -82,8 +90,7 @@ bool menuModelReceiverOptions(event_t event)
0, // PWM rate
isModuleR9MAccess(g_moduleIdx) && receiverVariant == PXX2_VARIANT_EU && reusableBuffer.hardwareAndSettings.moduleSettings.txPower > 14 /*25mW*/ ? READONLY_ROW : (uint8_t)0, // Telemetry
IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_TELEMETRY_25MW, 0),
- IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_FPORT, 0),
- IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_FPORT2, 0),
+ uint8_t((IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT) || IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT2)) ? 0 : HIDDEN_ROW),
uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW),
uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW),
0 // channels ...
@@ -171,21 +178,19 @@ bool menuModelReceiverOptions(event_t event)
}
break;
- case ITEM_RECEIVER_SETTINGS_SPORT_FPORT:
- lcdDrawText(MENUS_MARGIN_LEFT, y, "F.Port");
- reusableBuffer.hardwareAndSettings.receiverSettings.fport = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.fport, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event);
- if (attr && checkIncDec_Ret) {
- reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY;
- }
- break;
-
- case ITEM_RECEIVER_SETTINGS_FPORT2:
- lcdDrawText(MENUS_MARGIN_LEFT, y, "F.Port2");
- reusableBuffer.hardwareAndSettings.receiverSettings.fport2 = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.fport2, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event);
- if (attr && checkIncDec_Ret) {
+ case ITEM_RECEIVER_SETTINGS_SPORT_MODE:
+ {
+ lcdDrawText(0, y, STR_PROTOCOL);
+ uint8_t portType = reusableBuffer.hardwareAndSettings.receiverSettings.fport | (reusableBuffer.hardwareAndSettings.receiverSettings.fport2 << 1);
+ lcdDrawTextAtIndex(LCD_W/2, y, STR_SPORT_MODES, portType, attr);
+ portType = checkIncDec(event, portType, 0, 2, EE_MODEL, isSPortModeAvailable);
+ if (checkIncDec_Ret) {
+ reusableBuffer.hardwareAndSettings.receiverSettings.fport = portType & 0x01;
+ reusableBuffer.hardwareAndSettings.receiverSettings.fport2 = (portType & 0x02) >> 1;
reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY;
}
break;
+ }
case ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1:
lcdDrawText(LCD_W/2, y+1, STR_MORE_OPTIONS_AVAILABLE, SMLSIZE|CENTERED);
diff --git a/radio/src/gui/480x272/model_select.cpp b/radio/src/gui/480x272/model_select.cpp
index 661edd814..cd0122ed4 100644
--- a/radio/src/gui/480x272/model_select.cpp
+++ b/radio/src/gui/480x272/model_select.cpp
@@ -246,6 +246,7 @@ void onModelSelectMenu(const char * result)
if (!confirmModelChange())
return;
}
+
// we store the latest changes if any
storageFlushCurrentModel();
storageCheck(true);
diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp
index a620b5685..cd9974ac5 100644
--- a/radio/src/gui/480x272/model_setup.cpp
+++ b/radio/src/gui/480x272/model_setup.cpp
@@ -577,7 +577,7 @@ void onModelAntennaSwitchConfirm(const char * result)
MODULE_TYPE_ROWS(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE*/ \
MULTIMODULE_STATUS_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS, ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS */ \
MODULE_CHANNELS_ROWS(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS*/ \
- IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(IF_INTERNAL_MODULE_ON(isModuleRxNumAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1))), /* *ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE */\
+ IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, MODULE_BIND_ROWS(INTERNAL_MODULE)), /* *ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE */\
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM*/ \
MODULE_OPTION_ROW(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS */ \
MULTIMODULE_MODULE_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND */ \
@@ -1549,6 +1549,7 @@ bool menuModelSetup(event_t event)
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER);
int l_posHorz = menuHorizontalPosition;
coord_t bindButtonPos = MODEL_SETUP_2ND_COLUMN;
+ // RXNUM
if (isModuleRxNumAvailable(moduleIdx)) {
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0 | LEFT, 2);
bindButtonPos += 40;
@@ -1572,12 +1573,13 @@ bool menuModelSetup(event_t event)
else if (attr) {
l_posHorz += 1;
}
+ // BIND - RANGE
if (isModuleBindRangeAvailable(moduleIdx)) {
drawButton(bindButtonPos, y, STR_MODULE_BIND, (moduleState[moduleIdx].mode == MODULE_MODE_BIND ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==1 ? attr : 0));
if (isModuleRangeAvailable(moduleIdx)) {
drawButton(bindButtonPos + 80, y, STR_MODULE_RANGE, (moduleState[moduleIdx].mode == MODULE_MODE_RANGECHECK ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==2 ? attr : 0));
}
- uint8_t newFlag = 0;
+ uint8_t newFlag = MODULE_MODE_NORMAL;
#if defined(MULTIMODULE)
if (getMultiBindStatus(moduleIdx) == MULTI_BIND_FINISHED) {
setMultiBindStatus(moduleIdx, MULTI_NORMAL_OPERATION);
diff --git a/radio/src/gui/common/stdlcd/model_receiver_options.cpp b/radio/src/gui/common/stdlcd/model_receiver_options.cpp
index de3547b75..fe5affb15 100644
--- a/radio/src/gui/common/stdlcd/model_receiver_options.cpp
+++ b/radio/src/gui/common/stdlcd/model_receiver_options.cpp
@@ -47,8 +47,7 @@ enum {
ITEM_RECEIVER_SETTINGS_PWM_RATE,
ITEM_RECEIVER_SETTINGS_TELEMETRY,
ITEM_RECEIVER_SETTINGS_TELEMETRY_25MW,
- ITEM_RECEIVER_SETTINGS_SPORT_FPORT,
- ITEM_RECEIVER_SETTINGS_FPORT2,
+ ITEM_RECEIVER_SETTINGS_SPORT_MODE,
ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1,
ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED2,
ITEM_RECEIVER_SETTINGS_PINMAP_FIRST
@@ -60,6 +59,15 @@ enum {
#define CH_ENABLE_SPORT 4
#define CH_ENABLE_SBUS 5
+bool isSPortModeAvailable(int mode)
+{
+ uint8_t receiverId = reusableBuffer.hardwareAndSettings.receiverSettings.receiverId;
+ if (mode == 2 && !IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT2)) {
+ return false;
+ }
+ return true;
+}
+
void menuModelReceiverOptions(event_t event)
{
const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2;
@@ -82,8 +90,7 @@ void menuModelReceiverOptions(event_t event)
0, // PWM rate
isModuleR9MAccess(g_moduleIdx) && receiverVariant == PXX2_VARIANT_EU && reusableBuffer.hardwareAndSettings.moduleSettings.txPower > 14 /*25mW*/ ? READONLY_ROW : (uint8_t)0, // Telemetry
IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_TELEMETRY_25MW, 0),
- IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_FPORT, 0),
- IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_FPORT2, 0),
+ uint8_t((IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT) || IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT2)) ? 0 : HIDDEN_ROW),
uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW),
uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW),
0 // channels ...
@@ -166,19 +173,19 @@ void menuModelReceiverOptions(event_t event)
}
break;
- case ITEM_RECEIVER_SETTINGS_SPORT_FPORT:
- reusableBuffer.hardwareAndSettings.receiverSettings.fport = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.fport, RECEIVER_OPTIONS_2ND_COLUMN, y, "F.Port", attr, event);
- if (attr && checkIncDec_Ret) {
- reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY;
- }
- break;
-
- case ITEM_RECEIVER_SETTINGS_FPORT2:
- reusableBuffer.hardwareAndSettings.receiverSettings.fport2 = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.fport2, RECEIVER_OPTIONS_2ND_COLUMN, y, "F.Port2", attr, event);
- if (attr && checkIncDec_Ret) {
+ case ITEM_RECEIVER_SETTINGS_SPORT_MODE:
+ {
+ lcdDrawText(0, y, STR_PROTOCOL);
+ uint8_t portType = reusableBuffer.hardwareAndSettings.receiverSettings.fport | (reusableBuffer.hardwareAndSettings.receiverSettings.fport2 << 1);
+ lcdDrawTextAtIndex(LCD_W/2, y, STR_SPORT_MODES, portType, attr);
+ portType = checkIncDec(event, portType, 0, 2, EE_MODEL, isSPortModeAvailable);
+ if (checkIncDec_Ret) {
+ reusableBuffer.hardwareAndSettings.receiverSettings.fport = portType & 0x01;
+ reusableBuffer.hardwareAndSettings.receiverSettings.fport2 = (portType & 0x02) >> 1;
reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY;
}
break;
+ }
case ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1:
lcdDrawText(LCD_W/2, y+1, STR_MORE_OPTIONS_AVAILABLE, SMLSIZE|CENTERED);
diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp
index fca6e047c..1bc66768d 100644
--- a/radio/src/gui/common/stdlcd/radio_hardware.cpp
+++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp
@@ -195,7 +195,9 @@ enum {
ITEM_RADIO_HARDWARE_MAX
};
-#if (NUM_POTS + NUM_SLIDERS) == 1
+#if (NUM_POTS + NUM_SLIDERS) == 0
+ #define POTS_ROWS HIDDEN_ROW
+#elif (NUM_POTS + NUM_SLIDERS) == 1
#define POTS_ROWS NAVIGATION_LINE_BY_LINE|1
#elif (NUM_POTS + NUM_SLIDERS) == 2
#define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1
@@ -238,20 +240,20 @@ enum {
#endif
#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA)
-#define EXTERNAL_ANTENNA_ROW 0,
-void onHardwareAntennaSwitchConfirm(const char * result)
-{
- if (result == STR_OK) {
- // Switch to external antenna confirmation
- g_eeGeneral.antennaMode = reusableBuffer.radioHardware.antennaMode;
- storageDirty(EE_GENERAL);
+ #define EXTERNAL_ANTENNA_ROW 0,
+ void onHardwareAntennaSwitchConfirm(const char * result)
+ {
+ if (result == STR_OK) {
+ // Switch to external antenna confirmation
+ g_eeGeneral.antennaMode = reusableBuffer.radioHardware.antennaMode;
+ storageDirty(EE_GENERAL);
+ }
+ else {
+ reusableBuffer.radioHardware.antennaMode = g_eeGeneral.antennaMode;
+ }
}
- else {
- reusableBuffer.radioHardware.antennaMode = g_eeGeneral.antennaMode;
- }
-}
#else
-#define EXTERNAL_ANTENNA_ROW
+ #define EXTERNAL_ANTENNA_ROW
#endif
#if defined(PCBX9LITE)
@@ -262,7 +264,7 @@ void onHardwareAntennaSwitchConfirm(const char * result)
#define SWITCH_TYPE_MAX(sw) (SWITCH_3POS)
#elif defined(PCBX9E)
#define SWITCH_TYPE_MAX(sw) ((MIXSRC_SF - MIXSRC_FIRST_SWITCH == sw || MIXSRC_SH - MIXSRC_FIRST_SWITCH == sw) ? SWITCH_2POS : SWITCH_3POS)
-#elif defined(RADIO_TX12)
+#elif defined(RADIO_TX12) || defined(RADIO_T8)
#define SWITCH_TYPE_MAX(sw) ((MIXSRC_SA - MIXSRC_FIRST_SWITCH == sw || MIXSRC_SD - MIXSRC_FIRST_SWITCH == sw) ? SWITCH_2POS : SWITCH_3POS)
#else
#define SWITCH_TYPE_MAX(sw) ((MIXSRC_SF - MIXSRC_FIRST_SWITCH == sw || MIXSRC_SH - MIXSRC_FIRST_SWITCH <= sw) ? SWITCH_2POS : SWITCH_3POS)
@@ -322,35 +324,27 @@ void menuRadioHardware(event_t event)
MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, HEADER_LINE + ITEM_RADIO_HARDWARE_MAX, {
HEADER_LINE_COLUMNS
0 /* calibration button */,
- 0 /* stick 1 */,
- 0 /* stick 2 */,
- 0 /* stick 3 */,
- 0 /* stick 4 */,
+ 0 /* stick 1 */,
+ 0 /* stick 2 */,
+ 0 /* stick 3 */,
+ 0 /* stick 4 */,
LABEL(Pots),
- POTS_ROWS,
+ POTS_ROWS,
LABEL(Switches),
- SWITCHES_ROWS,
-
+ SWITCHES_ROWS,
0 /* battery calib */,
RTC_ROW
TX_CAPACITY_MEASUREMENT_ROWS
-
MAX_BAUD_ROWS
-
BLUETOOTH_ROWS
-
EXTERNAL_ANTENNA_ROW
-
AUX_SERIAL_ROWS
-
0 /* ADC filter */,
READONLY_ROW /* RAS */,
SPORT_POWER_ROWS
1 /* debugs */,
-
- 0,
-
- 0
+ 0 /* EEPROM backup */,
+ 0 /* Factory reset */
});
uint8_t sub = menuVerticalPosition - HEADER_LINE;
diff --git a/radio/src/gui/common/stdlcd/view_telemetry.cpp b/radio/src/gui/common/stdlcd/view_telemetry.cpp
index ecdb96aa9..07a31442c 100644
--- a/radio/src/gui/common/stdlcd/view_telemetry.cpp
+++ b/radio/src/gui/common/stdlcd/view_telemetry.cpp
@@ -34,7 +34,7 @@ enum NavigationDirection {
#if defined(NAVIGATION_XLITE)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_LEFT) && IS_SHIFT_PRESSED())
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_RIGHT) && IS_SHIFT_PRESSED())
-#elif defined(NAVIGATION_X7_TX12)
+#elif defined(KEYS_GPIO_REG_PAGEDN)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEUP))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEDN))
#elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D)
diff --git a/radio/src/gui/navigation/navigation_x7.cpp b/radio/src/gui/navigation/navigation_x7.cpp
index ac4a4bbdd..7e4255dac 100644
--- a/radio/src/gui/navigation/navigation_x7.cpp
+++ b/radio/src/gui/navigation/navigation_x7.cpp
@@ -56,8 +56,11 @@ void onSwitchLongEnterPress(const char * result)
int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops)
{
int newval = val;
-
+#if defined(ROTARY_ENCODER_NAVIGATION)
if (s_editMode>0 && event==EVT_ROTARY_RIGHT) {
+#else
+ if (s_editMode>0 && (event==EVT_KEY_FIRST(KEY_PLUS) || event==EVT_KEY_REPT(KEY_PLUS))) {
+#endif
newval += min(rotencSpeed, i_max-val);
while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max) {
newval++;
@@ -67,7 +70,11 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla
AUDIO_KEY_ERROR();
}
}
+#if defined(ROTARY_ENCODER_NAVIGATION)
else if (s_editMode>0 && event==EVT_ROTARY_LEFT) {
+#else
+ if (s_editMode>0 && (event==EVT_KEY_FIRST(KEY_MINUS) || event==EVT_KEY_REPT(KEY_MINUS))) {
+#endif
newval -= min(rotencSpeed, val-i_min);
while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min) {
newval--;
@@ -217,7 +224,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
if (menuTab) {
int cc = curr;
switch (event) {
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEUP)
case EVT_KEY_FIRST(KEY_PAGEUP):
#else
case EVT_KEY_LONG(KEY_PAGE):
@@ -232,7 +239,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
killEvents(event);
break;
-#if defined(NAVIGATION_X7_TX12)
+#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_FIRST(KEY_PAGEDN):
#else
case EVT_KEY_BREAK(KEY_PAGE):
@@ -310,12 +317,14 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
}
}
break;
-
+#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_RIGHT:
- case EVT_KEY_FIRST(KEY_RIGHT):
AUDIO_KEY_PRESS();
// no break
- case EVT_KEY_REPT(KEY_RIGHT):
+#else
+ case EVT_KEY_FIRST(KEY_DOWN):
+ case EVT_KEY_REPT(KEY_DOWN):
+#endif
if (s_editMode > 0) break; // TODO it was !=
if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) {
if (l_posHorz >= 0) {
@@ -341,12 +350,14 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t
l_posHorz = POS_HORZ_INIT(l_posVert);
break;
-
+#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_LEFT:
- case EVT_KEY_FIRST(KEY_LEFT):
AUDIO_KEY_PRESS();
// no break
- case EVT_KEY_REPT(KEY_LEFT):
+#else
+ case EVT_KEY_FIRST(KEY_UP):
+ case EVT_KEY_REPT(KEY_UP):
+#endif
if (s_editMode > 0) break; // TODO it was !=
if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) {
if (l_posHorz >= 0) {
diff --git a/radio/src/keys.h b/radio/src/keys.h
index 44c1e53fe..0d4bc37dc 100644
--- a/radio/src/keys.h
+++ b/radio/src/keys.h
@@ -82,6 +82,11 @@ inline bool IS_KEY_EVT(event_t evt, uint8_t key)
#define EVT_ROTARY_RIGHT 0xDE00
#define IS_NEXT_EVENT(event) (event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))
#define IS_PREVIOUS_EVENT(event) (event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP))
+#elif defined(RADIO_T8)
+ #define EVT_ROTARY_BREAK EVT_KEY_BREAK(KEY_ENTER)
+ #define EVT_ROTARY_LONG EVT_KEY_LONG(KEY_ENTER)
+ #define IS_NEXT_EVENT(event) (event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))
+ #define IS_PREVIOUS_EVENT(event) (event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP))
#elif (defined(PCBHORUS) || defined(PCBTARANIS)) && defined(ROTARY_ENCODER_NAVIGATION)
#define EVT_ROTARY_BREAK EVT_KEY_BREAK(KEY_ENTER)
#define EVT_ROTARY_LONG EVT_KEY_LONG(KEY_ENTER)
diff --git a/radio/src/lua/CMakeLists.txt b/radio/src/lua/CMakeLists.txt
index 5b89c1f65..fee1d9f15 100644
--- a/radio/src/lua/CMakeLists.txt
+++ b/radio/src/lua/CMakeLists.txt
@@ -29,5 +29,6 @@ if(PYTHONINTERP_FOUND)
add_lua_export_target(x12s ${LUA_INCLUDES} -DPCBHORUS -DPCBX12S)
add_lua_export_target(t12 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_T12)
add_lua_export_target(tx12 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_TX12)
+ add_lua_export_target(t8 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_T8)
add_lua_export_target(t16 ${LUA_INCLUDES} -DPCBHORUS -DPCBX10 -DRADIO_T16)
endif()
diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp
index 37634ae1c..b3c3f5ee8 100644
--- a/radio/src/lua/api_general.cpp
+++ b/radio/src/lua/api_general.cpp
@@ -42,6 +42,8 @@
#include "lua/lua_exports_t12.inc"
#elif defined(RADIO_TX12)
#include "lua/lua_exports_tx12.inc"
+#elif defined(RADIO_T8)
+ #include "lua/lua_exports_t8.inc"
#elif defined(PCBX9LITES)
#include "lua/lua_exports_x9lites.inc"
#elif defined(PCBX9LITE)
@@ -1779,11 +1781,11 @@ const luaR_value_entry opentxConstants[] = {
{ "MIXSRC_SE", MIXSRC_SE },
{ "MIXSRC_SG", MIXSRC_SG },
#endif
-#if !defined(PCBXLITE) && !defined(PCBX9LITE)
+#if defined(HARDWARE_SWITCH_F)
{ "MIXSRC_SF", MIXSRC_SF },
-#if !defined(RADIO_TX12)
- { "MIXSRC_SH", MIXSRC_SH },
#endif
+#if defined(HARDWARE_SWITCH_H)
+ { "MIXSRC_SH", MIXSRC_SH },
#endif
{ "MIXSRC_CH1", MIXSRC_CH1 },
{ "SWSRC_LAST", SWSRC_LAST_LOGICAL_SWITCH },
@@ -1845,7 +1847,7 @@ const luaR_value_entry opentxConstants[] = {
{ "ROTENC_LOWSPEED", ROTENC_LOWSPEED },
{ "ROTENC_MIDSPEED", ROTENC_MIDSPEED },
{ "ROTENC_HIGHSPEED", ROTENC_HIGHSPEED },
-#elif defined(PCBX9D) || defined(PCBX9DP) // key reverted between field nav and value change
+#elif defined(PCBX9D) || defined(PCBX9DP) || defined(RADIO_T8) // key reverted between field nav and value change
{ "EVT_VIRTUAL_PREV", EVT_KEY_FIRST(KEY_PLUS) },
{ "EVT_VIRTUAL_PREV_REPT", EVT_KEY_REPT(KEY_PLUS) },
{ "EVT_VIRTUAL_NEXT", EVT_KEY_FIRST(KEY_MINUS) },
@@ -1882,7 +1884,7 @@ const luaR_value_entry opentxConstants[] = {
{ "EVT_VIRTUAL_ENTER_LONG", EVT_KEY_LONG(KEY_ENTER) },
{ "EVT_VIRTUAL_EXIT", EVT_KEY_BREAK(KEY_EXIT) },
#elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D)
-#if defined(RADIO_TX12)
+#if defined(RADIO_TX12) || defined(RADIO_T8)
{ "EVT_VIRTUAL_PREV_PAGE", EVT_KEY_BREAK(KEY_PAGEUP) },
{ "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_BREAK(KEY_PAGEDN) },
{ "EVT_VIRTUAL_MENU", EVT_KEY_BREAK(KEY_MODEL) },
diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp
index a0cef2c1d..81ac4472a 100644
--- a/radio/src/lua/interface.cpp
+++ b/radio/src/lua/interface.cpp
@@ -745,11 +745,23 @@ void displayLuaError(const char * title)
if (lua_warning_info[0]) {
char * split = strstr(lua_warning_info, ": ");
if (split) {
- lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y+FH+3, lua_warning_info, split-lua_warning_info, SMLSIZE);
- lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y+2*FH+2, split+2, lua_warning_info+LUA_WARNING_INFO_LEN-split, SMLSIZE);
+#if LCD_W == 128
+ if (strlen(split + 2) <= 20) {
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + FH + 3, lua_warning_info, split - lua_warning_info, SMLSIZE);
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + 2 * FH + 2, split + 2, strlen(split + 2), SMLSIZE);
+ }
+ else {
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + FH, lua_warning_info, split - lua_warning_info, SMLSIZE);
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + 2 * FH, split + 2, 20, SMLSIZE);
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + 3 * FH, split + 22, strlen(split + 22), SMLSIZE);
+ }
+#else
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + FH + 3, lua_warning_info, split - lua_warning_info, SMLSIZE);
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + 2 * FH + 2, split + 2, lua_warning_info + LUA_WARNING_INFO_LEN - split, SMLSIZE);
+#endif
}
else {
- lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y+FH+3, lua_warning_info, 40, SMLSIZE);
+ lcdDrawSizedText(WARNING_LINE_X, WARNING_LINE_Y + FH + 3, lua_warning_info, 40, SMLSIZE);
}
}
}
@@ -787,7 +799,11 @@ void luaError(lua_State * L, uint8_t error, bool acknowledge)
#if defined(SIMU)
if (!strncmp(msg, ".", 2)) msg += 1;
#endif
+#if LCD_W == 128
+ msg = strrchr(msg, '/') + 1;
+#else
if (!strncmp(msg, "/SCRIPTS/", 9)) msg += 9;
+#endif
strncpy(lua_warning_info, msg, LUA_WARNING_INFO_LEN);
lua_warning_info[LUA_WARNING_INFO_LEN] = '\0';
}
diff --git a/radio/src/main.cpp b/radio/src/main.cpp
index db12ee20f..8ff9cd736 100644
--- a/radio/src/main.cpp
+++ b/radio/src/main.cpp
@@ -531,6 +531,10 @@ void perMain()
}
#endif
+#if defined(KEYS_GPIO_REG_BIND) && defined(BIND_KEY)
+ bindButtonHandler(evt);
+#endif
+
#if defined(GUI)
DEBUG_TIMER_START(debugTimerGuiMain);
guiMain(evt);
diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp
index bebb5b317..2a75c4033 100644
--- a/radio/src/opentx.cpp
+++ b/radio/src/opentx.cpp
@@ -334,6 +334,14 @@ void generalDefault()
setDefaultOwnerId();
#endif
+#if defined(RADIOMASTER_RTF_RELEASE)
+ // Those settings are for headless radio
+ g_eeGeneral.USBMode = USB_JOYSTICK_MODE;
+ g_eeGeneral.disableRtcWarning = 1;
+ g_eeGeneral.splashMode = 3; // Disable splash
+ g_eeGeneral.pwrOnSpeed = 1; // 1 second
+#endif
+
g_eeGeneral.chkSum = 0xFFFF;
}
@@ -523,6 +531,15 @@ void modelDefault(uint8_t id)
g_model.switchWarningState |= (1 << (3*i));
}
#endif
+
+#if defined(RADIOMASTER_RTF_RELEASE)
+ // Those settings are for headless radio
+ g_model.trainerData.mode = TRAINER_MODE_SLAVE;
+ g_model.moduleData[INTERNAL_MODULE].type = MODULE_TYPE_MULTIMODULE;
+ g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKY);
+ g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKY_SUBTYPE_D8;
+ g_model.moduleData[INTERNAL_MODULE].failsafeMode = FAILSAFE_NOPULSES;
+#endif
}
bool isInputRecursive(int index)
@@ -917,7 +934,7 @@ void checkAll()
checkFailsafe();
checkRSSIAlarmsDisabled();
-#if defined(SDCARD)
+#if defined(SDCARD) && !defined(RADIOMASTER_RTF_RELEASE)
checkSDVersion();
#endif
@@ -2196,6 +2213,7 @@ uint32_t pwrCheck()
#endif
event_t evt = getEvent(false);
DISPLAY_WARNING(evt);
+ LED_ERROR_BEGIN();
lcdRefresh();
if (warningResult) {
@@ -2205,6 +2223,7 @@ uint32_t pwrCheck()
else if (!warningText) {
// shutdown has been cancelled
pwr_check_state = PWR_CHECK_PAUSED;
+ LED_ERROR_END();
return e_power_on;
}
}
diff --git a/radio/src/opentx.h b/radio/src/opentx.h
index 6d028ff06..d0f6fccaf 100644
--- a/radio/src/opentx.h
+++ b/radio/src/opentx.h
@@ -69,6 +69,12 @@
#define CASE_GYRO(x)
#endif
+#if defined(BACKLIGHT_GPIO)
+#define CASE_BACKLIGHT(x) x,
+#else
+#define CASE_BACKLIGHT(x)
+#endif
+
#if defined(LUA)
#define CASE_LUA(x) x,
#else
@@ -382,6 +388,8 @@ inline bool SPLASH_NEEDED()
#define ROTENC_HIGHSPEED 50
#define ROTENC_DELAY_MIDSPEED 32
#define ROTENC_DELAY_HIGHSPEED 16
+#elif defined(RADIO_T8)
+ constexpr uint8_t rotencSpeed = 1;
#endif
constexpr uint8_t HEART_TIMER_10MS = 0x01;
@@ -437,6 +445,10 @@ extern uint8_t potsPos[NUM_XPOTS];
bool trimDown(uint8_t idx);
void readKeysAndTrims();
+#if defined(KEYS_GPIO_REG_BIND)
+void bindButtonHandler(event_t event);
+#endif
+
uint16_t evalChkSum();
void alert(const char * title, const char * msg, uint8_t sound);
@@ -998,7 +1010,13 @@ constexpr uint8_t OPENTX_START_NO_CHECKS = 0x04;
#if defined(STATUS_LEDS)
#define LED_ERROR_BEGIN() ledRed()
+#if defined(RADIO_T8)
+ // Because of green backlit logo, green is preferred on this radio
+ #define LED_ERROR_END() ledGreen()
+ #define LED_BIND() ledBlue()
+#else
#define LED_ERROR_END() ledBlue()
+#endif
#else
#define LED_ERROR_BEGIN()
#define LED_ERROR_END()
diff --git a/radio/src/options.h b/radio/src/options.h
index bc50f70fd..8592897af 100644
--- a/radio/src/options.h
+++ b/radio/src/options.h
@@ -98,6 +98,9 @@ static const char * const options[] = {
#endif
#if defined(HARDWARE_EXTERNAL_ACCESS_MOD)
"externalaccessmod",
+#endif
+#if defined(BIND_KEY)
+ "bindkey",
#endif
nullptr //sentinel
};
diff --git a/radio/src/pulses/modules_constants.h b/radio/src/pulses/modules_constants.h
index 15a2c2283..6fbec157e 100644
--- a/radio/src/pulses/modules_constants.h
+++ b/radio/src/pulses/modules_constants.h
@@ -203,6 +203,14 @@ enum MMRFrskySubtypes {
MM_RF_FRSKY_SUBTYPE_D16_CLONED
};
+enum MMRFrskyX2Subtypes {
+ MM_RF_FRSKYX2_SUBTYPE_D16,
+ MM_RF_FRSKYX2_SUBTYPE_D8,
+ MM_RF_FRSKYX2_SUBTYPE_D16_LBT,
+ MM_RF_FRSKYX2_SUBTYPE_D16_LBT_8CH,
+ MM_RF_FRSKYX2_SUBTYPE_D16_CLONED
+};
+
enum ModuleSubtypeDSM2 {
DSM2_PROTO_LP45,
DSM2_PROTO_DSM2,
diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h
index fc9a06b92..b6888f1f8 100644
--- a/radio/src/sdcard.h
+++ b/radio/src/sdcard.h
@@ -145,6 +145,8 @@ const char * getBasename(const char * path);
#define OTX_FOURCC 0x3D78746F // otx for Jumper T12
#elif defined(RADIO_TX12)
#define OTX_FOURCC 0x4178746F // otx for Radiomaster TX12
+#elif defined(RADIO_T8)
+ #define OTX_FOURCC 0x4378746F // otx for Radiomaster T8
#elif defined(PCBX7)
#define OTX_FOURCC 0x3678746F // otx for Taranis X7 / X7S / X7 Express / X7S Express
#elif defined(PCBX9LITES)
diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp
index 6d086e100..2e9c6a89e 100644
--- a/radio/src/simu.cpp
+++ b/radio/src/simu.cpp
@@ -273,6 +273,15 @@ void OpenTxSim::updateKeysAndSwitches(bool start)
KEY_Down, KEY_EXIT,
KEY_Right, KEY_TELE,
KEY_Left, KEY_SYS,
+#elif defined(RADIO_T8)
+ KEY_Page_Up, KEY_PAGEUP,
+ KEY_Page_Down, KEY_PAGEDN,
+ KEY_Return, KEY_ENTER,
+ KEY_Right, KEY_MODEL,
+ KEY_BackSpace, KEY_EXIT,
+ KEY_Left, KEY_SYS,
+ KEY_Up, KEY_PLUS,
+ KEY_Down, KEY_MINUS,
#elif defined(PCBTARANIS)
KEY_Page_Up, KEY_MENU,
#if defined(KEYS_GPIO_REG_PAGE)
diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp
index da86cebe8..40bac6a67 100644
--- a/radio/src/storage/storage_common.cpp
+++ b/radio/src/storage/storage_common.cpp
@@ -53,6 +53,13 @@ void preModelLoad()
}
pauseMixerCalculations();
+#if defined(INTMODULE_PWR_GPIO)
+ INTERNAL_MODULE_OFF();
+#endif
+#if defined(EXTMODULE_PWR_GPIO)
+ EXTERNAL_MODULE_OFF();
+#endif
+
stopTrainer();
}
diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp
index bf230850d..727b05096 100644
--- a/radio/src/switches.cpp
+++ b/radio/src/switches.cpp
@@ -663,6 +663,9 @@ void checkSwitches()
}
int x = SWITCH_WARNING_LIST_X;
int y = SWITCH_WARNING_LIST_Y;
+#if defined(COLORLCD)
+ lcdNextPos = SWITCH_WARNING_LIST_X;
+#endif
int numWarnings = 0;
for (int i=0; iSQR2 = (ADC_CHANNEL_BATT << 0) + (ADC_Channel_Vbat << 5);
ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_POT2 << 25);
}
+#elif defined(RADIO_T8)
+ ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT << 0) + (ADC_Channel_Vbat << 5);
+ ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15);
#elif defined(PCBX7)
ADC_MAIN->SQR2 = (ADC_CHANNEL_BATT << 0) + (ADC_Channel_Vbat << 5);
ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_POT2 << 25);
diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt
index 55bcdeb66..1a69afdff 100644
--- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt
+++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt
@@ -89,7 +89,7 @@ set(BOOTLOADER_SRC
bin_files.cpp
)
-if(PCB STREQUAL X12S OR PCB STREQUAL X10 OR PCB STREQUAL X9E OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR (PCB STREQUAL X7 AND NOT (PCBREV STREQUAL T12)) OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES)
+if(PCB STREQUAL X12S OR PCB STREQUAL X10 OR PCB STREQUAL X9E OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR (PCB STREQUAL X7 AND NOT (PCBREV STREQUAL T12 OR PCBREV STREQUAL T8)) OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES)
set(BOOTLOADER_SRC
${BOOTLOADER_SRC}
../../../../../targets/common/arm/stm32/rotary_encoder_driver.cpp
diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp
index b849fa8a2..e94ae4756 100644
--- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp
+++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp
@@ -218,8 +218,13 @@ int main()
}
}
+#if defined(RADIO_T8) && !defined(RADIOMASTER_RELEASE)
+ // Bind button not pressed
+ if ((~KEYS_GPIO_REG_BIND & KEYS_GPIO_PIN_BIND) == false) {
+#else
// LHR & RHL trims not pressed simultanously
if (readTrims() != BOOTLOADER_KEYS) {
+#endif
// Start main application
jumpTo(APP_START_ADDRESS);
}
diff --git a/radio/src/targets/common/arm/stm32/pwr_driver.cpp b/radio/src/targets/common/arm/stm32/pwr_driver.cpp
index 220b5fdfd..32ff59195 100644
--- a/radio/src/targets/common/arm/stm32/pwr_driver.cpp
+++ b/radio/src/targets/common/arm/stm32/pwr_driver.cpp
@@ -80,7 +80,7 @@ void pwrInit()
GPIO_Init(SD_PRESENT_GPIO, &GPIO_InitStructure);
#endif
-#if defined(INTMODULE_USART) && defined(TRAINER_MODULE_CPPM_GPIO_PIN)
+#if defined(INTMODULE_USART) && defined(TRAINER_MODULE_CPPM)
GPIO_SetBits(TRAINER_MODULE_CPPM_GPIO, TRAINER_MODULE_CPPM_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = TRAINER_MODULE_CPPM_GPIO_PIN;
GPIO_Init(TRAINER_MODULE_CPPM_GPIO, &GPIO_InitStructure);
diff --git a/radio/src/targets/sky9x/CMakeLists.txt b/radio/src/targets/sky9x/CMakeLists.txt
index 842035bde..d09906965 100644
--- a/radio/src/targets/sky9x/CMakeLists.txt
+++ b/radio/src/targets/sky9x/CMakeLists.txt
@@ -12,6 +12,7 @@ set(PPM_LIMITS_SYMETRICAL YES)
set(PXX1 YES)
set(AFHDS3 NO)
set(GHOST NO)
+add_definitions(-DHARDWARE_EXTERNAL_MODULE)
add_definitions(-DDISABLE_MULTI_UPDATE)
if(PCB STREQUAL 9XRPRO)
diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt
index b7e1ea590..a33500216 100644
--- a/radio/src/targets/taranis/CMakeLists.txt
+++ b/radio/src/targets/taranis/CMakeLists.txt
@@ -6,6 +6,9 @@ option(AFHDS3 "AFHDS3 TX Module" ON)
option(GHOST "Ghost TX Module" ON)
option(INTERNAL_MODULE_PPM "Support for PPM internal module" OFF)
option(AUTOUPDATE "Auto update internal chips from SD" OFF)
+option(BIND_KEY "Enable bind button" OFF)
+
+set(EXTERNAL_MODULE YES)
if(PCB STREQUAL X9E)
option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON)
@@ -144,6 +147,24 @@ elseif(PCB STREQUAL X7)
add_definitions(-DRADIO_TX12)
add_definitions(-DEEPROM_VARIANT=0x4002)
add_definitions(-DMANUFACTURER_RADIOMASTER)
+ elseif(PCBREV STREQUAL T8)
+ option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" ON)
+ set(EXTERNAL_MODULE NO)
+ set(AFHDS3 NO)
+ set(FLAVOUR t8)
+ set(NAVIGATION_TYPE x7)
+ set(CPU_TYPE STM32F2)
+ set(CPU_TYPE_FULL STM32F205xE) # for size report
+ set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld)
+ set(ROTARY_ENCODER NO)
+ set(LUA_EXPORT lua_export_t8)
+ set(BLUETOOTH NO)
+ if(RADIOMASTER_RELEASE)
+ set(BIND_KEY YES)
+ endif()
+ add_definitions(-DRADIO_T8)
+ add_definitions(-DEEPROM_VARIANT=0x4004)
+ add_definitions(-DMANUFACTURER_RADIOMASTER)
elseif(PCBREV STREQUAL ACCESS)
option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF)
option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON)
@@ -334,6 +355,14 @@ if(ROTARY_ENCODER)
)
endif()
+if(BIND_KEY)
+ set(TARGET_SRC
+ ${TARGET_SRC}
+ bind_button_driver.cpp
+ )
+ add_definitions(-DBIND_KEY)
+endif()
+
if(USB_CHARGER)
set(TARGET_SRC ${TARGET_SRC} usb_charger_driver.cpp)
add_definitions(-DUSB_CHARGER)
@@ -455,4 +484,8 @@ if(INTERNAL_MODULE_PPM)
add_definitions(-DINTERNAL_MODULE_PPM)
endif()
+if(EXTERNAL_MODULE)
+ add_definitions(-DHARDWARE_EXTERNAL_MODULE)
+endif()
+
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET})
diff --git a/radio/src/targets/taranis/backlight_driver.cpp b/radio/src/targets/taranis/backlight_driver.cpp
index 63a5bfd1a..7c758f818 100644
--- a/radio/src/targets/taranis/backlight_driver.cpp
+++ b/radio/src/targets/taranis/backlight_driver.cpp
@@ -20,7 +20,13 @@
#include "opentx.h"
-#if defined(PCBX9E)
+#if !defined(BACKLIGHT_GPIO)
+ // no backlight
+ void backlightInit() {}
+ void backlightEnable(uint8_t level) {}
+ void backlightDisable() {}
+ uint8_t isBacklightEnabled() {return false;}
+#elif defined(PCBX9E)
void backlightInit()
{
GPIO_InitTypeDef GPIO_InitStructure;
diff --git a/radio/src/targets/taranis/bind_button_driver.cpp b/radio/src/targets/taranis/bind_button_driver.cpp
new file mode 100644
index 000000000..2d3ca63fc
--- /dev/null
+++ b/radio/src/targets/taranis/bind_button_driver.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) OpenTX
+ *
+ * Based on code named
+ * th9x - http://code.google.com/p/th9x
+ * er9x - http://code.google.com/p/er9x
+ * gruvin9x - http://code.google.com/p/gruvin9x
+ *
+ * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "opentx.h"
+
+
+bool setBindProtocolSelection()
+{
+ int16_t xPos = calibratedAnalogs[CONVERT_MODE(0)];
+ int16_t yPos = calibratedAnalogs[CONVERT_MODE(1)];
+
+ // Center: D8
+ if (abs(xPos < 50 && abs(yPos) < 50)) {
+ g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKY);
+ g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKY_SUBTYPE_D8;
+ storageDirty(EE_MODEL);
+ return true;
+ }
+
+ // Top left: D16 FCC
+ if (xPos < -512 && yPos > 512) {
+ g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKY);
+ g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKY_SUBTYPE_D16;
+ g_model.moduleData[INTERNAL_MODULE].failsafeMode = FAILSAFE_NOPULSES;
+ storageDirty(EE_MODEL);
+ return true;
+ }
+
+ // Top right: D16 LBT
+ if (xPos > 512 && yPos > 512) {
+ g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKY);
+ g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKY_SUBTYPE_D16_LBT;
+ g_model.moduleData[INTERNAL_MODULE].failsafeMode = FAILSAFE_NOPULSES;
+ storageDirty(EE_MODEL);
+ return true;
+ }
+
+ // Bottom left: V2.1 D16 FCC
+ if (xPos < -512 && yPos < -512) {
+ g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKYX2);
+ g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKYX2_SUBTYPE_D16;
+ g_model.moduleData[INTERNAL_MODULE].failsafeMode = FAILSAFE_NOPULSES;
+ storageDirty(EE_MODEL);
+ return true;
+ }
+
+ // Bottom right: V2.1 D16 LBT
+ if (xPos > 512 && yPos < -512) {
+ g_model.moduleData[INTERNAL_MODULE].setMultiProtocol(MODULE_SUBTYPE_MULTI_FRSKYX2);
+ g_model.moduleData[INTERNAL_MODULE].subType = MM_RF_FRSKYX2_SUBTYPE_D16_LBT;
+ g_model.moduleData[INTERNAL_MODULE].failsafeMode = FAILSAFE_NOPULSES;
+ storageDirty(EE_MODEL);
+ return true;
+ }
+
+ return false;
+}
+
+void bindButtonHandler(event_t event)
+{
+ if( !isModuleMultimodule(INTERNAL_MODULE))
+ return;
+
+ if (event == EVT_KEY_LONG(KEY_BIND) && getMultiBindStatus(INTERNAL_MODULE) == MULTI_NORMAL_OPERATION) {
+ if (setBindProtocolSelection()) {
+ setMultiBindStatus(INTERNAL_MODULE, MULTI_BIND_INITIATED);
+ moduleState[INTERNAL_MODULE].mode = MODULE_MODE_BIND;
+ }
+ }
+
+ if (getMultiBindStatus(INTERNAL_MODULE) == MULTI_BIND_INITIATED) {
+ if (FAST_BLINK_ON_PHASE)
+ LED_BIND();
+ else
+ ledOff();
+ }
+
+ if (getMultiBindStatus(INTERNAL_MODULE) == MULTI_BIND_FINISHED) {
+ setMultiBindStatus(INTERNAL_MODULE, MULTI_NORMAL_OPERATION);
+ moduleState[INTERNAL_MODULE].mode = MODULE_MODE_NORMAL;
+ LED_ERROR_END();
+ }
+}
diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp
index 97222bce2..69e36d5e8 100644
--- a/radio/src/targets/taranis/board.cpp
+++ b/radio/src/targets/taranis/board.cpp
@@ -273,6 +273,8 @@ void boardOff()
#if defined (RADIO_TX12)
#define BATTERY_DIVIDER 22830
+#elif defined (RADIO_T8)
+ #define BATTERY_DIVIDER 50000
#else
#define BATTERY_DIVIDER 26214
#endif
diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h
index 1b6351377..505ecfdec 100644
--- a/radio/src/targets/taranis/board.h
+++ b/radio/src/targets/taranis/board.h
@@ -27,8 +27,8 @@
#include "board_common.h"
#include "hal.h"
-#if defined(RADIO_TX12)
- #define NAVIGATION_X7_TX12
+#if defined(RADIO_TX12) || defined(RADIO_TX12)
+ #define NAVIGATION_X7_TX12
#endif
#if defined(ROTARY_ENCODER_NAVIGATION)
@@ -152,7 +152,7 @@ void extmoduleSendInvertedByte(uint8_t byte);
// Trainer driver
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
-#if defined(PCBX9D) || (defined(PCBX9DP) && PCBREV < 2019)
+#if defined(TRAINER_DETECT_GPIO)
// Trainer detect is a switch on the jack
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET)
#elif defined(PCBXLITES)
@@ -270,6 +270,10 @@ enum EnumKeys
KEY_COUNT,
KEY_MAX = KEY_COUNT - 1,
+#if defined(KEYS_GPIO_REG_BIND)
+ KEY_BIND,
+#endif
+
#if defined(ROTARY_ENCODER_NAVIGATION)
KEY_PLUS,
KEY_MINUS,
@@ -355,7 +359,7 @@ enum EnumSwitchesPositions
SW_SE1,
SW_SE2,
#endif
-#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || defined(PCBX7) || defined(PCBXLITES) || defined(PCBX9LITES)
+#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || defined(PCBX7) || defined(PCBXLITES) || defined(PCBX9LITES) || defined(RADIO_T8)
SW_SF0,
SW_SF1,
SW_SF2,
@@ -365,7 +369,7 @@ enum EnumSwitchesPositions
SW_SG1,
SW_SG2,
#endif
-#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || (defined(PCBX7) && !defined(RADIO_TX12))
+#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || (defined(PCBX7) && !defined(RADIO_TX12)) || defined(RADIO_T8)
SW_SH0,
SW_SH1,
SW_SH2,
@@ -442,6 +446,11 @@ enum EnumSwitchesPositions
#define STORAGE_NUM_SWITCHES NUM_SWITCHES
#define DEFAULT_SWITCH_CONFIG (SWITCH_3POS << 10) + (SWITCH_3POS << 8) + (SWITCH_TOGGLE << 6) + (SWITCH_3POS << 4) + (SWITCH_3POS << 2) + (SWITCH_TOGGLE << 0)
#define DEFAULT_POTS_CONFIG (POT_WITH_DETENT << 0) + (POT_WITH_DETENT << 2);
+#elif defined(RADIO_T8)
+ #define NUM_SWITCHES 4
+ #define STORAGE_NUM_SWITCHES 8
+ #define DEFAULT_SWITCH_CONFIG (SWITCH_2POS << 6) + (SWITCH_3POS << 4) + (SWITCH_3POS << 2) + (SWITCH_2POS << 0);
+ #define DEFAULT_POTS_CONFIG (0)
#elif defined(PCBX7ACCESS)
#define NUM_SWITCHES 7
#define STORAGE_NUM_SWITCHES 8
@@ -544,6 +553,11 @@ enum Analogs {
#define NUM_SLIDERS 0
#define STORAGE_NUM_POTS 1
#define STORAGE_NUM_SLIDERS 0
+#elif defined(RADIO_T8)
+ #define NUM_POTS 0
+ #define NUM_SLIDERS 0
+ #define STORAGE_NUM_POTS 2
+ #define STORAGE_NUM_SLIDERS 0
#elif defined(PCBXLITE) || defined(PCBX7)
#define NUM_POTS 2
#define NUM_SLIDERS 0
@@ -644,6 +658,11 @@ extern uint16_t adcValues[NUM_ANALOGS];
#define BATTERY_WARN 66 // 6.6V
#define BATTERY_MIN 67 // 6.7V
#define BATTERY_MAX 83 // 8.3V
+#elif defined(RADIO_T8)
+ // 1S Li-ion / Lipo
+ #define BATTERY_WARN 33 // 3.3V
+ #define BATTERY_MIN 32 // 3.2V
+ #define BATTERY_MAX 42 // 4.2V
#else
// NI-MH 7.2V
#define BATTERY_WARN 65 // 6.5V
@@ -710,6 +729,10 @@ uint8_t isBacklightEnabled();
#define USB_NAME "Radiomaster TX12"
#define USB_MANUFACTURER 'R', 'M', '_', 'T', 'X', ' ', ' ', ' ' /* 8 bytes */
#define USB_PRODUCT 'R', 'M', ' ', 'T', 'X', '1', '2', ' ' /* 8 Bytes */
+#elif defined(RADIO_T8)
+ #define USB_NAME "Radiomaster T8"
+ #define USB_MANUFACTURER 'R', 'M', '_', 'T', 'X', ' ', ' ', ' ' /* 8 bytes */
+ #define USB_PRODUCT 'R', 'M', ' ', 'T', '8', ' ', ' ', ' ' /* 8 Bytes */
#else
#define USB_NAME "FrSky Taranis"
#define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */
@@ -864,8 +887,10 @@ void bluetoothDisable();
#endif
// USB Charger
+#if defined(USB_CHARGER)
void usbChargerInit();
bool usbChargerLed();
+#endif
// LED driver
void ledInit();
@@ -889,7 +914,7 @@ void ledBlue();
#define IS_LCD_RESET_NEEDED() true
#define LCD_CONTRAST_MIN 10
#define LCD_CONTRAST_MAX 30
-#if defined(RADIO_TX12)
+#if defined(RADIO_TX12) || defined(RADIO_T8)
#define LCD_CONTRAST_DEFAULT 21
#else
#define LCD_CONTRAST_DEFAULT 15
diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h
index 131eeae4b..541559b81 100644
--- a/radio/src/targets/taranis/hal.h
+++ b/radio/src/targets/taranis/hal.h
@@ -74,6 +74,25 @@
#define KEYS_GPIO_PIN_MDL GPIO_Pin_11 // PE.11
#define KEYS_GPIO_REG_TELE GPIOD->IDR
#define KEYS_GPIO_PIN_TELE GPIO_Pin_2 // PD.02
+#elif defined(RADIO_T8)
+ #define KEYS_GPIO_REG_PAGEUP GPIOD->IDR
+ #define KEYS_GPIO_PIN_PAGEUP GPIO_Pin_3 // PD.03
+ #define KEYS_GPIO_REG_PAGEDN GPIOD->IDR
+ #define KEYS_GPIO_PIN_PAGEDN GPIO_Pin_7 // PD.07
+ #define KEYS_GPIO_REG_EXIT GPIOB->IDR
+ #define KEYS_GPIO_PIN_EXIT GPIO_Pin_3 // PB.03
+ #define KEYS_GPIO_REG_ENTER GPIOA->IDR
+ #define KEYS_GPIO_PIN_ENTER GPIO_Pin_13 // PA.13
+ #define KEYS_GPIO_REG_SYS GPIOB->IDR
+ #define KEYS_GPIO_PIN_SYS GPIO_Pin_4 // PB.04
+ #define KEYS_GPIO_REG_MDL GPIOE->IDR
+ #define KEYS_GPIO_PIN_MDL GPIO_Pin_11 // PE.11
+ #define KEYS_GPIO_REG_PLUS GPIOE->IDR
+ #define KEYS_GPIO_PIN_PLUS GPIO_Pin_9 // PE.09
+ #define KEYS_GPIO_REG_MINUS GPIOE->IDR
+ #define KEYS_GPIO_PIN_MINUS GPIO_Pin_10 // PE.10
+ #define KEYS_GPIO_REG_BIND GPIOA->IDR
+ #define KEYS_GPIO_PIN_BIND GPIO_Pin_10 // PA.10
#elif defined(PCBX7)
#define KEYS_GPIO_REG_PAGE GPIOD->IDR
#define KEYS_GPIO_PIN_PAGE GPIO_Pin_3 // PD.03
@@ -332,6 +351,11 @@
#define HARDWARE_SWITCH_A
#define SWITCHES_GPIO_REG_A GPIOC->IDR
#define SWITCHES_GPIO_PIN_A GPIO_Pin_13 // PC.13
+#elif defined(RADIO_T8)
+ #define STORAGE_SWITCH_A
+ #define HARDWARE_SWITCH_A
+ #define SWITCHES_GPIO_REG_A GPIOE->IDR
+ #define SWITCHES_GPIO_PIN_A GPIO_Pin_14 // PE.14
#elif defined(PCBX7)
#define STORAGE_SWITCH_A
#define HARDWARE_SWITCH_A
@@ -362,6 +386,13 @@
#define SWITCHES_GPIO_PIN_B_L GPIO_Pin_6 // PA.06
#define SWITCHES_GPIO_REG_B_H GPIOA->IDR
#define SWITCHES_GPIO_PIN_B_H GPIO_Pin_5 // PA.05
+#elif defined(RADIO_T8)
+ #define STORAGE_SWITCH_B
+ #define HARDWARE_SWITCH_B
+ #define SWITCHES_GPIO_REG_B_L GPIOE->IDR
+ #define SWITCHES_GPIO_PIN_B_L GPIO_Pin_7 // PE.07
+ #define SWITCHES_GPIO_REG_B_H GPIOE->IDR
+ #define SWITCHES_GPIO_PIN_B_H GPIO_Pin_13 // PE.13
#elif defined(PCBX7)
#define STORAGE_SWITCH_B
#define HARDWARE_SWITCH_B
@@ -406,6 +437,13 @@
#define SWITCHES_GPIO_PIN_C_L GPIO_Pin_11 // PD.11
#define SWITCHES_GPIO_REG_C_H GPIOE->IDR
#define SWITCHES_GPIO_PIN_C_H GPIO_Pin_0 // PE.00
+#elif defined(RADIO_T8)
+ #define STORAGE_SWITCH_C
+ #define HARDWARE_SWITCH_C
+ #define SWITCHES_GPIO_REG_C_L GPIOE->IDR
+ #define SWITCHES_GPIO_PIN_C_L GPIO_Pin_2 // PE.02
+ #define SWITCHES_GPIO_REG_C_H GPIOE->IDR
+ #define SWITCHES_GPIO_PIN_C_H GPIO_Pin_1 // PE.01
#elif defined(PCBX7)
#define STORAGE_SWITCH_C
#define HARDWARE_SWITCH_C
@@ -448,6 +486,11 @@
#define SWITCHES_GPIO_PIN_D_L GPIO_Pin_4 // PB.04
#define SWITCHES_GPIO_REG_D_H GPIOB->IDR
#define SWITCHES_GPIO_PIN_D_H GPIO_Pin_5 // PB.05
+#elif defined(RADIO_T8)
+ #define STORAGE_SWITCH_D
+ #define HARDWARE_SWITCH_D
+ #define SWITCHES_GPIO_REG_D GPIOD->IDR
+ #define SWITCHES_GPIO_PIN_D GPIO_Pin_14 // PD.14
#elif defined(RADIO_TX12)
#define STORAGE_SWITCH_D
#define HARDWARE_SWITCH_D
@@ -539,6 +582,9 @@
#define SWITCHES_GPIO_PIN_F_L GPIO_Pin_1 // PE.01
#define SWITCHES_GPIO_REG_F_H GPIOE->IDR
#define SWITCHES_GPIO_PIN_F_H GPIO_Pin_2 // PE.02
+#elif defined(RADIO_T8)
+ #define STORAGE_SWITCH_F
+ // no SWF
#elif defined(PCBX7)
#define STORAGE_SWITCH_F
#define HARDWARE_SWITCH_F
@@ -563,7 +609,7 @@
#define HARDWARE_SWITCH_G
#define SWITCHES_GPIO_REG_G GPIOC->IDR
#define SWITCHES_GPIO_PIN_G GPIO_Pin_2 // PC.02
-#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE)
+#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_T8)
// no SWG
#else
#define STORAGE_SWITCH_G
@@ -586,6 +632,9 @@
#define SWITCHES_GPIO_PIN_H GPIO_Pin_14 // PD.14
#elif defined(PCBXLITE) || defined(PCBX9LITE)
// no SWH
+#elif defined(RADIO_T8)
+ #define STORAGE_SWITCH_H
+ // no SWH
#elif defined(RADIO_TX12)
#elif defined(PCBX7)
#define STORAGE_SWITCH_H
@@ -615,6 +664,10 @@
#define SWITCHES_GPIO_REG_I GPIOC->IDR
#define SWITCHES_GPIO_PIN_I GPIO_Pin_13 // PC.13
#define STORAGE_SWITCH_J
+#elif defined(RADIO_T8)
+ #define STORAGE_SWITCH_I
+ #define STORAGE_SWITCH_J
+ // no SWI/J
#elif defined(RADIO_TX12)
#define STORAGE_SWITCH_I
#define HARDWARE_SWITCH_I
@@ -746,6 +799,13 @@
#define KEYS_GPIOC_PINS (GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3|GPIO_Pin_13)
#define KEYS_GPIOD_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15)
#define KEYS_GPIOE_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8| GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15)
+#elif defined(RADIO_T8)
+ #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE)
+ #define KEYS_GPIOA_PINS (KEYS_GPIO_PIN_ENTER | KEYS_GPIO_PIN_BIND)
+ #define KEYS_GPIOB_PINS (KEYS_GPIO_PIN_EXIT | KEYS_GPIO_PIN_SYS)
+ #define KEYS_GPIOC_PINS (TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_RVU | TRIMS_GPIO_PIN_RVD)
+ #define KEYS_GPIOD_PINS (KEYS_GPIO_PIN_PAGEUP | KEYS_GPIO_PIN_PAGEDN | SWITCHES_GPIO_PIN_D | TRIMS_GPIO_PIN_LHL)
+ #define KEYS_GPIOE_PINS (SWITCHES_GPIO_PIN_C_H | SWITCHES_GPIO_PIN_C_L | TRIMS_GPIO_PIN_RHL | TRIMS_GPIO_PIN_RHR | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_LVD | SWITCHES_GPIO_PIN_B_L | KEYS_GPIO_PIN_PLUS | KEYS_GPIO_PIN_MINUS | KEYS_GPIO_PIN_MDL | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_A)
#elif defined(RADIO_X7ACCESS)
#define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE)
#define KEYS_GPIOA_PINS GPIO_Pin_5
@@ -900,6 +960,25 @@
#define ADC_CHANNEL_POT2 ADC_Channel_12 // ADC1_IN12
#define ADC_CHANNEL_BATT ADC_Channel_10 // ADC1_IN10
#define ADC_VREF_PREC2 330
+#elif defined(RADIO_T8)
+ // No pots
+ #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2)
+ #define ADC_RCC_APB1Periph 0
+ #define ADC_RCC_APB2Periph RCC_APB2Periph_ADC1
+ #define ADC_GPIO_PIN_STICK_RV GPIO_Pin_0 // PA.00
+ #define ADC_GPIO_PIN_STICK_RH GPIO_Pin_1 // PA.01
+ #define ADC_GPIO_PIN_STICK_LV GPIO_Pin_2 // PA.02
+ #define ADC_GPIO_PIN_STICK_LH GPIO_Pin_3 // PA.03
+ #define ADC_CHANNEL_STICK_RV ADC_Channel_0 // ADC1_IN0
+ #define ADC_CHANNEL_STICK_RH ADC_Channel_1 // ADC1_IN1
+ #define ADC_CHANNEL_STICK_LV ADC_Channel_2 // ADC1_IN2
+ #define ADC_CHANNEL_STICK_LH ADC_Channel_3 // ADC1_IN3
+ #define ADC_GPIO_PIN_BATT GPIO_Pin_0 // PC.00
+ #define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV)
+ #define ADC_GPIOB_PINS 0
+ #define ADC_GPIOC_PINS ADC_GPIO_PIN_BATT
+ #define ADC_CHANNEL_BATT ADC_Channel_10
+ #define ADC_VREF_PREC2 300
#elif defined(PCBX7)
#define HARDWARE_POT1
#define HARDWARE_POT2
@@ -1027,6 +1106,16 @@
#define LED_BLUE_GPIO_PIN GPIO_Pin_1 // PB.01
#define LED_RED_GPIO GPIOC
#define LED_RED_GPIO_PIN GPIO_Pin_4 // PC.04
+#elif defined(RADIO_T8)
+ #define STATUS_LEDS
+ #define GPIO_LED_GPIO_ON GPIO_SetBits
+ #define GPIO_LED_GPIO_OFF GPIO_ResetBits
+ #define LED_RED_GPIO GPIOC
+ #define LED_RED_GPIO_PIN GPIO_Pin_4 // PC.04
+ #define LED_BLUE_GPIO GPIOC
+ #define LED_BLUE_GPIO_PIN GPIO_Pin_5 // PC.05
+ #define LED_GREEN_GPIO GPIOB
+ #define LED_GREEN_GPIO_PIN GPIO_Pin_1 // PB.01
#elif defined(PCBX7)
#define STATUS_LEDS
#define GPIO_LED_GPIO_ON GPIO_SetBits
@@ -1152,7 +1241,7 @@
#define INTMODULE_DMA_STREAM_IRQHandler DMA2_Stream5_IRQHandler
#define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF5
#define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
-#elif defined(RADIO_T12) || defined(RADIO_TX12)
+#elif (defined(RADIO_T12) && defined(HARDWARE_INTERNAL_MODULE))|| defined(RADIO_TX12) || defined(RADIO_T8)
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_USART3 | RCC_APB1Periph_TIM2)
#define INTMODULE_RCC_APB2Periph 0
@@ -1401,7 +1490,7 @@
#define TELEMETRY_EXTI_IRQn EXTI9_5_IRQn
#define TELEMETRY_EXTI_TRIGGER EXTI_Trigger_Rising
-#if defined(RADIO_X7) || defined(RADIO_X7ACCESS) || defined(RADIO_TX12)
+#if defined(RADIO_X7) || defined(RADIO_X7ACCESS) || defined(RADIO_TX12) || defined(RADIO_T8)
#define TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER
#elif defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_X9DP2019)
#define TELEMETRY_EXTI_IRQHandler EXTI9_5_IRQHandler
@@ -1477,7 +1566,9 @@
// Heartbeat for iXJT / ISRM synchro
#define INTMODULE_HEARTBEAT_TRIGGER EXTI_Trigger_Falling
-#if defined(PCBXLITE)
+#if !defined(HARDWARE_EXTERNAL_MODULE)
+ // No heartbeat
+#elif defined(PCBXLITE)
#define INTMODULE_HEARTBEAT
#define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define INTMODULE_HEARTBEAT_GPIO GPIOD
@@ -1507,7 +1598,7 @@
#define INTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource7
#define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line7
#define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI9_5_IRQn
-#elif defined(RADIO_X7) || defined(RADIO_TX12)
+#elif defined(RADIO_X7) || defined(RADIO_TX12)
#define INTMODULE_HEARTBEAT
#define INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER
#define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC
@@ -1577,15 +1668,17 @@
#define TRAINER_MODULE_SBUS_DMA_STREAM EXTMODULE_USART_RX_DMA_STREAM
#define TRAINER_MODULE_SBUS_DMA_CHANNEL EXTMODULE_USART_RX_DMA_CHANNEL
#else
+#if defined(HARDWARE_EXTERNAL_MODULE)
#define TRAINER_MODULE_CPPM
#define TRAINER_MODULE_SBUS
- #define TRAINER_MODULE_RCC_AHB1Periph RCC_AHB1Periph_GPIOC
- #define TRAINER_MODULE_RCC_APB2Periph RCC_APB2Periph_USART6
- #define TRAINER_MODULE_RCC_APB1Periph RCC_APB1Periph_TIM3
- #define TRAINER_MODULE_CPPM_TIMER TRAINER_TIMER
- #define TRAINER_MODULE_CPPM_GPIO INTMODULE_HEARTBEAT_GPIO
- #define TRAINER_MODULE_CPPM_GPIO_PIN INTMODULE_HEARTBEAT_GPIO_PIN
- #define TRAINER_MODULE_CPPM_GPIO_PinSource INTMODULE_HEARTBEAT_EXTI_PinSource
+#endif
+ #define TRAINER_MODULE_RCC_AHB1Periph RCC_AHB1Periph_GPIOC
+ #define TRAINER_MODULE_RCC_APB2Periph RCC_APB2Periph_USART6
+ #define TRAINER_MODULE_RCC_APB1Periph RCC_APB1Periph_TIM3
+ #define TRAINER_MODULE_CPPM_TIMER TRAINER_TIMER
+ #define TRAINER_MODULE_CPPM_GPIO INTMODULE_HEARTBEAT_GPIO
+ #define TRAINER_MODULE_CPPM_GPIO_PIN INTMODULE_HEARTBEAT_GPIO_PIN
+ #define TRAINER_MODULE_CPPM_GPIO_PinSource INTMODULE_HEARTBEAT_EXTI_PinSource
#define TRAINER_MODULE_CPPM_INTERRUPT_ENABLE TIM_DIER_CC2IE
#define TRAINER_MODULE_CPPM_INTERRUPT_FLAG TIM_SR_CC2IF
#define TRAINER_MODULE_CPPM_CCMR1 (TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0)
@@ -1665,6 +1758,10 @@
#define BACKLIGHT_CCMR1 TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 // Channel 1, PWM
#define BACKLIGHT_CCER TIM_CCER_CC1E
#define BACKLIGHT_COUNTER_REGISTER BACKLIGHT_TIMER->CCR1
+#elif defined(RADIO_T8)
+ #define BACKLIGHT_RCC_AHB1Periph 0
+ #define BACKLIGHT_RCC_APB1Periph 0
+ #define BACKLIGHT_RCC_APB2Periph 0
#elif defined(PCBX7)
#define BACKLIGHT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define BACKLIGHT_RCC_APB1Periph RCC_APB1Periph_TIM4
@@ -1692,7 +1789,7 @@
#define KEYS_BACKLIGHT_RCC_AHB1Periph 0
// LCD driver
-#if defined(RADIO_TX12) || defined(RADIO_T12)
+#if defined(RADIO_TX12) || defined(RADIO_T12) || defined(RADIO_T8)
#define LCD_VERTICAL_INVERT
#endif
#if defined(PCBX9E)
@@ -1887,7 +1984,7 @@
#define AUDIO_SPEAKER_ENABLE_GPIO_PIN GPIO_Pin_14 // PD.14
#define HEADPHONE_TRAINER_SWITCH_GPIO GPIOD
#define HEADPHONE_TRAINER_SWITCH_GPIO_PIN GPIO_Pin_9 // PD.09
-#elif defined(RADIO_TX12)
+#elif defined(RADIO_TX12) || defined(RADIO_T8)
#define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1)
#define AUDIO_MUTE_GPIO GPIOE
#define AUDIO_MUTE_GPIO_PIN GPIO_Pin_12 // PE.12
@@ -2013,7 +2110,7 @@
#define BT_USART_IRQn USART3_IRQn
// #define BT_DMA_Stream_RX DMA1_Stream1
// #define BT_DMA_Channel_RX DMA_Channel_4
-#elif defined(PCBX9D) || defined(PCBX9DP) || defined(RADIO_T12) || defined(RADIO_TX12)
+#elif defined(PCBX9D) || defined(PCBX9DP) || defined(RADIO_T12) || defined(RADIO_TX12) | defined(RADIO_T8)
#define STORAGE_BLUETOOTH
#define BT_RCC_AHB1Periph 0
#define BT_RCC_APB1Periph 0
diff --git a/radio/src/targets/taranis/keys_driver.cpp b/radio/src/targets/taranis/keys_driver.cpp
index 6883740c4..d99851441 100644
--- a/radio/src/targets/taranis/keys_driver.cpp
+++ b/radio/src/targets/taranis/keys_driver.cpp
@@ -88,6 +88,10 @@ uint32_t readKeys()
result |= 1 << KEY_SHIFT;
#endif
+#if defined(KEYS_GPIO_PIN_BIND)
+ if (~KEYS_GPIO_REG_BIND & KEYS_GPIO_PIN_BIND)
+ result |= 1 << KEY_BIND;
+#endif
// if (result != 0) TRACE("readKeys(): result=0x%02x", result);
return result;
@@ -200,7 +204,8 @@ uint32_t switchState(uint8_t index)
uint32_t xxx = 0;
switch (index) {
-#if defined(RADIO_TX12)
+
+#if defined(RADIO_TX12) || defined(RADIO_T8)
ADD_2POS_CASE(A);
ADD_3POS_CASE(B, 1);
ADD_3POS_CASE(C, 2);
@@ -235,6 +240,8 @@ uint32_t switchState(uint8_t index)
ADD_2POS_CASE(D);
ADD_3POS_CASE(E, 4);
ADD_3POS_CASE(F, 5);
+#elif defined(RADIO_T8)
+ ADD_2POS_CASE(D);
#elif defined(PCBX7)
ADD_3POS_CASE(D, 3);
ADD_2POS_CASE(F);
diff --git a/radio/src/targets/taranis/lcd_driver_spi.cpp b/radio/src/targets/taranis/lcd_driver_spi.cpp
index e1efa8e15..97f191c2b 100644
--- a/radio/src/targets/taranis/lcd_driver_spi.cpp
+++ b/radio/src/targets/taranis/lcd_driver_spi.cpp
@@ -20,7 +20,7 @@
#include "opentx.h"
-#if defined(RADIO_T12) || defined(RADIO_TX12)
+#if defined(RADIO_T12) || defined(RADIO_TX12) || defined(RADIO_T8)
#define LCD_CONTRAST_OFFSET -10
#else
#define LCD_CONTRAST_OFFSET 160
diff --git a/radio/src/targets/taranis/usb_charger_driver.cpp b/radio/src/targets/taranis/usb_charger_driver.cpp
index 7e92c6dbc..78cc3d6a6 100644
--- a/radio/src/targets/taranis/usb_charger_driver.cpp
+++ b/radio/src/targets/taranis/usb_charger_driver.cpp
@@ -33,5 +33,9 @@ void usbChargerInit()
bool usbChargerLed()
{
+#if defined(SIMU)
+ return true;
+#else
return (GPIO_ReadInputDataBit(USB_CHARGER_GPIO, USB_CHARGER_GPIO_PIN) == Bit_RESET && usbPlugged());
+#endif
}
diff --git a/radio/src/tests/switches.cpp b/radio/src/tests/switches.cpp
index 4eae3ba5c..504fae354 100644
--- a/radio/src/tests/switches.cpp
+++ b/radio/src/tests/switches.cpp
@@ -106,7 +106,7 @@ TEST(evalLogicalSwitches, playFile)
char filename[AUDIO_FILENAME_MAXLEN+1];
#if defined(EEPROM)
-#define MODELNAME "MODEL01"
+#define MODELNAME TR_MODEL "01"
#else
#define MODELNAME "Model00"
#endif
diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp
index 48d01b4bc..455d6490d 100644
--- a/radio/src/translations.cpp
+++ b/radio/src/translations.cpp
@@ -81,6 +81,7 @@ ISTR(POTTYPES);
ISTR(SLIDERTYPES);
ISTR(ANTENNA_MODES);
ISTR(SPORT_UPDATE_POWER_MODES);
+ISTR(SPORT_MODES);
#if defined(PCBSKY9X) && defined(REVX)
ISTR(VOUTPUT_TYPE);
@@ -829,3 +830,4 @@ const char STR_ABOUT_PARENTS_3[] = TR_ABOUT_PARENTS_3;
const char STR_ABOUT_PARENTS_4[] = TR_ABOUT_PARENTS_4;
const char STR_AUTH_FAILURE[] = TR_AUTH_FAILURE;
+const char STR_PROTOCOL[] = TR_PROTOCOL;
diff --git a/radio/src/translations.h b/radio/src/translations.h
index 73c843389..a9131d8a5 100644
--- a/radio/src/translations.h
+++ b/radio/src/translations.h
@@ -161,6 +161,7 @@ extern const char STR_R9M_PXX2_RF_PROTOCOLS[];
extern const char STR_DSM_PROTOCOLS[];
extern const char STR_MULTI_PROTOCOLS[];
extern const char STR_MULTI_POWER[];
+extern const char STR_SPORT_MODES[];
#if defined(AFHDS3)
extern const char STR_AFHDS3_ONE_TO_ONE_TELEMETRY[];
@@ -964,6 +965,7 @@ extern const char STR_ABOUT_PARENTS_3[];
extern const char STR_ABOUT_PARENTS_4[];
extern const char STR_AUTH_FAILURE[];
+extern const char STR_PROTOCOL[];
#define CHR_HOUR TR_CHR_HOUR
#define CHR_INPUT TR_CHR_INPUT
diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt
index 2f42f7edd..87f83a9e9 100644
--- a/radio/src/translations/cz.h.txt
+++ b/radio/src/translations/cz.h.txt
@@ -294,6 +294,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Mínus"
@@ -441,7 +444,7 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Výstup"
#endif
-#define TR_PROTO INDENT "Protokol"
+#define TR_PROTOCOL "Protokol"
#define TR_PPMFRAME INDENT "PPM modulace"
#define TR_REFRESHRATE TR(INDENT "Obnovit", INDENT "Obn. frekv.")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Výstup VBAT: ", INDENT "Varování: výstupní hodnota VBAT: ")
@@ -780,7 +783,7 @@
#define TR_NO_MODELS_ON_SD "žádný model" BREAKSPACE "na SD"
#define TR_NO_BITMAPS_ON_SD "žádné obrázky" BREAKSPACE "na SD"
#define TR_NO_SCRIPTS_ON_SD "žádný skript" BREAKSPACE "na SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Syntaktická chyba skriptu"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntaktická chyba", "Syntaktická chyba skriptu")
#define TR_SCRIPT_PANIC "Script zmaten"
#define TR_SCRIPT_KILLED "Script ukončen"
#define TR_SCRIPT_ERROR "Neznámá chyba"
diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt
index 1e85008b0..0d30316e3 100644
--- a/radio/src/translations/de.h.txt
+++ b/radio/src/translations/de.h.txt
@@ -300,6 +300,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -443,8 +446,8 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Output"
#endif
-#define TR_PROTO TR(INDENT "Protok.", INDENT "Protokoll")
- #define TR_PPMFRAME INDENT "PPM-Frame"
+#define TR_PROTOCOL TR("Protok.", "Protokoll")
+#define TR_PPMFRAME INDENT "PPM-Frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#define TR_WARN_5VOLTS "Warning: output level is 5 volts"
@@ -782,7 +785,7 @@
#define TR_NO_MODELS_ON_SD "Kein Modelle" BREAKSPACE "auf SD"
#define TR_NO_BITMAPS_ON_SD "Keine Bitmaps" BREAKSPACE "auf SD"
#define TR_NO_SCRIPTS_ON_SD "Keine Skripte" BREAKSPACE "auf SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Skript Syntaxfehler"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntaxfehler", "Skript Syntaxfehler")
#define TR_SCRIPT_PANIC "Skript Panik"
#define TR_SCRIPT_KILLED "Skript beendet"
#define TR_SCRIPT_ERROR "Unbekannter Fehler"
diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt
index ad49d6997..d0dd3e25c 100644
--- a/radio/src/translations/en.h.txt
+++ b/radio/src/translations/en.h.txt
@@ -300,6 +300,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -442,7 +445,7 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Output"
#endif
-#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
+#define TR_PROTOCOL TR("Proto", "Protocol")
#define TR_PPMFRAME INDENT "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
@@ -786,7 +789,7 @@
#define TR_NO_MODELS_ON_SD "No models" BREAKSPACE "on SD"
#define TR_NO_BITMAPS_ON_SD "No bitmaps" BREAKSPACE "on SD"
#define TR_NO_SCRIPTS_ON_SD "No scripts" BREAKSPACE "on SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Script syntax error"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntax error", "Script syntax error")
#define TR_SCRIPT_PANIC "Script panic"
#define TR_SCRIPT_KILLED "Script killed"
#define TR_SCRIPT_ERROR "Unknown error"
diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt
index e89998d7f..cbbe3b591 100644
--- a/radio/src/translations/es.h.txt
+++ b/radio/src/translations/es.h.txt
@@ -297,6 +297,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -441,7 +444,7 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Output"
#endif
-#define TR_PROTO TR(INDENT"Proto",INDENT"Protocolo")
+#define TR_PROTOCOL TR("Proto", "Protocolo")
#define TR_PPMFRAME INDENT "Trama PPM"
#define TR_REFRESHRATE TR(INDENT "Refresco", INDENT "Velocidad refresco")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Salida es VBAT: ", INDENT "Aviso: señal salida es VBAT: ")
@@ -783,7 +786,7 @@
#define TR_NO_MODELS_ON_SD "Sin modelos en SD"
#define TR_NO_BITMAPS_ON_SD "Sin imágenes en SD"
#define TR_NO_SCRIPTS_ON_SD "No scripts en SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Script syntax error"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntax error", "Script syntax error")
#define TR_SCRIPT_PANIC "Script panic"
#define TR_SCRIPT_KILLED "Script killed"
#define TR_SCRIPT_ERROR "Error desconocido"
diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt
index e18b51102..03c1ecf25 100644
--- a/radio/src/translations/fi.h.txt
+++ b/radio/src/translations/fi.h.txt
@@ -318,6 +318,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -455,7 +458,7 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Output"
#endif
-#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
+#define TR_PROTOCOL TR("Proto", "Protocol")
#define TR_PPMFRAME TR("PPM frame", INDENT "PPM frame")
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
@@ -799,7 +802,7 @@
#define TR_NO_MODELS_ON_SD "No Models on SD"
#define TR_NO_BITMAPS_ON_SD "No Bitmaps on SD"
#define TR_NO_SCRIPTS_ON_SD "No Scripts on SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Script syntax error"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntax error", "Script syntax error")
#define TR_SCRIPT_PANIC "Script panic"
#define TR_SCRIPT_KILLED "Script killed"
#define TR_SCRIPT_ERROR "Unknown error"
diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt
index ffaeb38c6..ce6624b67 100644
--- a/radio/src/translations/fr.h.txt
+++ b/radio/src/translations/fr.h.txt
@@ -320,6 +320,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Moins"
@@ -461,8 +464,8 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Sortie"
#endif
-#define TR_PROTO TR(INDENT "Proto.", INDENT "Protocole")
- #define TR_PPMFRAME INDENT "Trame PPM"
+#define TR_PROTOCOL TR("Proto.", "Protocole")
+#define TR_PPMFRAME INDENT "Trame PPM"
#define TR_REFRESHRATE INDENT "Période"
#define STR_WARN_BATTVOLTAGE TR(INDENT "Signal est VBAT: ", INDENT "ATTENTION: signal est à VBAT: ")
#define TR_WARN_5VOLTS "Warning: output level is 5 volts"
@@ -802,7 +805,7 @@
#define TR_NO_MODELS_ON_SD "Aucun modèle SD"
#define TR_NO_BITMAPS_ON_SD "Aucun Bitmap SD"
#define TR_NO_SCRIPTS_ON_SD "Aucun Script SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Erreur syntaxe script"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Erreur syntaxe", "Erreur syntaxe script")
#define TR_SCRIPT_PANIC "Script bloqué"
#define TR_SCRIPT_KILLED "Script interrompu"
#define TR_SCRIPT_ERROR "Erreur inconnue"
diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt
index c1e8c0be0..eeecb347a 100644
--- a/radio/src/translations/it.h.txt
+++ b/radio/src/translations/it.h.txt
@@ -321,6 +321,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -463,8 +466,8 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Uscita"
#endif
-#define TR_PROTO TR(INDENT "Protoc.", INDENT "Protocollo")
- #define TR_PPMFRAME INDENT "Frame PPM"
+#define TR_PROTOCOL TR("Protoc.", "Protocollo")
+#define TR_PPMFRAME INDENT "Frame PPM"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Uscita VBAT: ", INDENT "Att.: livel. uscita VBAT: ")
#define TR_WARN_5VOLTS "Attenzione: il livello d'uscita è 5 Volts"
@@ -801,7 +804,7 @@
#define TR_NO_MODELS_ON_SD "No Model." BREAKSPACE "su SD"
#define TR_NO_BITMAPS_ON_SD "No Immag." BREAKSPACE "su SD"
#define TR_NO_SCRIPTS_ON_SD "No Scripts" BREAKSPACE "su SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Script errore sintassi"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Errore sintassi", "Script errore sintassi")
#define TR_SCRIPT_PANIC "Script panic"
#define TR_SCRIPT_KILLED "Script fermato"
#define TR_SCRIPT_ERROR "Errore sconosciuto"
diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt
index fe5abbfe3..087305944 100644
--- a/radio/src/translations/nl.h.txt
+++ b/radio/src/translations/nl.h.txt
@@ -298,6 +298,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -442,8 +445,8 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Output"
#endif
-#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
- #define TR_PPMFRAME INDENT "PPM frame"
+#define TR_PROTOCOL TR("Proto", "Protocol")
+#define TR_PPMFRAME INDENT "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#define TR_WARN_5VOLTS "Warning: output level is 5 volts"
@@ -787,7 +790,7 @@
#define TR_NO_MODELS_ON_SD "Geen Modellen" BREAKSPACE "op SD"
#define TR_NO_BITMAPS_ON_SD "Geen Bitmaps" BREAKSPACE "op SD"
#define TR_NO_SCRIPTS_ON_SD "Geen Scripts" BREAKSPACE "op SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Script syntax error"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntax error", "Script syntax error")
#define TR_SCRIPT_PANIC "Script panic"
#define TR_SCRIPT_KILLED "Script killed"
#define TR_SCRIPT_ERROR "Unknown error"
diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt
index edfcee741..367694cde 100644
--- a/radio/src/translations/pl.h.txt
+++ b/radio/src/translations/pl.h.txt
@@ -318,6 +318,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -462,8 +465,8 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Wyjście"
#endif
-#define TR_PROTO TR(INDENT "Proto", INDENT "Protokół")
- #define TR_PPMFRAME INDENT "Ramka PPM"
+#define TR_PROTOCOL TR("Proto", "Protokół")
+#define TR_PPMFRAME INDENT "Ramka PPM"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#define TR_WARN_5VOLTS "Warning: output level is 5 volts"
@@ -800,7 +803,7 @@
#define TR_NO_MODELS_ON_SD "Brak modelu na SD"
#define TR_NO_BITMAPS_ON_SD "Brak obrazków na SD"
#define TR_NO_SCRIPTS_ON_SD "Brak skryptów na SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Skrypt:syntax error"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntax error", "Skrypt:syntax error")
#define TR_SCRIPT_PANIC "Skrypt:panic"
#define TR_SCRIPT_KILLED "Skrypt:killed"
#define TR_SCRIPT_ERROR "Nieznany błąd"
@@ -1130,21 +1133,21 @@
#define TR_ABOUT_MARTIN_2 "Projekty graficzne"
#if defined(MANUFACTURER_FRSKY)
- #define TR_ABOUT_HARDWARE_1 "FrSky"
- #define TR_ABOUT_HARDWARE_2 "Proucent/projektant Hardware"
- #define TR_ABOUT_HARDWARE_3 "Współautor firmware"
+ #define TR_ABOUT_HARDWARE_1 "FrSky"
+ #define TR_ABOUT_HARDWARE_2 "Proucent/projektant Hardware"
+ #define TR_ABOUT_HARDWARE_3 "Współautor firmware"
#elif defined(MANUFACTURER_RADIOMASTER)
- #define TR_ABOUT_HARDWARE_1 "Radiomaster"
- #define TR_ABOUT_HARDWARE_2 "Proucent/projektant Hardware"
- #define TR_ABOUT_HARDWARE_3 "Współautor firmware"
+ #define TR_ABOUT_HARDWARE_1 "Radiomaster"
+ #define TR_ABOUT_HARDWARE_2 "Proucent/projektant Hardware"
+ #define TR_ABOUT_HARDWARE_3 "Współautor firmware"
#elif defined(MANUFACTURER_JUMPER)
- #define TR_ABOUT_HARDWARE_1 "JumperRC"
- #define TR_ABOUT_HARDWARE_2 "Proucent/projektant Hardware"
- #define TR_ABOUT_HARDWARE_3 "Współautor firmware"
+ #define TR_ABOUT_HARDWARE_1 "JumperRC"
+ #define TR_ABOUT_HARDWARE_2 "Proucent/projektant Hardware"
+ #define TR_ABOUT_HARDWARE_3 "Współautor firmware"
#else
- #define TR_ABOUT_HARDWARE_1 "Brent Nelson"
- #define TR_ABOUT_HARDWARE_2 "Sky9x designer/výrobce"
- #define TR_ABOUT_HARDWARE_3 ""
+ #define TR_ABOUT_HARDWARE_1 "Brent Nelson"
+ #define TR_ABOUT_HARDWARE_2 "Sky9x designer/výrobce"
+ #define TR_ABOUT_HARDWARE_3 ""
#endif
#define TR_ABOUT_PARENTS_1 "Projekty macierzyste"
diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt
index 412e3698a..7ef85235b 100644
--- a/radio/src/translations/pt.h.txt
+++ b/radio/src/translations/pt.h.txt
@@ -311,6 +311,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -459,7 +462,7 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Output"
#endif
-#define TR_PROTO INDENT"Proto"
+#define TR_PROTOCOL "Proto"
#define TR_PPMFRAME "PPM frame"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
@@ -801,7 +804,7 @@
#define TR_NO_MODELS_ON_SD "Sem Modelo no SD"
#define TR_NO_BITMAPS_ON_SD "No Bitmaps on SD"
#define TR_NO_SCRIPTS_ON_SD "No Scripts on SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Script syntax error"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntax error", "Script syntax error")
#define TR_SCRIPT_PANIC "Script panic"
#define TR_SCRIPT_KILLED "Script killed"
#define TR_SCRIPT_ERROR "Unknown error"
@@ -1240,7 +1243,7 @@
#define TR_MENU_INVERT "Invert"
#define TR_JITTER_FILTER "ADC Filter"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage")
-#define TR_AUTH_FAILURE "Auth-failure"
+#define TR_AUTH_FAILURE "Auth-failure"
#define ZSTR_VFR "VFR"
#define ZSTR_RSSI "RSSI"
diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt
index 57cf99ba6..499fcb41d 100644
--- a/radio/src/translations/se.h.txt
+++ b/radio/src/translations/se.h.txt
@@ -312,6 +312,9 @@
#elif defined(RADIO_TX12)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Exit\0""Enter""Up\0 ""Down\0""SYS\0 ""MDL\0 ""TELE\0"
+#elif defined(RADIO_T8)
+ #define LEN_VKEYS "\005"
+ #define TR_VKEYS "RTN\0 ""ENTER""PGUP\0""PGDN\0""SYS\0 ""MDL\0 ""UP\0 ""DOWN\0"
#elif defined(PCBTARANIS)
#define LEN_VKEYS "\005"
#define TR_VKEYS "Menu\0""Exit\0""Enter""Page\0""Plus\0""Minus"
@@ -461,8 +464,8 @@
#if defined(PCBSKY9X) && defined(REVX)
#define TR_OUTPUT_TYPE INDENT "Output"
#endif
-#define TR_PROTO TR(INDENT "Proto", INDENT "Protokoll")
- #define TR_PPMFRAME INDENT "PPM-paket"
+#define TR_PROTOCOL TR("Proto", "Protokoll")
+#define TR_PPMFRAME INDENT "PPM-paket"
#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate")
#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ")
#define TR_WARN_5VOLTS "Warning: output level is 5 volts"
@@ -800,7 +803,7 @@
#define TR_NO_MODELS_ON_SD "Ingen modell i SD"
#define TR_NO_BITMAPS_ON_SD "Ikoner saknas på SD"
#define TR_NO_SCRIPTS_ON_SD "Programkod saknas på SD"
-#define TR_SCRIPT_SYNTAX_ERROR "Script syntax error"
+#define TR_SCRIPT_SYNTAX_ERROR TR("Syntax error", "Script syntax error")
#define TR_SCRIPT_PANIC "Script panic"
#define TR_SCRIPT_KILLED "Script killed"
#define TR_SCRIPT_ERROR "Unknown error"
diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h
index e0e6f4bef..268eb2606 100644
--- a/radio/src/translations/untranslated.h
+++ b/radio/src/translations/untranslated.h
@@ -109,6 +109,9 @@
#define LEN_R9M_PXX2_RF_PROTOCOLS "\006"
#define TR_R9M_PXX2_RF_PROTOCOLS "ACCESS""FCC\0 ""EU\0 ""Flex"
+#define LEN_SPORT_MODES "\014"
+#define TR_SPORT_MODES "S.PORT\0 ""F.PORT\0 ""FBUS(FPORT2)"
+
#define LEN_R9M_REGION "\006"
#define TR_R9M_REGION "FCC\0 ""EU\0 ""868MHz""915MHz"
diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py
index 66d9f053d..b7132d510 100755
--- a/radio/util/build-firmware.py
+++ b/radio/util/build-firmware.py
@@ -148,6 +148,11 @@ def main():
cmake_options["PCBREV"] = "TX12"
firmware_options = options_radiomaster_tx12
maxsize = 65536 * 8
+ elif board_name == "t8":
+ cmake_options["PCB"] = "X7"
+ cmake_options["PCBREV"] = "T8"
+ firmware_options = options_radiomaster_t8
+ maxsize = 65536 * 8
elif board_name == "t16":
cmake_options["PCB"] = "X10"
cmake_options["PCBREV"] = "T16"
diff --git a/radio/util/fwoptions.py b/radio/util/fwoptions.py
index f4438db44..7b2a01edd 100755
--- a/radio/util/fwoptions.py
+++ b/radio/util/fwoptions.py
@@ -258,6 +258,17 @@ options_radiomaster_tx12 = {
"afhds3": ("AFHDS3", "YES", "NO")
}
+options_radiomaster_t8 = {
+ "noheli": ("HELI", "NO", "YES"),
+ "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"),
+ "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"),
+ "nogvars": ("GVARS", "NO", "YES"),
+ "faimode": ("FAI", "YES", None),
+ "faichoice": ("FAI", "CHOICE", None),
+ "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"),
+ "bindkey": ("BIND_KEY", "NO", "YES"),
+}
+
options_radiomaster_tx16s = {
"noheli": ("HELI", "NO", "YES"),
"ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"),
diff --git a/tools/build-radiomaster.py b/tools/build-radiomaster.py
index 985bc705a..564463537 100755
--- a/tools/build-radiomaster.py
+++ b/tools/build-radiomaster.py
@@ -28,6 +28,18 @@ boards = {
"PCB": "X7",
"PCBREV": "TX12",
"DEFAULT_MODE": "2",
+ },
+ "T8_1": {
+ "PCB": "X7",
+ "PCBREV": "T8",
+ "DEFAULT_MODE": "1",
+ "RADIOMASTER_RTF_RELEASE": "YES",
+ },
+ "T8_2": {
+ "PCB": "X7",
+ "PCBREV": "T8",
+ "DEFAULT_MODE": "2",
+ "RADIOMASTER_RTF_RELEASE": "YES",
}
}
diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh
index 6c5642ccd..ca25ac809 100755
--- a/tools/commit-tests.sh
+++ b/tools/commit-tests.sh
@@ -88,7 +88,7 @@ fi
if [[ " X9LITE ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X9LITE
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X9LITE -DHELI=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X9LITE -DHELI=YES -DGVARS=YES -DTRANSLATIONS=CZ "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -97,7 +97,7 @@ fi
if [[ " X9LITES X9LITE ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X9LITES
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X9LITES -DHELI=YES -DGVARS=YES -DMULTIMODULE=NO "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X9LITES -DHELI=YES -DGVARS=YES -DMULTIMODULE=NO -DTRANSLATIONS=DE "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -106,7 +106,7 @@ fi
if [[ " X7 ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X7
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X7 -DHELI=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X7 -DHELI=YES -DGVARS=YES -DTRANSLATIONS=ES "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -115,7 +115,7 @@ fi
if [[ " X7ACCESS X7 ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X7 ACCESS
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=ACCESS -DHELI=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=ACCESS -DHELI=YES -DGVARS=YES -DTRANSLATIONS=FR "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -124,7 +124,7 @@ fi
if [[ " T12 X7 ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on T12
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES -DTRANSLATIONS=IT "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -133,6 +133,15 @@ fi
if [[ " TX12 X7 ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on TX12
rm -rf ./*
+ cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=TX12 -DHELI=YES -DGVARS=YES -DTRANSLATIONS=PT "${SRCDIR}"
+ make -j"${CORES}" ${FIRMARE_TARGET}
+ make -j"${CORES}" libsimulator
+ make -j"${CORES}" tests-radio
+fi
+
+if [[ " T8 X7 ALL " =~ \ ${FLAVOR}\ ]] ; then
+ # OpenTX on T8
+ rm -rf ./*
cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=TX12 -DHELI=YES -DGVARS=YES "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
@@ -142,7 +151,7 @@ fi
if [[ " XLITE ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X-Lite
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=XLITE -DHELI=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=XLITE -DHELI=YES -DGVARS=YES -DTRANSLATIONS=SK "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -151,7 +160,7 @@ fi
if [[ " XLITES XLITE ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X-Lites
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=XLITES -DHELI=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=XLITES -DHELI=YES -DGVARS=YES -DTRANSLATIONS=SE "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -160,7 +169,7 @@ fi
if [[ " X9D X9 ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X9D
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES -DTRANSLATIONS=PL "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -169,7 +178,7 @@ fi
if [[ " X9D+ X9 ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X9D+
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES -DTRANSLATIONS=HU "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio
@@ -178,7 +187,7 @@ fi
if [[ " X9D+2019 X9 ALL " =~ \ ${FLAVOR}\ ]] ; then
# OpenTX on X9D+ 2019
rm -rf ./*
- cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}"
+ cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES -DTRANSLATIONS=NL "${SRCDIR}"
make -j"${CORES}" ${FIRMARE_TARGET}
make -j"${CORES}" libsimulator
make -j"${CORES}" tests-radio