feat(color,cpn): Updates to the model telemetry page, sensor ID consistency (#3401)

* Add 'Show Instance ID' button to telemetry page to show/hide sensor instance number (default is hidden).
Fix issues with page refresh when all sensors deleted.
Select closest sensor when a single sensor is deleted.
On change, only refresh the sensor list instead of the whole page.
The 'showInstanceIds' property is saved to the model file.
Update Companion to save/load 'showInstanceIds' in model YAML file. Add checkbox to telemetry edit page.

* Update all radio specific files.

* Keep focus on 'Discover/Stop' button when searching for new sensors.
Start sensor ID index at 1 to match B&W radios.
Keep focus on changed parameter when editing sensor, don't rebuild entire parameter list on change.

* Display actual 'instance' ID instead of 'instance' + 1.

* Fix incorrect ID when reloading simulator data.

* Fix incorrect ID when reloading simulator data on B&W radios.
This commit is contained in:
philmoz
2023-04-17 18:44:44 +10:00
committed by GitHub
parent 7bf6dbba0f
commit 6985d3f24b
49 changed files with 559 additions and 345 deletions
@@ -108,7 +108,7 @@ void menuModelSensor(event_t event)
if (sensor->type == TELEM_TYPE_CUSTOM) {
lcdDrawTextAlignedLeft(y, STR_ID);
lcdDrawHexNumber(SENSOR_2ND_COLUMN, y, sensor->id, LEFT|(menuHorizontalPosition==0 ? attr : 0));
lcdDrawNumber(SENSOR_3RD_COLUMN, y, (sensor->instance & 0x1F) + 1, LEFT|(menuHorizontalPosition==1 ? attr : 0));
lcdDrawNumber(SENSOR_3RD_COLUMN, y, sensor->instance & 0x1F, LEFT|(menuHorizontalPosition==1 ? attr : 0));
if (attr && s_editMode > 0) {
switch (menuHorizontalPosition) {
case 0:
@@ -118,7 +118,7 @@ void menuModelSensor(event_t event)
if (sensor->type == TELEM_TYPE_CUSTOM) {
lcdDrawTextAlignedLeft(y, STR_ID);
lcdDrawHexNumber(SENSOR_2ND_COLUMN, y, sensor->id, LEFT|(menuHorizontalPosition==0 ? attr : 0));
lcdDrawNumber(SENSOR_3RD_COLUMN, y, (sensor->instance & 0x1F) + 1, LEFT|(menuHorizontalPosition==1 ? attr : 0));
lcdDrawNumber(SENSOR_3RD_COLUMN, y, sensor->instance & 0x1F, LEFT|(menuHorizontalPosition==1 ? attr : 0));
if (attr) {
switch (menuHorizontalPosition) {
case 0:
+452 -279
View File
@@ -39,15 +39,6 @@ std::string getSensorCustomValue(uint8_t sensor, int32_t value, LcdFlags flags);
// Overview grid variants
static const lv_coord_t col_dsc[] = {LV_GRID_FR(14), LV_GRID_FR(6),
LV_GRID_TEMPLATE_LAST};
#if LCD_W > LCD_H
static const lv_coord_t col_dsc2[] = {LV_GRID_FR(3), LV_GRID_FR(3), 8, LV_GRID_FR(8), LV_GRID_FR(2),
LV_GRID_TEMPLATE_LAST};
#else
static const lv_coord_t col_dsc2[] = {28, 56, 8, LV_GRID_FR(1), 32,
LV_GRID_TEMPLATE_LAST};
#endif
static const lv_coord_t col_dsc3[] = {LCD_W - 12,
LV_GRID_TEMPLATE_LAST};
#if TWOCOLBUTTONS
static const lv_coord_t col_dsc4[] = {LV_GRID_FR(1), LV_GRID_FR(1),
LV_GRID_TEMPLATE_LAST};
@@ -67,59 +58,117 @@ static const lv_coord_t e_col_dsc2[] = {LV_GRID_FR(4), LV_GRID_FR(3), LV_GRID_FR
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT,
LV_GRID_TEMPLATE_LAST};
// Sensor value label that updates current value display
class SensorValueLabel : public StaticText {
#define BTN_H 32
#define NUM_W 36
#define NAME_W 56
class TSStyle
{
public:
SensorValueLabel(Window * parent, const rect_t &rect, uint8_t index) :
StaticText(parent, rect, ""),
index(index)
TSStyle() {}
void init()
{
padLeft(10);
}
if (!styleInitDone)
{
styleInitDone = true;
void checkEvents() override
{
uint32_t now = RTOS_GET_MS();
TelemetryItem & telemetryItem = telemetryItems[index];
lv_style_init(&tsContStyle);
lv_style_set_pad_all(&tsContStyle, 0);
lv_style_set_width(&tsContStyle, NUM_W);
lv_style_set_height(&tsContStyle, BTN_H-4);
if ((now - lastRefresh >= 200) || telemetryItem.isFresh()) {
// update at least every 200ms
lastRefresh = now;
lv_style_init(&tsNumStyle);
lv_style_set_text_font(&tsNumStyle, getFont(FONT(STD)));
lv_style_set_text_color(&tsNumStyle, makeLvColor(COLOR_THEME_SECONDARY1));
lv_style_set_text_align(&tsNumStyle, LV_TEXT_ALIGN_CENTER);
lv_style_set_width(&tsNumStyle, NUM_W);
std::string s;
LcdFlags color = COLOR_THEME_SECONDARY1;
lv_style_init(&tsNameStyle);
lv_style_set_text_font(&tsNameStyle, getFont(FONT(STD)));
lv_style_set_text_color(&tsNameStyle, makeLvColor(COLOR_THEME_SECONDARY1));
lv_style_set_text_align(&tsNameStyle, LV_TEXT_ALIGN_LEFT);
lv_style_set_width(&tsNameStyle, NAME_W);
if (telemetryItem.isAvailable()) {
color = telemetryItem.isOld() ? COLOR_THEME_WARNING : color;
s = getSensorCustomValue(index, getValue(MIXSRC_FIRST_TELEM + 3 * index), LEFT);
} else {
s = "---";
}
lv_style_init(&tsFreshStyle);
lv_style_set_text_color(&tsFreshStyle, makeLvColor(COLOR_THEME_SECONDARY1));
lv_style_set_width(&tsFreshStyle, 8);
lv_style_set_height(&tsFreshStyle, 8);
lv_style_set_img_recolor(&tsFreshStyle, makeLvColor(COLOR_THEME_SECONDARY1));
lv_style_set_img_recolor_opa(&tsFreshStyle, LV_OPA_COVER);
#if LCD_H > LCD_W
if (s.size() >= 20) {
setFont(FONT(XS));
} else {
setFont(FONT(STD));
}
#endif
lv_obj_set_style_text_color(lvobj, makeLvColor(color), 0);
setText(s);
lv_style_init(&tsValueStyle);
lv_style_set_text_font(&tsValueStyle, getFont(FONT(STD)));
lv_style_set_text_color(&tsValueStyle, makeLvColor(COLOR_THEME_SECONDARY1));
lv_style_set_text_align(&tsValueStyle, LV_TEXT_ALIGN_LEFT);
lv_style_set_width(&tsValueStyle, LV_SIZE_CONTENT);
lv_style_init(&tsIdStyle);
lv_style_set_text_font(&tsIdStyle, getFont(FONT(XXS)));
lv_style_set_text_color(&tsIdStyle, makeLvColor(COLOR_THEME_SECONDARY1));
lv_style_set_text_align(&tsIdStyle, LV_TEXT_ALIGN_CENTER);
lv_style_set_width(&tsIdStyle, NUM_W);
lv_style_set_height(&tsIdStyle, 11);
}
}
void paint(BitmapBuffer * dc) override
void setContStyle(lv_obj_t* obj)
{
TelemetryItem &telemetryItem = telemetryItems[index];
// Draw a 'fresh' marker
if (telemetryItem.isFresh())
dc->drawFilledCircle(5, 10, 4, COLOR_THEME_SECONDARY1);
init();
lv_obj_add_style(obj, &tsContStyle, LV_PART_MAIN);
}
protected:
uint8_t index;
uint32_t lastRefresh = 0;
void setNumStyle(lv_obj_t* obj)
{
init();
lv_obj_add_style(obj, &tsNumStyle, LV_PART_MAIN);
}
void setNameStyle(lv_obj_t* obj)
{
init();
lv_obj_add_style(obj, &tsNameStyle, LV_PART_MAIN);
}
void setValueStyle(lv_obj_t* obj)
{
init();
lv_obj_add_style(obj, &tsValueStyle, LV_PART_MAIN);
}
void setFreshStyle(lv_obj_t* obj)
{
init();
lv_obj_add_style(obj, &tsFreshStyle, LV_PART_MAIN);
}
void setIdStyle(lv_obj_t* obj)
{
init();
lv_obj_add_style(obj, &tsIdStyle, LV_PART_MAIN);
}
private:
lv_style_t tsContStyle;
lv_style_t tsNumStyle;
lv_style_t tsNameStyle;
lv_style_t tsValueStyle;
lv_style_t tsIdStyle;
lv_style_t tsFreshStyle;
bool styleInitDone;
};
static TSStyle tsStyle;
static uint8_t freshBitmap[] = {
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
};
class SensorButton : public Button {
@@ -128,27 +177,29 @@ class SensorButton : public Button {
Button(parent, rect, nullptr, 0, 0, input_mix_line_create),
index(index)
{
padAll(0);
lv_obj_set_layout(lvobj, LV_LAYOUT_GRID);
lv_obj_set_grid_dsc_array(lvobj, col_dsc2, row_dsc);
lv_obj_set_style_pad_row(lvobj, 0, 0);
lv_obj_set_style_pad_column(lvobj, 4, 0);
padTop(0);
padBottom(0);
padLeft(3);
padRight(3);
setHeight(BTN_H);
lv_obj_set_flex_flow(lvobj, LV_FLEX_FLOW_ROW);
lv_obj_set_style_pad_all(lvobj, 0, 0);
lv_obj_set_flex_align(lvobj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_AROUND);
check(isActive());
lv_obj_update_layout(parent->getLvObj());
if(lv_obj_is_visible(lvobj)) delayed_init(nullptr);
lv_obj_add_event_cb(lvobj, SensorButton::on_draw, LV_EVENT_DRAW_MAIN_BEGIN, nullptr);
}
protected:
bool init = false;
bool hideId = false;
bool showId = false;
lv_obj_t* numLabel = nullptr;
lv_obj_t* idLabel = nullptr;
uint8_t index;
lv_obj_t* valLabel = nullptr;
lv_obj_t* fresh = nullptr;
uint32_t lastRefresh = 0;
uint8_t index;
static void on_draw(lv_event_t * e)
{
@@ -164,61 +215,74 @@ class SensorButton : public Button {
bool isActive() const
{
TelemetryItem & telemetryItem = telemetryItems[index];
return telemetryItem.isAvailable();
return telemetryItems[index].isAvailable();
}
void setNumIdState()
{
showId = g_model.showInstanceIds;
if (showId) {
lv_obj_clear_flag(idLabel, LV_OBJ_FLAG_HIDDEN);
lv_obj_set_style_text_font(numLabel, getFont(FONT(XS)), 0);
lv_obj_set_height(numLabel, 14);
} else {
lv_obj_add_flag(idLabel, LV_OBJ_FLAG_HIDDEN);
lv_obj_set_style_text_font(numLabel, getFont(FONT(STD)), 0);
lv_obj_set_height(numLabel, 22);
}
}
void checkEvents() override
{
Button::checkEvents();
check(isActive());
if (hideId != g_model.ignoreSensorIds) {
hideId = g_model.ignoreSensorIds;
if (hideId)
lv_obj_add_flag(idLabel, LV_OBJ_FLAG_HIDDEN);
else
lv_obj_clear_flag(idLabel, LV_OBJ_FLAG_HIDDEN);
}
refresh();
}
void delayed_init(lv_event_t* e)
{
char s[20];
auto lbl = lv_label_create(lvobj);
lv_obj_set_style_text_align(lbl, LV_TEXT_ALIGN_CENTER, 0);
lv_obj_set_grid_cell(lbl, LV_GRID_ALIGN_CENTER, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1);
auto box = lv_obj_create(lvobj);
tsStyle.setContStyle(box);
lv_obj_set_flex_flow(box, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(box, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_AROUND);
lv_label_set_text(lbl, std::to_string(index).c_str());
numLabel = lv_label_create(box);
tsStyle.setNumStyle(numLabel);
lbl = lv_label_create(lvobj);
lv_obj_set_style_text_align(lbl, LV_TEXT_ALIGN_LEFT, 0);
lv_obj_set_grid_cell(lbl, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);
lv_label_set_text(numLabel, std::to_string(index+1).c_str());
strAppend(s, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN);
lv_label_set_text(lbl, s);
auto v = new SensorValueLabel(this, rect_t{}, index);
lv_obj_set_grid_cell(v->getLvObj(), LV_GRID_ALIGN_STRETCH, 2, 2, LV_GRID_ALIGN_CENTER, 0, 1);
idLabel = lv_label_create(box);
tsStyle.setIdStyle(idLabel);
TelemetrySensor * sensor = & g_model.telemetrySensors[index];
if (sensor->type == TELEM_TYPE_CUSTOM) {
sprintf(s, "%d", sensor->instance);
sprintf(s, "ID: %d", sensor->instance);
} else {
s[0] = 0;
}
hideId = g_model.ignoreSensorIds;
idLabel = lv_label_create(lvobj);
lv_obj_set_style_text_align(idLabel, LV_TEXT_ALIGN_LEFT, 0);
lv_obj_set_grid_cell(idLabel, LV_GRID_ALIGN_START, 4, 1, LV_GRID_ALIGN_CENTER, 0, 1);
lv_label_set_text(idLabel, s);
setNumIdState();
if (hideId)
lv_obj_add_flag(idLabel, LV_OBJ_FLAG_HIDDEN);
auto lbl = lv_label_create(lvobj);
tsStyle.setNameStyle(lbl);
strAppend(s, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN);
lv_label_set_text(lbl, s);
box = lv_obj_create(lvobj);
tsStyle.setFreshStyle(box);
fresh = lv_canvas_create(box);
tsStyle.setFreshStyle(fresh);
lv_canvas_set_buffer(fresh, freshBitmap, 8, 8, LV_IMG_CF_ALPHA_8BIT);
lv_obj_add_flag(fresh, LV_OBJ_FLAG_HIDDEN);
valLabel = lv_label_create(lvobj);
tsStyle.setValueStyle(valLabel);
lv_label_set_text(valLabel, "");
init = true;
refresh();
@@ -232,6 +296,38 @@ class SensorButton : public Button {
void refresh()
{
if (!init) return;
if (showId != g_model.showInstanceIds)
setNumIdState();
// Draw a 'fresh' marker
if (telemetryItems[index].isFresh())
lv_obj_clear_flag(fresh, LV_OBJ_FLAG_HIDDEN);
else
lv_obj_add_flag(fresh, LV_OBJ_FLAG_HIDDEN);
uint32_t now = RTOS_GET_MS();
TelemetryItem & telemetryItem = telemetryItems[index];
// Update value
if ((now - lastRefresh >= 200) || telemetryItem.isFresh()) {
// update at least every 200ms
lastRefresh = now;
std::string s;
LcdFlags color = COLOR_THEME_SECONDARY1;
if (telemetryItem.isAvailable()) {
color = telemetryItem.isOld() ? COLOR_THEME_WARNING : color;
s = getSensorCustomValue(index, getValue(MIXSRC_FIRST_TELEM + 3 * index), LEFT);
} else {
s = "---";
}
lv_obj_set_style_text_color(valLabel, makeLvColor(color), 0);
lv_label_set_text(valLabel, s.c_str());
}
}
};
@@ -271,9 +367,36 @@ class SensorEditWindow : public Page {
protected:
uint8_t index;
uint32_t lastRefresh = 0;
FormWindow * sensorParametersWindow = nullptr;
StaticText * headerValue = nullptr;
enum ParamTypes {
P_FORMULA = 0,
P_ID,
P_UNIT,
P_PREC,
P_CELLSENSOR,
P_GPSSENSOR,
P_CURRENTSENSOR,
P_CONSUMPTIONSOURCE,
P_CALC0,
P_BLADES,
P_RATIO,
P_CELLINDEX,
P_ALTSENSOR,
P_CALC1,
P_MULT,
P_OFFSET,
P_CALC2,
P_CALC3,
P_AUTOOFFSET,
P_ONLYPOS,
P_FILTER,
P_PERSISTENT,
P_COUNT,
};
FormWindow::Line* paramLines[P_COUNT] = {};
void buildHeader(Window * window)
{
std::string title2 = STR_SENSOR + std::to_string(index + 1) + " = " + STR_NA;
@@ -310,197 +433,102 @@ class SensorEditWindow : public Page {
}
}
void updateSensorParametersWindow()
void updateSensorParameters()
{
// Sensor variable part
sensorParametersWindow->clear();
sensorParametersWindow->setFlexLayout();
FlexGridLayout grid(e_col_dsc, row_dsc, 2);
FlexGridLayout grid2(e_col_dsc2, row_dsc, 2);
TelemetrySensor * sensor = &g_model.telemetrySensors[index];
FormWindow::Line* line;
for (int i = P_FORMULA; i < P_COUNT; i += 1) {
lv_obj_add_flag(paramLines[i]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
if (sensor->type == TELEM_TYPE_CALCULATED) {
// Formula
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_FORMULA, 0, COLOR_THEME_PRIMARY1);
new Choice(line, rect_t{}, STR_VFORMULAS, 0, TELEM_FORMULA_LAST, GET_DEFAULT(sensor->formula),
[=](uint8_t newValue) {
sensor->formula = newValue;
sensor->param = 0;
if (sensor->formula == TELEM_FORMULA_CELL) {
sensor->unit = UNIT_VOLTS;
sensor->prec = 2;
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
sensor->unit = UNIT_DIST;
sensor->prec = 0;
}
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
sensor->unit = UNIT_MAH;
sensor->prec = 0;
}
SET_DIRTY();
telemetryItems[index].clear();
updateSensorParametersWindow();
});
lv_obj_clear_flag(paramLines[P_FORMULA]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else {
line = sensorParametersWindow->newLine(&grid2);
new StaticText(line, rect_t{}, STR_ID, 0, COLOR_THEME_PRIMARY1);
auto hex = new NumberEdit(line, rect_t{}, 0, 0xFFFF, GET_SET_DEFAULT(sensor->id));
hex->setDisplayHandler([](int32_t value) {
std::stringstream stream;
stream << std::hex << value;
return stream.str();
});
new NumberEdit(line, rect_t{}, 0, 0xff, GET_SET_DEFAULT(sensor->instance));
lv_obj_clear_flag(paramLines[P_ID]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
// Unit
if ((sensor->type == TELEM_TYPE_CALCULATED && (sensor->formula == TELEM_FORMULA_DIST)) || sensor->isConfigurable()) {
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_UNIT, 0, COLOR_THEME_PRIMARY1);
new Choice(line, rect_t{}, STR_VTELEMUNIT, 0, UNIT_MAX, GET_DEFAULT(sensor->unit),
[=](uint8_t newValue) {
sensor->unit = newValue;
if (sensor->unit == UNIT_FAHRENHEIT) {
sensor->prec = 0;
}
SET_DIRTY();
telemetryItems[index].clear();
updateSensorParametersWindow();
});
lv_obj_clear_flag(paramLines[P_UNIT]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
// Precision
if (sensor->isPrecConfigurable() && sensor->unit != UNIT_FAHRENHEIT) {
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_PRECISION, 0, COLOR_THEME_PRIMARY1);
new Choice(line, rect_t{}, STR_VPREC, 0, 2, GET_DEFAULT(sensor->prec),
[=](uint8_t newValue) {
sensor->prec = newValue;
SET_DIRTY();
telemetryItems[index].clear();
updateSensorParametersWindow();
});
lv_obj_clear_flag(paramLines[P_PREC]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
// Params
if (sensor->unit < UNIT_FIRST_VIRTUAL) {
line = sensorParametersWindow->newLine(&grid);
if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) {
new StaticText(line, rect_t{}, STR_CELLSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, &sensor->cell.source, isCellsSensor);
lv_obj_clear_flag(paramLines[P_CELLSENSOR]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
new StaticText(line, rect_t{}, STR_GPSSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, &sensor->dist.gps, isGPSSensor);
lv_obj_clear_flag(paramLines[P_GPSSENSOR]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
new StaticText(line, rect_t{}, STR_CURRENTSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, &sensor->consumption.source, isSensorAvailable);
lv_obj_clear_flag(paramLines[P_CURRENTSENSOR]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else if (sensor->formula == TELEM_FORMULA_TOTALIZE) {
new StaticText(line, rect_t{}, STR_SOURCE, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, &sensor->consumption.source, isSensorAvailable);
lv_obj_clear_flag(paramLines[P_CONSUMPTIONSOURCE]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else {
new StaticText(line, rect_t{}, STR_SOURCE + std::to_string(1), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, (uint8_t *) &sensor->calc.sources[0], isSensorAvailable);
lv_obj_clear_flag(paramLines[P_CALC0]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
}
else {
if (sensor->unit == UNIT_RPMS) {
new StaticText(line, rect_t{}, STR_BLADES, 0, COLOR_THEME_PRIMARY1);
new NumberEdit(line, rect_t{}, 1, 30000, GET_SET_DEFAULT(sensor->custom.ratio));
lv_obj_clear_flag(paramLines[P_BLADES]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else {
new StaticText(line, rect_t{}, STR_RATIO, 0, COLOR_THEME_PRIMARY1);
auto edit = new NumberEdit(line, rect_t{}, 0, 30000, GET_SET_DEFAULT(sensor->custom.ratio));
edit->setZeroText("-");
lv_obj_clear_flag(paramLines[P_RATIO]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
}
}
if (!(sensor->unit == UNIT_GPS || sensor->unit == UNIT_DATETIME || sensor->unit == UNIT_CELLS ||
(sensor->type == TELEM_TYPE_CALCULATED && (sensor->formula == TELEM_FORMULA_CONSUMPTION || sensor->formula == TELEM_FORMULA_TOTALIZE)))) {
line = sensorParametersWindow->newLine(&grid);
if (sensor->type == TELEM_TYPE_CALCULATED) {
if (sensor->formula == TELEM_FORMULA_CELL) {
new StaticText(line, rect_t{}, STR_CELLINDEX, 0, COLOR_THEME_PRIMARY1);
new Choice(line, rect_t{}, STR_VCELLINDEX, TELEM_CELL_INDEX_LOWEST, TELEM_CELL_INDEX_LAST, GET_SET_DEFAULT(sensor->cell.index));
lv_obj_clear_flag(paramLines[P_CELLINDEX]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
new StaticText(line, rect_t{}, STR_ALTSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, &sensor->dist.alt, isAltSensor);
lv_obj_clear_flag(paramLines[P_ALTSENSOR]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else {
new StaticText(line, rect_t{}, STR_SOURCE + std::to_string(2), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, (uint8_t *) &sensor->calc.sources[1], isSensorAvailable);
lv_obj_clear_flag(paramLines[P_CALC1]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
}
else if (sensor->unit == UNIT_RPMS) {
new StaticText(line, rect_t{}, STR_MULTIPLIER, 0, COLOR_THEME_PRIMARY1);
new NumberEdit(line, rect_t{}, 1, 30000, GET_SET_DEFAULT(sensor->custom.offset));
lv_obj_clear_flag(paramLines[P_MULT]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
else {
new StaticText(line, rect_t{}, STR_OFFSET, 0, COLOR_THEME_PRIMARY1);
new NumberEdit(line, rect_t{}, -30000, 30000, GET_SET_DEFAULT(sensor->custom.offset),
0, (sensor->prec > 0) ? (sensor->prec == 2 ? PREC2 : PREC1) : 0);
lv_obj_clear_flag(paramLines[P_OFFSET]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
}
if ((sensor->type == TELEM_TYPE_CALCULATED && sensor->formula < TELEM_FORMULA_MULTIPLY)) {
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_SOURCE + std::to_string(3), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, (uint8_t *) &sensor->calc.sources[2], isSensorAvailable);
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_SOURCE + std::to_string(4), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(line, rect_t{}, (uint8_t *) &sensor->calc.sources[3], isSensorAvailable);
lv_obj_clear_flag(paramLines[P_CALC2]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(paramLines[P_CALC3]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
// Auto Offset
if (sensor->unit != UNIT_RPMS && sensor->isConfigurable()) {
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_AUTOOFFSET, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(sensor->autoOffset));
lv_obj_clear_flag(paramLines[P_AUTOOFFSET]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
if (sensor->isConfigurable()) {
// Only positive
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_ONLYPOSITIVE, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(sensor->onlyPositive));
lv_obj_clear_flag(paramLines[P_ONLYPOS]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
// Filter
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_FILTER, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(sensor->filter));
lv_obj_clear_flag(paramLines[P_FILTER]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
if (sensor->type == TELEM_TYPE_CALCULATED) {
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_PERSISTENT, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_DEFAULT(sensor->persistent), [=](int32_t newValue) {
sensor->persistent = newValue;
if (!sensor->persistent)
sensor->persistentValue = 0;
SET_DIRTY();
});
lv_obj_clear_flag(paramLines[P_PERSISTENT]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
line = sensorParametersWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_LOGS, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_DEFAULT(sensor->logs), [=](int32_t newValue) {
sensor->logs = newValue;
logsClose();
SET_DIRTY();
});
}
void buildBody(FormWindow * window)
@@ -514,6 +542,7 @@ class SensorEditWindow : public Page {
form->padAll(4);
FlexGridLayout grid(e_col_dsc, row_dsc, 2);
FlexGridLayout grid2(e_col_dsc2, row_dsc, 2);
TelemetrySensor * sensor = &g_model.telemetrySensors[index];
@@ -535,11 +564,155 @@ class SensorEditWindow : public Page {
sensor->autoOffset = 0;
}
SET_DIRTY();
updateSensorParametersWindow();
updateSensorParameters();
});
sensorParametersWindow = new FormWindow(form, rect_t{});
updateSensorParametersWindow();
// Parameters
paramLines[P_FORMULA] = form->newLine(&grid);
new StaticText(paramLines[P_FORMULA], rect_t{}, STR_FORMULA, 0, COLOR_THEME_PRIMARY1);
new Choice(paramLines[P_FORMULA], rect_t{}, STR_VFORMULAS, 0, TELEM_FORMULA_LAST, GET_DEFAULT(sensor->formula),
[=](uint8_t newValue) {
sensor->formula = newValue;
sensor->param = 0;
if (sensor->formula == TELEM_FORMULA_CELL) {
sensor->unit = UNIT_VOLTS;
sensor->prec = 2;
}
else if (sensor->formula == TELEM_FORMULA_DIST) {
sensor->unit = UNIT_DIST;
sensor->prec = 0;
}
else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
sensor->unit = UNIT_MAH;
sensor->prec = 0;
}
SET_DIRTY();
telemetryItems[index].clear();
updateSensorParameters();
});
paramLines[P_ID] = form->newLine(&grid2);
new StaticText(paramLines[P_ID], rect_t{}, STR_ID, 0, COLOR_THEME_PRIMARY1);
auto hex = new NumberEdit(paramLines[P_ID], rect_t{}, 0, 0xFFFF, GET_SET_DEFAULT(sensor->id));
hex->setDisplayHandler([](int32_t value) {
std::stringstream stream;
stream << std::hex << value;
return stream.str();
});
new NumberEdit(paramLines[P_ID], rect_t{}, 0, 0xff, GET_SET_DEFAULT(sensor->instance));
paramLines[P_UNIT] = form->newLine(&grid);
new StaticText(paramLines[P_UNIT], rect_t{}, STR_UNIT, 0, COLOR_THEME_PRIMARY1);
new Choice(paramLines[P_UNIT], rect_t{}, STR_VTELEMUNIT, 0, UNIT_MAX, GET_DEFAULT(sensor->unit),
[=](uint8_t newValue) {
sensor->unit = newValue;
if (sensor->unit == UNIT_FAHRENHEIT) {
sensor->prec = 0;
}
SET_DIRTY();
telemetryItems[index].clear();
updateSensorParameters();
});
paramLines[P_PREC] = form->newLine(&grid);
new StaticText(paramLines[P_PREC], rect_t{}, STR_PRECISION, 0, COLOR_THEME_PRIMARY1);
new Choice(paramLines[P_PREC], rect_t{}, STR_VPREC, 0, 2, GET_DEFAULT(sensor->prec),
[=](uint8_t newValue) {
sensor->prec = newValue;
SET_DIRTY();
telemetryItems[index].clear();
updateSensorParameters();
});
paramLines[P_CELLSENSOR] = form->newLine(&grid);
new StaticText(paramLines[P_CELLSENSOR], rect_t{}, STR_CELLSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_CELLSENSOR], rect_t{}, &sensor->cell.source, isCellsSensor);
paramLines[P_GPSSENSOR] = form->newLine(&grid);
new StaticText(paramLines[P_GPSSENSOR], rect_t{}, STR_GPSSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_GPSSENSOR], rect_t{}, &sensor->dist.gps, isGPSSensor);
paramLines[P_CURRENTSENSOR] = form->newLine(&grid);
new StaticText(paramLines[P_CURRENTSENSOR], rect_t{}, STR_CURRENTSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_CURRENTSENSOR], rect_t{}, &sensor->consumption.source, isSensorAvailable);
paramLines[P_CONSUMPTIONSOURCE] = form->newLine(&grid);
new StaticText(paramLines[P_CONSUMPTIONSOURCE], rect_t{}, STR_SOURCE, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_CONSUMPTIONSOURCE], rect_t{}, &sensor->consumption.source, isSensorAvailable);
paramLines[P_CALC0] = form->newLine(&grid);
new StaticText(paramLines[P_CALC0], rect_t{}, STR_SOURCE + std::to_string(1), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_CALC0], rect_t{}, (uint8_t *) &sensor->calc.sources[0], isSensorAvailable);
paramLines[P_BLADES] = form->newLine(&grid);
new StaticText(paramLines[P_BLADES], rect_t{}, STR_BLADES, 0, COLOR_THEME_PRIMARY1);
new NumberEdit(paramLines[P_BLADES], rect_t{}, 1, 30000, GET_SET_DEFAULT(sensor->custom.ratio));
paramLines[P_RATIO] = form->newLine(&grid);
new StaticText(paramLines[P_RATIO], rect_t{}, STR_RATIO, 0, COLOR_THEME_PRIMARY1);
auto edit = new NumberEdit(paramLines[P_RATIO], rect_t{}, 0, 30000, GET_SET_DEFAULT(sensor->custom.ratio));
edit->setZeroText("-");
paramLines[P_CELLINDEX] = form->newLine(&grid);
new StaticText(paramLines[P_CELLINDEX], rect_t{}, STR_CELLINDEX, 0, COLOR_THEME_PRIMARY1);
new Choice(paramLines[P_CELLINDEX], rect_t{}, STR_VCELLINDEX, TELEM_CELL_INDEX_LOWEST, TELEM_CELL_INDEX_LAST, GET_SET_DEFAULT(sensor->cell.index));
paramLines[P_ALTSENSOR] = form->newLine(&grid);
new StaticText(paramLines[P_ALTSENSOR], rect_t{}, STR_ALTSENSOR, 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_ALTSENSOR], rect_t{}, &sensor->dist.alt, isAltSensor);
paramLines[P_CALC1] = form->newLine(&grid);
new StaticText(paramLines[P_CALC1], rect_t{}, STR_SOURCE + std::to_string(2), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_CALC1], rect_t{}, (uint8_t *) &sensor->calc.sources[1], isSensorAvailable);
paramLines[P_MULT] = form->newLine(&grid);
new StaticText(paramLines[P_MULT], rect_t{}, STR_MULTIPLIER, 0, COLOR_THEME_PRIMARY1);
new NumberEdit(paramLines[P_MULT], rect_t{}, 1, 30000, GET_SET_DEFAULT(sensor->custom.offset));
paramLines[P_OFFSET] = form->newLine(&grid);
new StaticText(paramLines[P_OFFSET], rect_t{}, STR_OFFSET, 0, COLOR_THEME_PRIMARY1);
new NumberEdit(paramLines[P_OFFSET], rect_t{}, -30000, 30000, GET_SET_DEFAULT(sensor->custom.offset),
0, (sensor->prec > 0) ? (sensor->prec == 2 ? PREC2 : PREC1) : 0);
paramLines[P_CALC2] = form->newLine(&grid);
new StaticText(paramLines[P_CALC2], rect_t{}, STR_SOURCE + std::to_string(3), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_CALC2], rect_t{}, (uint8_t *) &sensor->calc.sources[2], isSensorAvailable);
paramLines[P_CALC3] = form->newLine(&grid);
new StaticText(paramLines[P_CALC3], rect_t{}, STR_SOURCE + std::to_string(4), 0, COLOR_THEME_PRIMARY1);
new SensorSourceChoice(paramLines[P_CALC3], rect_t{}, (uint8_t *) &sensor->calc.sources[3], isSensorAvailable);
paramLines[P_AUTOOFFSET] = form->newLine(&grid);
new StaticText(paramLines[P_AUTOOFFSET], rect_t{}, STR_AUTOOFFSET, 0, COLOR_THEME_PRIMARY1);
new CheckBox(paramLines[P_AUTOOFFSET], rect_t{}, GET_SET_DEFAULT(sensor->autoOffset));
paramLines[P_ONLYPOS] = form->newLine(&grid);
new StaticText(paramLines[P_ONLYPOS], rect_t{}, STR_ONLYPOSITIVE, 0, COLOR_THEME_PRIMARY1);
new CheckBox(paramLines[P_ONLYPOS], rect_t{}, GET_SET_DEFAULT(sensor->onlyPositive));
paramLines[P_FILTER] = form->newLine(&grid);
new StaticText(paramLines[P_FILTER], rect_t{}, STR_FILTER, 0, COLOR_THEME_PRIMARY1);
new CheckBox(paramLines[P_FILTER], rect_t{}, GET_SET_DEFAULT(sensor->filter));
paramLines[P_PERSISTENT] = form->newLine(&grid);
new StaticText(paramLines[P_PERSISTENT], rect_t{}, STR_PERSISTENT, 0, COLOR_THEME_PRIMARY1);
new CheckBox(paramLines[P_PERSISTENT], rect_t{}, GET_DEFAULT(sensor->persistent), [=](int32_t newValue) {
sensor->persistent = newValue;
if (!sensor->persistent)
sensor->persistentValue = 0;
SET_DIRTY();
});
// Logs
line = form->newLine(&grid);
new StaticText(line, rect_t{}, STR_LOGS, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_DEFAULT(sensor->logs), [=](int32_t newValue) {
sensor->logs = newValue;
logsClose();
SET_DIRTY();
});
updateSensorParameters();
}
};
@@ -562,10 +735,7 @@ void ModelTelemetryPage::checkEvents()
void ModelTelemetryPage::rebuild(FormWindow * window, int8_t focusSensorIndex)
{
auto scroll_y = lv_obj_get_scroll_y(window->getLvObj());
window->clear();
build(window, focusSensorIndex);
lv_obj_scroll_to_y(window->getLvObj(), scroll_y, LV_ANIM_OFF);
buildSensorList(focusSensorIndex);
lastKnownIndex = availableTelemetryIndex();
}
@@ -579,53 +749,18 @@ void ModelTelemetryPage::editSensor(FormWindow * window, uint8_t index)
});
}
#if LCD_W > LCD_H
#define B_HEIGHT 32
#else
#define B_HEIGHT 44
#endif
void ModelTelemetryPage::build(FormWindow * window, int8_t focusSensorIndex)
void ModelTelemetryPage::buildSensorList(int8_t focusSensorIndex)
{
window->padAll(4);
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 0);
bool didFocus = false;
SensorButton* first = nullptr;
this->window = window;
sensorWindow->clear();
FlexGridLayout grid(col_dsc, row_dsc, 2);
FlexGridLayout grid2(col_dsc2, row_dsc, 2);
// Sensors
auto line = window->newLine(&grid2);
lv_obj_set_style_pad_row(line->getLvObj(), 0, 0);
lv_obj_set_style_pad_column(line->getLvObj(), 4, 0);
auto subttl = new Subtitle(line, rect_t{}, STR_TELEMETRY_SENSORS, 0, COLOR_THEME_PRIMARY1);
#if LCD_H > LCD_W
lv_obj_set_grid_cell(subttl->getLvObj(), LV_GRID_ALIGN_START, 0, 3, LV_GRID_ALIGN_CENTER, 0, 1);
line = window->newLine(&grid2);
lv_obj_set_style_pad_row(line->getLvObj(), 0, 0);
lv_obj_set_style_pad_column(line->getLvObj(), 4, 0);
grid2.nextCell();
#endif
// Sensors columns titles
uint8_t sensorsCount = getTelemetrySensorsCount();
if (sensorsCount > 0) {
new StaticText(line, rect_t{}, STR_NAME, 0, FONT(XS) | COLOR_THEME_PRIMARY1);
grid2.nextCell();
new StaticText(line, rect_t{}, STR_VALUE, 0, FONT(XS) | COLOR_THEME_PRIMARY1);
idLabel = new StaticText(line, rect_t{}, STR_ID, 0, FONT(XS) | COLOR_THEME_PRIMARY1);
if (g_model.ignoreSensorIds)
lv_obj_add_flag(idLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
FlexGridLayout grid3(col_dsc3, row_dsc, 2);
for (uint8_t idx = 0; idx < MAX_TELEMETRY_SENSORS; idx++) {
if (g_model.telemetrySensors[idx].isAvailable()) {
line = window->newLine(&grid3);
auto button = new SensorButton(line, rect_t{0, 0, LCD_W-12, 25}, idx);
auto button = new SensorButton(sensorWindow, rect_t{}, idx);
if (!first) first = button;
button->setPressHandler([=]() -> uint8_t {
Menu * menu = new Menu(window);
@@ -650,21 +785,56 @@ void ModelTelemetryPage::build(FormWindow * window, int8_t focusSensorIndex)
});
menu->addLine(STR_DELETE, [=]() {
delTelemetryIndex(idx); // calls setDirty internally
rebuild(window);
for (uint8_t i = idx + 1; i < MAX_TELEMETRY_SENSORS; i += 1) {
if (g_model.telemetrySensors[i].isAvailable()) {
rebuild(window, i);
return;
}
}
for (uint8_t i = idx - 1; i >= 0; i -= 1) {
if (g_model.telemetrySensors[i].isAvailable()) {
rebuild(window, i);
return;
}
}
rebuild(window,-1);
});
return 0;
});
if (focusSensorIndex == idx) {
lv_group_focus_obj(button->getLvObj());
didFocus = true;
}
}
}
if (!didFocus) {
if (first && !allowNewSensors)
lv_group_focus_obj(first->getLvObj());
else
lv_group_focus_obj(discover->getLvObj());
}
}
void ModelTelemetryPage::build(FormWindow * window)
{
window->padAll(4);
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 0);
this->window = window;
// Sensors
new Subtitle(window, rect_t{}, STR_TELEMETRY_SENSORS, 0, COLOR_THEME_PRIMARY1);
sensorWindow = new FormWindow(window, rect_t{});
sensorWindow->padAll(0);
sensorWindow->setFlexLayout(LV_FLEX_FLOW_COLUMN, 4);
FlexGridLayout grid4(col_dsc4, row_dsc, 4);
// Autodiscover button
line = window->newLine(&grid4);
auto discover = new TextButton(line, rect_t{}, (allowNewSensors) ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS);
auto line = window->newLine(&grid4);
discover = new TextButton(line, rect_t{}, (allowNewSensors) ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS);
discover->setPressHandler([=]() {
allowNewSensors = !allowNewSensors;
if (allowNewSensors) {
@@ -690,14 +860,15 @@ void ModelTelemetryPage::build(FormWindow * window, int8_t focusSensorIndex)
});
lv_obj_set_grid_cell(b->getLvObj(), LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);
uint8_t sensorsCount = getTelemetrySensorsCount();
if (sensorsCount > 0) {
#if TWOCOLBUTTONS
line = window->newLine(&grid4);
#endif
// Delete all sensors button
b = new TextButton(line, rect_t{}, STR_DELETE_ALL_SENSORS,
[]() -> uint8_t {
new FullScreenDialog(WARNING_TYPE_CONFIRM, STR_CONFIRMDELETE, "", "", [=]() {
[=]() -> uint8_t {
new ConfirmDialog(window, STR_DELETE_ALL_SENSORS, STR_CONFIRMDELETE, [=]() {
for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
delTelemetryIndex(i);
}
@@ -712,22 +883,22 @@ void ModelTelemetryPage::build(FormWindow * window, int8_t focusSensorIndex)
#endif
}
FlexGridLayout grid(col_dsc, row_dsc, 2);
// Show instance IDs button
line = window->newLine(&grid);
line->padLeft(10);
new StaticText(line, rect_t{}, STR_SHOW_INSTANCE_ID, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(g_model.showInstanceIds));
// Ignore instance button
line = window->newLine(&grid);
line->padLeft(10);
new StaticText(line, rect_t{}, STR_IGNORE_INSTANCE, 0, COLOR_THEME_PRIMARY1);
new CheckBox(line, rect_t{}, GET_DEFAULT(g_model.ignoreSensorIds),
[=](bool newValue) {
g_model.ignoreSensorIds = newValue;
if (newValue)
lv_obj_add_flag(idLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
else
lv_obj_clear_flag(idLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
});
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(g_model.ignoreSensorIds));
// RSSI
line = window->newLine(&grid);
new Subtitle(line, rect_t{}, getRssiLabel(), 0, COLOR_THEME_PRIMARY1);
new Subtitle(window, rect_t{}, getRssiLabel(), 0, COLOR_THEME_PRIMARY1);
line = window->newLine(&grid);
line->padLeft(10);
@@ -745,8 +916,7 @@ void ModelTelemetryPage::build(FormWindow * window, int8_t focusSensorIndex)
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(g_model.disableTelemetryWarning));
// Vario
line = window->newLine(&grid);
new Subtitle(line, rect_t{}, STR_VARIO, 0, COLOR_THEME_PRIMARY1);
new Subtitle(window, rect_t{}, STR_VARIO, 0, COLOR_THEME_PRIMARY1);
FlexGridLayout grid5(col_dsc5, row_dsc, 4);
@@ -786,6 +956,9 @@ void ModelTelemetryPage::build(FormWindow * window, int8_t focusSensorIndex)
cMax->setAvailableHandler([](int val) { return g_model.varioData.centerMin - 5 < val; });
new Choice(line, rect_t{}, STR_VVARIOCENTER, 0, 1, GET_SET_DEFAULT(g_model.varioData.centerSilent));
// Don't call this before the 'discover' button has been created
buildSensorList(-1);
}
+5 -7
View File
@@ -28,21 +28,19 @@ class ModelTelemetryPage: public PageTab {
public:
ModelTelemetryPage();
void build(FormWindow * window) override
{
build(window, -1);
}
void build(FormWindow * window) override;
void checkEvents() override;
protected:
int lastKnownIndex = 0;
FormWindow * window = nullptr;
Window* idLabel = nullptr;
FormWindow* window = nullptr;
FormWindow* sensorWindow = nullptr;
TextButton* discover = nullptr;
void editSensor(FormWindow * window, uint8_t index);
void build(FormWindow * window, int8_t focusSensorIndex=-1);
void rebuild(FormWindow * window, int8_t focusSensorIndex=-1);
void buildSensorList(int8_t focusSensorIndex=-1);
};
#endif //_MODEL_TELEMETRY_H