Merge branch 'EdgeTX:2.4' into 2.4
This commit is contained in:
@@ -317,19 +317,23 @@ coord_t drawGPSCoord(BitmapBuffer * dc, coord_t x, coord_t y, int32_t value, con
|
||||
}
|
||||
*tmp++ = direction[value>=0 ? 0 : 1];
|
||||
*tmp = '\0';
|
||||
dc->drawText(x, y, s, flags);
|
||||
x = dc->drawText(x, y, s, flags);
|
||||
return x;
|
||||
}
|
||||
|
||||
void drawGPSPosition(BitmapBuffer * dc, coord_t x, coord_t y, int32_t longitude, int32_t latitude, LcdFlags flags)
|
||||
{
|
||||
if (flags & EXPANDED) {
|
||||
drawGPSCoord(dc, x, y, latitude, "NS", flags, true);
|
||||
drawGPSCoord(dc, x, y + FH, longitude, "EW", flags, true);
|
||||
}
|
||||
else {
|
||||
x = drawGPSCoord(dc, x, y, latitude, "NS", flags, false);
|
||||
drawGPSCoord(dc, x + 5, y, longitude, "EW", flags, false);
|
||||
if (flags & PREC1) {
|
||||
drawGPSCoord(dc, x, y, latitude, "NS", flags, false);
|
||||
drawGPSCoord(dc, x, y + FH, longitude, "EW", flags, false);
|
||||
} else {
|
||||
if (flags & RIGHT) {
|
||||
x = drawGPSCoord(dc, x, y, longitude, "EW", flags, false);
|
||||
drawGPSCoord(dc, x - 5, y, latitude, "NS", flags, false);
|
||||
} else {
|
||||
x = drawGPSCoord(dc, x, y, latitude, "NS", flags, false);
|
||||
drawGPSCoord(dc, x + 5, y, longitude, "EW", flags, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,8 +123,6 @@ void loadCustomScreens()
|
||||
}
|
||||
|
||||
auto topbar = viewMain->getTopbar();
|
||||
|
||||
// TODO: how to reload this guy?
|
||||
topbar->load();
|
||||
|
||||
viewMain->setCurrentMainView(0);
|
||||
|
||||
@@ -108,15 +108,30 @@ class ModelButton : public Button
|
||||
if (strncmp(modelCell->modelFilename, g_eeGeneral.currModelFilename,
|
||||
LEN_MODEL_FILENAME) == 0) {
|
||||
memcpy(&partialModel.header, &g_model.header, sizeof(partialModel));
|
||||
version = EEPROM_VER;
|
||||
} else {
|
||||
error =
|
||||
readModel(modelCell->modelFilename, (uint8_t *)&partialModel.header,
|
||||
sizeof(partialModel), &version);
|
||||
if (!error) {
|
||||
if (modelCell->modelName[0] == '\0' &&
|
||||
partialModel.header.name[0] != '\0') {
|
||||
modelCell->setModelName(partialModel.header.name);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
if (modelCell->modelName[0] == '\0' &&
|
||||
partialModel.header.name[0] != '\0') {
|
||||
|
||||
if (version == 219) {
|
||||
size_t len = sizeof(partialModel.header.name);
|
||||
char* str = partialModel.header.name;
|
||||
for (int i=0; i < len; i++) {
|
||||
str[i] = zchar2char(str[i]);
|
||||
}
|
||||
// Trim string
|
||||
while(len > 0 && str[len-1]) {
|
||||
if (str[len - 1] != ' ' && str[len - 1] != '\0') break;
|
||||
str[--len] = '\0';
|
||||
}
|
||||
}
|
||||
modelCell->setModelName(partialModel.header.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -250,6 +250,92 @@ class SpecialFunctionEditPage : public Page
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case FUNC_ADJUST_GVAR: {
|
||||
|
||||
new StaticText(specialFunctionOneWindow, grid.getLabelSlot(),
|
||||
STR_GLOBALVAR);
|
||||
auto gvarchoice =
|
||||
new Choice(specialFunctionOneWindow, grid.getFieldSlot(), 0,
|
||||
MAX_GVARS - 1, GET_SET_DEFAULT(CFN_GVAR_INDEX(cfn)));
|
||||
gvarchoice->setTextHandler([](int32_t value) {
|
||||
return std::string(STR_GV) + std::to_string(value + 1);
|
||||
});
|
||||
grid.nextLine();
|
||||
|
||||
new StaticText(specialFunctionOneWindow, grid.getLabelSlot(),
|
||||
STR_MODE);
|
||||
auto modechoice =
|
||||
new Choice(specialFunctionOneWindow, grid.getFieldSlot(),
|
||||
FUNC_ADJUST_GVAR_CONSTANT, FUNC_ADJUST_GVAR_INCDEC,
|
||||
GET_DEFAULT(CFN_GVAR_MODE(cfn)), nullptr);
|
||||
grid.nextLine();
|
||||
|
||||
modechoice->setTextHandler([](int32_t value) {
|
||||
switch (value) {
|
||||
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||
return std::string(STR_CONSTANT);
|
||||
case FUNC_ADJUST_GVAR_SOURCE:
|
||||
return std::string(STR_MIXSOURCE);
|
||||
case FUNC_ADJUST_GVAR_GVAR:
|
||||
return std::string(STR_GLOBALVAR);
|
||||
case FUNC_ADJUST_GVAR_INCDEC:
|
||||
return std::string(STR_INCDEC);
|
||||
}
|
||||
return std::string("---");
|
||||
});
|
||||
|
||||
modechoice->setSetValueHandler([=](int32_t newValue) {
|
||||
CFN_GVAR_MODE(cfn) = newValue;
|
||||
CFN_PARAM(cfn) = 0;
|
||||
SET_DIRTY();
|
||||
updateSpecialFunctionOneWindow();
|
||||
});
|
||||
|
||||
switch (CFN_GVAR_MODE(cfn)) {
|
||||
case FUNC_ADJUST_GVAR_CONSTANT: {
|
||||
//TODO: label
|
||||
int16_t val_min, val_max;
|
||||
getMixSrcRange(CFN_GVAR_INDEX(cfn) + MIXSRC_FIRST_GVAR, val_min,
|
||||
val_max);
|
||||
new NumberEdit(specialFunctionOneWindow, grid.getFieldSlot(),
|
||||
val_min, val_max, GET_SET_DEFAULT(CFN_PARAM(cfn)));
|
||||
break;
|
||||
}
|
||||
case FUNC_ADJUST_GVAR_SOURCE:
|
||||
//TODO: label
|
||||
new SourceChoice(specialFunctionOneWindow, grid.getFieldSlot(),
|
||||
0, MIXSRC_LAST_CH, GET_SET_DEFAULT(CFN_PARAM(cfn)));
|
||||
break;
|
||||
case FUNC_ADJUST_GVAR_GVAR: {
|
||||
auto gvarchoice =
|
||||
new Choice(specialFunctionOneWindow, grid.getFieldSlot(), 0,
|
||||
MAX_GVARS - 1, GET_SET_DEFAULT(CFN_PARAM(cfn)));
|
||||
gvarchoice->setTextHandler([](int32_t value) {
|
||||
return std::string(STR_GV) + std::to_string(value + 1);
|
||||
});
|
||||
gvarchoice->setAvailableHandler([=](int value) {
|
||||
return CFN_GVAR_INDEX(cfn) != value;
|
||||
});
|
||||
break;
|
||||
}
|
||||
case FUNC_ADJUST_GVAR_INCDEC: {
|
||||
int16_t val_min, val_max;
|
||||
getMixSrcRange(CFN_GVAR_INDEX(cfn) + MIXSRC_FIRST_GVAR, val_min, val_max);
|
||||
getGVarIncDecRange(val_min, val_max);
|
||||
auto numedit = new NumberEdit(specialFunctionOneWindow,
|
||||
grid.getFieldSlot(), val_min, val_max,
|
||||
GET_SET_DEFAULT(CFN_PARAM(cfn)));
|
||||
numedit->setDisplayHandler(
|
||||
[](BitmapBuffer *dc, LcdFlags flags, int value) {
|
||||
dc->drawNumber(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, abs(value),
|
||||
flags, 0, value >= 0 ? "+= " : "-= ", nullptr);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
grid.nextLine();
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_ENABLE_PARAM(func)) {
|
||||
@@ -390,12 +476,18 @@ class SpecialFunctionButton : public Button
|
||||
dc->drawNumber(col2, line2, CFN_PARAM(cfn));
|
||||
break;
|
||||
|
||||
case FUNC_TRAINER:
|
||||
drawSource(
|
||||
dc, col1, line2,
|
||||
CFN_CH_INDEX(cfn) == 0 ? 0 : MIXSRC_Rud + CFN_CH_INDEX(cfn) - 1);
|
||||
case FUNC_TRAINER: {
|
||||
std::string text;
|
||||
int16_t value = CFN_CH_INDEX(cfn);
|
||||
if (value == 0)
|
||||
text = std::string(STR_STICKS);
|
||||
else if (value == NUM_STICKS + 1)
|
||||
text = std::string(STR_CHANS);
|
||||
else
|
||||
text = TEXT_AT_INDEX(STR_VSRCRAW, value);
|
||||
dc->drawText(col1, line2, text.c_str(), 0);
|
||||
break;
|
||||
|
||||
}
|
||||
case FUNC_RESET:
|
||||
if (CFN_PARAM(cfn) < FUNC_RESET_PARAM_FIRST_TELEM) {
|
||||
dc->drawTextAtIndex(col1, line2, STR_VFSWRESET, CFN_PARAM(cfn));
|
||||
@@ -450,6 +542,26 @@ class SpecialFunctionButton : public Button
|
||||
dc->drawNumber(col3, line1, CFN_PARAM(cfn), PREC1,
|
||||
sizeof(CFN_PARAM(cfn)), nullptr, "s");
|
||||
break;
|
||||
|
||||
case FUNC_ADJUST_GVAR:
|
||||
switch(CFN_GVAR_MODE(cfn)) {
|
||||
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||
dc->drawNumber(col1, line2, CFN_PARAM(cfn), 0);
|
||||
break;
|
||||
case FUNC_ADJUST_GVAR_SOURCE:
|
||||
drawSource(dc, col1, line2, CFN_PARAM(cfn), 0);
|
||||
break;
|
||||
case FUNC_ADJUST_GVAR_GVAR:
|
||||
drawSource(dc, col1, line2, CFN_PARAM(cfn) + MIXSRC_FIRST_GVAR, 0);
|
||||
break;
|
||||
case FUNC_ADJUST_GVAR_INCDEC: {
|
||||
int16_t value = CFN_PARAM(cfn);
|
||||
std::string text(value >= 0 ? "+= " : "-= ");
|
||||
text += std::to_string(abs(value));
|
||||
dc->drawText(col1, line2, text.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (HAS_ENABLE_PARAM(func)) {
|
||||
theme->drawCheckBox(dc, CFN_ACTIVE(cfn), col3, line2);
|
||||
|
||||
@@ -97,7 +97,12 @@ class ModelBitmapWidget: public Widget
|
||||
TRACE("could not load bitmap '%s'", filename.c_str());
|
||||
return;
|
||||
}
|
||||
buffer->drawScaledBitmap(bitmap.get(), 0, 38, width(), height() - 38);
|
||||
|
||||
if (rect.h >= 96 && rect.w >= 120) {
|
||||
buffer->drawScaledBitmap(bitmap.get(), 0, 38, width(), height() - 38);
|
||||
} else {
|
||||
buffer->drawScaledBitmap(bitmap.get(), 0, 0, width(), height());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,10 +26,11 @@ const coord_t NUMBERS_PADDING = 4;
|
||||
class ValueWidget: public Widget
|
||||
{
|
||||
public:
|
||||
ValueWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData):
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
{
|
||||
}
|
||||
ValueWidget(const WidgetFactory* factory, FormGroup* parent,
|
||||
const rect_t& rect, Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
void refresh(BitmapBuffer * dc) override
|
||||
{
|
||||
@@ -37,7 +38,7 @@ class ValueWidget: public Widget
|
||||
mixsrc_t field = persistentData->options[0].value.unsignedValue;
|
||||
|
||||
// get color from options[1]
|
||||
lcdSetColor(persistentData->options[1].value.unsignedValue);
|
||||
LcdFlags color = COLOR2FLAGS(persistentData->options[1].value.unsignedValue);
|
||||
|
||||
coord_t xValue, yValue, xLabel, yLabel;
|
||||
LcdFlags attrValue, attrLabel = 0;
|
||||
@@ -55,7 +56,7 @@ class ValueWidget: public Widget
|
||||
yValue = -2;
|
||||
xLabel = NUMBERS_PADDING;
|
||||
yLabel = +2;
|
||||
attrValue = RIGHT | NO_UNIT | FONT(XL);
|
||||
attrValue = RIGHT | NO_UNIT | FONT(L);
|
||||
}
|
||||
else {
|
||||
xValue = NUMBERS_PADDING;
|
||||
@@ -64,7 +65,7 @@ class ValueWidget: public Widget
|
||||
yLabel = 2;
|
||||
if (field >= MIXSRC_FIRST_TELEM) {
|
||||
if (isGPSSensor(1 + (field - MIXSRC_FIRST_TELEM) / 3)) {
|
||||
attrValue = LEFT | FONT(L) | EXPANDED;
|
||||
attrValue = LEFT | FONT(L) | PREC1;
|
||||
}
|
||||
else {
|
||||
attrValue = LEFT | FONT(XL);
|
||||
@@ -72,7 +73,7 @@ class ValueWidget: public Widget
|
||||
}
|
||||
#if defined(INTERNAL_GPS)
|
||||
else if (field == MIXSRC_TX_GPS) {
|
||||
attrValue = LEFT | FONT(L) | EXPANDED;
|
||||
attrValue = LEFT | FONT(L) | PREC1;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
@@ -83,27 +84,32 @@ class ValueWidget: public Widget
|
||||
if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) {
|
||||
TimerState & timerState = timersStates[field - MIXSRC_FIRST_TIMER];
|
||||
if (timerState.val < 0) {
|
||||
lcdSetColor(lcdColorTable[ALARM_COLOR_INDEX]);
|
||||
color = ALARM_COLOR;
|
||||
}
|
||||
drawSource(dc, NUMBERS_PADDING, 2, field, CUSTOM_COLOR);
|
||||
drawSource(dc, NUMBERS_PADDING + 1, 3, field, BLACK);
|
||||
drawTimer(dc, xValue, yValue, abs(timerState.val), attrValue | FONT(XL) | CUSTOM_COLOR);
|
||||
drawSource(dc, NUMBERS_PADDING, 2, field, color);
|
||||
drawSource(dc, NUMBERS_PADDING + 1, 3, field, COLOR2FLAGS(BLACK));
|
||||
drawTimer(dc, xValue, yValue, abs(timerState.val), attrValue | FONT(XL) | color);
|
||||
}
|
||||
|
||||
if (field == MIXSRC_TX_TIME) {
|
||||
drawTimer(dc, xValue, yValue, getValue(MIXSRC_TX_TIME),
|
||||
attrValue | FONT(XL) | color);
|
||||
}
|
||||
|
||||
if (field >= MIXSRC_FIRST_TELEM) {
|
||||
TelemetryItem & telemetryItem = telemetryItems[(field - MIXSRC_FIRST_TELEM) / 3]; // TODO macro to convert a source to a telemetry index
|
||||
TelemetryItem & telemetryItem = telemetryItems[(field - MIXSRC_FIRST_TELEM) / 3];
|
||||
if (!telemetryItem.isAvailable() || telemetryItem.isOld()) {
|
||||
lcdSetColor(lcdColorTable[TEXT_DISABLE_COLOR_INDEX]);
|
||||
color = TEXT_DISABLE_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
if (persistentData->options[2].value.boolValue) {
|
||||
drawSource(dc,xLabel + 1, yLabel + 1, field, attrLabel | BLACK);
|
||||
drawSourceValue(dc, xValue + 1, yValue + 1, field, attrValue | BLACK);
|
||||
drawSource(dc,xLabel + 1, yLabel + 1, field, attrLabel | COLOR2FLAGS(BLACK));
|
||||
drawSourceValue(dc, xValue + 1, yValue + 1, field, attrValue | COLOR2FLAGS(BLACK));
|
||||
}
|
||||
|
||||
drawSource(dc, xLabel, yLabel, field, attrLabel | CUSTOM_COLOR);
|
||||
drawSourceValue(dc, xValue, yValue, field, attrValue | CUSTOM_COLOR);
|
||||
drawSource(dc, xLabel, yLabel, field, attrLabel | color);
|
||||
drawSourceValue(dc, xValue, yValue, field, attrValue | color);
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
|
||||
@@ -43,10 +43,12 @@ class WidgetsContainerImpl: public WidgetsContainer
|
||||
// remove old one if existing
|
||||
removeWidget(index);
|
||||
|
||||
Widget * widget = nullptr;
|
||||
Widget* widget = nullptr;
|
||||
if (factory) {
|
||||
strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(ZonePersistentData::widgetName));
|
||||
widget = factory->create(this, getZone(index), &persistentData->zones[index].widgetData);
|
||||
strncpy(persistentData->zones[index].widgetName, factory->getName(),
|
||||
sizeof(ZonePersistentData::widgetName));
|
||||
widget = factory->create(this, getZone(index),
|
||||
&persistentData->zones[index].widgetData);
|
||||
}
|
||||
widgets[index] = widget;
|
||||
|
||||
@@ -61,12 +63,16 @@ class WidgetsContainerImpl: public WidgetsContainer
|
||||
if (index >= N)
|
||||
return;
|
||||
|
||||
if (widgets[index])
|
||||
if (widgets[index]) {
|
||||
removeField(widgets[index]);
|
||||
widgets[index]->deleteLater();
|
||||
}
|
||||
|
||||
widgets[index] = nullptr;
|
||||
memset(persistentData->zones[index].widgetName, 0, sizeof(ZonePersistentData::widgetName));
|
||||
memset(&persistentData->zones[index].widgetData, 0, sizeof(Widget::PersistentData));
|
||||
memset(persistentData->zones[index].widgetName, 0,
|
||||
sizeof(ZonePersistentData::widgetName));
|
||||
memset(&persistentData->zones[index].widgetData, 0,
|
||||
sizeof(Widget::PersistentData));
|
||||
}
|
||||
|
||||
Widget * getWidget(unsigned int index) override
|
||||
@@ -89,6 +95,7 @@ class WidgetsContainerImpl: public WidgetsContainer
|
||||
|
||||
// remove old widget
|
||||
if (widgets[i]) {
|
||||
removeField(widgets[i]);
|
||||
widgets[i]->deleteLater();
|
||||
widgets[i] = nullptr;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ void convertRadioData(int version)
|
||||
RAISE_ALERT(STR_STORAGE_WARNING, STR_SDCARD_CONVERSION_REQUIRE, NULL,
|
||||
AU_NONE);
|
||||
|
||||
// Load models list before converting
|
||||
modelslist.load();
|
||||
|
||||
unsigned converted = 0;
|
||||
auto to_convert = modelslist.getModelsCount() + 1;
|
||||
|
||||
@@ -68,6 +71,8 @@ void convertRadioData(int version)
|
||||
#if STORAGE_CONVERSIONS < 220
|
||||
if (version == 219) {
|
||||
convertRadioData_219_to_220(g_eeGeneral);
|
||||
storageDirty(EE_GENERAL);
|
||||
storageCheck(true);
|
||||
}
|
||||
#endif
|
||||
converted++;
|
||||
@@ -76,9 +81,6 @@ void convertRadioData(int version)
|
||||
RTOS_WAIT_MS(200);
|
||||
#endif
|
||||
|
||||
// Load models list before converting
|
||||
modelslist.load();
|
||||
|
||||
const char* error = nullptr;
|
||||
for (auto category_ptr : modelslist.getCategories()) {
|
||||
for (auto model_ptr : *category_ptr) {
|
||||
|
||||
@@ -109,7 +109,7 @@ void convertModelData_219_to_220(ModelData &model)
|
||||
convertToStr(model.header.name, LEN_MODEL_NAME_219);
|
||||
|
||||
for (uint8_t i=0; i<MAX_TIMERS_219; i++) {
|
||||
//TODO: convert to new timers v220
|
||||
// convert to new timers v220
|
||||
TimerData& timer = newModel.timers[i];
|
||||
convertToStr(timer.name, LEN_TIMER_NAME_219);
|
||||
|
||||
@@ -153,7 +153,7 @@ void convertModelData_219_to_220(ModelData &model)
|
||||
|
||||
// CurveHeader.name
|
||||
for (uint8_t i=0; i<MAX_CURVES_219; ++i) {
|
||||
convertToStr(model.expoData[i].name, LEN_CURVE_NAME_219);
|
||||
convertToStr(model.curves[i].name, LEN_CURVE_NAME_219);
|
||||
}
|
||||
|
||||
// CustomFunctionData::play.name
|
||||
|
||||
@@ -48,7 +48,9 @@ ModelCell::~ModelCell()
|
||||
void ModelCell::setModelName(char * name)
|
||||
{
|
||||
strncpy(modelName, name, LEN_MODEL_NAME);
|
||||
if (modelName[0] == 0) {
|
||||
modelName[LEN_MODEL_NAME] = '\0';
|
||||
|
||||
if (modelName[0] == '\0') {
|
||||
char * tmp;
|
||||
strncpy(modelName, modelFilename, LEN_MODEL_NAME);
|
||||
tmp = (char *) memchr(modelName, '.', LEN_MODEL_NAME);
|
||||
|
||||
Vendored
+1
-1
Submodule radio/src/thirdparty/libopenui updated: 6b661c4907...bca0e093b0
Reference in New Issue
Block a user