Fix MPM Protocol Sorting (#580)

* Fixed Protocol Sorting in model_setup.cpp

* update submodule for libopenui

* Fix potential compilation issue

* Fixed Protocol Sorting in model_setup.cpp

* fix merge issue

* Submodule libopenui back to edgetx master branch

* Reset to libopenui 5c70891
As this was the submodule at the time this branch was started.
This should remove it as a change in the PR.

* fixed an off by one error in the initialization of the sorted list.  When you selected the last protocol in the list it crashed.

* Reset to libopenui 5c70891
As this was the submodule at the time this branch was started.

Co-authored-by: kkoenig1@optonline.com <kkoenig1@optonline.com>
Co-authored-by: Peter Feerick <peter.feerick@gmail.com>
This commit is contained in:
Kevin Koenig
2021-09-01 09:47:32 +10:00
committed by GitHub
co-authored by kkoenig1@optonline.com <kkoenig1@optonline.com> Peter Feerick
parent 71764fec1d
commit 32da77ce02
+96 -2
View File
@@ -22,9 +22,91 @@
#include "opentx.h"
#include "libopenui.h"
#include "storage/modelslist.h"
#include "algorithm"
#define SET_DIRTY() storageDirty(EE_MODEL)
class RFProtocols
{
private:
const char * protocols;
int maxProtocols;
std::vector<std::string> labels;
uint8_t getProtoStringLength();
public:
RFProtocols(const char * rfProtocols, int max);
int findProtocolIndex(int rfProtcolIndex);
int lookupProtocolIndex(int selectedIndex);
std::vector<std::string> &getLabels();
};
uint8_t RFProtocols::getProtoStringLength()
{
return protocols[0];
}
RFProtocols::RFProtocols(const char *protocols, int max)
{
this->protocols = protocols;
maxProtocols = max;
uint8_t len = protocols[0];
const char * value = &protocols[1];
for (int i = 0; i <= max; i++)
{
std::string label = std::string(value, min<uint8_t>(len, strlen(value)));
labels.emplace_back(label);
value += len;
}
std::sort(labels.begin(), labels.end());
}
std::vector<std::string> &RFProtocols::getLabels()
{
return labels;
}
int RFProtocols::lookupProtocolIndex(int selectedIndex)
{
uint8_t len = getProtoStringLength();
const char *p = &protocols[1];
const char *protocolLabel = labels.at(selectedIndex).c_str();
int protocolIndex = 0;
for (; protocolIndex < maxProtocols; protocolIndex++)
{
if (strncmp(p, protocolLabel, min((int)strlen(protocolLabel), (int)len)) == 0)
break;
p += len;
}
assert(protocolIndex < maxProtocols);
return protocolIndex;
}
int RFProtocols::findProtocolIndex(int rfProtocolIndex)
{
uint8_t len = getProtoStringLength();
const char *protocolLabel = &protocols[1] + len * rfProtocolIndex;
auto result = std::find_if(labels.begin(), labels.end(), [protocolLabel, len](std::string &a) {
auto theSame = strncmp(a.c_str(), protocolLabel, max((int)a.length(), (int)len)) == 0;
return theSame;
});
assert(result != labels.end());
return result - labels.begin();
}
// global pointer intialized once on the first call to update()
RFProtocols *rfProtocols = nullptr;
std::string switchWarninglabel(swsrc_t index)
{
static const char switchPositions[] = {
@@ -641,15 +723,27 @@ class ModuleWindow : public FormGroup {
// Multi type (CUSTOM, brand A, brand B,...)
int multiRfProto = g_model.moduleData[moduleIdx].getMultiProtocol();
// initialize rfProtocols if it is not initialized already. This is a hack
// because i dont know how to construct it at the exact right time after the module
// is loaded
if (rfProtocols == nullptr)
rfProtocols = new RFProtocols(STR_MULTI_PROTOCOLS, MODULE_SUBTYPE_MULTI_LAST);
multiRfProto = rfProtocols->findProtocolIndex(multiRfProto);
// Grid count for narrow/wide screen
int count = LCD_W < LCD_H ? 1 : (g_model.moduleData[moduleIdx].multi.customProto ? 3 : 2);
rfChoice = new Choice(
this,
grid.getFieldSlot(count, 0),
STR_MULTI_PROTOCOLS, MODULE_SUBTYPE_MULTI_FIRST,
rfProtocols->getLabels(), MODULE_SUBTYPE_MULTI_FIRST,
MODULE_SUBTYPE_MULTI_LAST, GET_DEFAULT(multiRfProto),
[=](int32_t newValue) {
newValue = rfProtocols->lookupProtocolIndex(newValue);
g_model.moduleData[moduleIdx].setMultiProtocol(newValue);
g_model.moduleData[moduleIdx].subType = 0;
if (mmSubProtocol != nullptr) mmSubProtocol->invalidate(); // always null ???