feat(color): Change global variables layout to better match other pages (#3116)

* Change global variables layout to better match other pages.

* Move internal classes for global variable page from .h to .cpp file. Convert header text in edit page to StaticText object and remove 'paint' function.

* Fix build error.

* chore: Formatting
This commit is contained in:
philmoz
2023-01-28 12:28:18 +10:00
committed by GitHub
parent e9b8a23ba4
commit 7a1231753a
4 changed files with 397 additions and 439 deletions
+368 -359
View File
@@ -22,421 +22,430 @@
#include "opentx.h"
#include "model_gvars.h"
#include "libopenui.h"
#include "numberedit.h"
#include "lvgl_widgets/input_mix_line.h"
#define SET_DIRTY() storageDirty(EE_MODEL)
#define SET_DIRTY() storageDirty(EE_MODEL)
#define TEXT_LEFT_MARGIN 2
#define GVAR_NAME_SIZE 45
#define GVAR_NAME_SIZE 44
#if LCD_W > LCD_H
#define GVAR_VAL_SIZE 45
#define GVAR_TTL_OFST 6
#else
#define GVAR_VAL_SIZE 50
#define GVAR_TTL_OFST 24
#endif
static const lv_coord_t btn_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(2),
LV_GRID_TEMPLATE_LAST};
static const lv_coord_t btn_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT,
LV_GRID_TEMPLATE_LAST};
GVarButton::GVarButton(FormGroup * parent, const rect_t &rect, uint8_t gvar) :
Button(parent, rect, nullptr, 0, 0, lv_btn_create),
gvarIdx(gvar)
class GVarButton : public Button
{
setHeight(LV_SIZE_CONTENT);
setWidth(LV_PCT(100));
public:
GVarButton(FormGroup* parent, const rect_t& rect, uint8_t gvar) :
Button(parent, rect, nullptr, 0, 0, input_mix_line_create), gvarIdx(gvar)
{
setHeight(LV_SIZE_CONTENT);
setWidth(LV_PCT(100));
build();
}
void GVarButton::checkEvents()
{
Button::checkEvents();
uint8_t newFM = getFlightMode();
if (currentFlightMode != newFM) {
uint8_t lastFM = currentFlightMode;
currentFlightMode = newFM;
labels[lastFM]->setFont(FONT(STD));
labels[currentFlightMode]->setFont(FONT(BOLD));
updateValueText(lastFM);
updateValueText(currentFlightMode);
build();
}
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
FlightModeData * fmData = &g_model.flightModeData[flightMode];
if(values[flightMode] != fmData->gvars[gvarIdx])
{
protected:
void checkEvents()
{
Button::checkEvents();
uint8_t newFM = getFlightMode();
if (currentFlightMode != newFM) {
uint8_t lastFM = currentFlightMode;
currentFlightMode = newFM;
labels[lastFM]->setBackgroundColor(COLOR_THEME_PRIMARY2);
labels[currentFlightMode]->setBackgroundColor(COLOR_THEME_SECONDARY3);
updateValueText(lastFM);
updateValueText(currentFlightMode);
}
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
FlightModeData* fmData = &g_model.flightModeData[flightMode];
if (values[flightMode] != fmData->gvars[gvarIdx]) {
updateValueText(flightMode);
}
}
}
protected:
uint8_t gvarIdx;
int lines;
int32_t gvarSum = 0; // used for invalidation
uint8_t currentFlightMode = 0; // used for invalidation
StaticText* labels[MAX_FLIGHT_MODES];
StaticText* valueTexts[MAX_FLIGHT_MODES];
gvar_t values[MAX_FLIGHT_MODES];
void build()
{
lv_obj_set_flex_flow(lvobj, LV_FLEX_FLOW_ROW);
lv_obj_set_style_pad_all(lvobj, 0, LV_PART_MAIN);
auto t =
new StaticText(this, rect_t{0, 0, GVAR_NAME_SIZE, PAGE_LINE_HEIGHT},
getGVarString(gvarIdx), 0, COLOR_THEME_SECONDARY1);
t->padLeft(1);
t->padTop(GVAR_TTL_OFST);
Window* container = new Window(this, rect_t{});
lv_obj_set_style_pad_all(container->getLvObj(), 0, LV_PART_MAIN);
lv_obj_set_style_flex_grow(container->getLvObj(), 2, LV_PART_MAIN);
lv_obj_set_height(container->getLvObj(), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(container->getLvObj(), LV_FLEX_FLOW_ROW_WRAP);
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
Window* fmCont = new Window(container, rect_t{});
fmCont->padAll(0);
lv_obj_set_width(fmCont->getLvObj(), GVAR_VAL_SIZE);
lv_obj_set_height(fmCont->getLvObj(), PAGE_LINE_HEIGHT * 2 - 6);
lv_obj_set_flex_flow(fmCont->getLvObj(), LV_FLEX_FLOW_COLUMN);
char label[16] = {};
getFlightModeString(label, flightMode + 1);
labels[flightMode] = new StaticText(fmCont, rect_t{}, label, 0,
COLOR_THEME_SECONDARY1 | CENTERED);
labels[flightMode]->setHeight(PAGE_LINE_HEIGHT - 6);
labels[flightMode]->setWidth(GVAR_VAL_SIZE);
labels[flightMode]->setFont(FONT(XS));
labels[flightMode]->setBackgroundColor(COLOR_THEME_PRIMARY2);
labels[flightMode]->setBackgroudOpacity(LV_OPA_COVER);
valueTexts[flightMode] = new StaticText(
fmCont, rect_t{}, "", 0, COLOR_THEME_SECONDARY1 | CENTERED);
StaticText* valText = valueTexts[flightMode];
if (flightMode == currentFlightMode) {
labels[flightMode]->setBackgroundColor(COLOR_THEME_SECONDARY3);
}
lv_obj_set_style_flex_track_place(valText->getLvObj(), LV_FLEX_ALIGN_END,
LV_PART_MAIN);
valText->setWidth(GVAR_VAL_SIZE);
valText->setBackgroundColor(COLOR_THEME_PRIMARY2);
valText->setBackgroudOpacity(LV_OPA_COVER);
valText->setHeight(PAGE_LINE_HEIGHT);
valText->setFont(FONT(STD));
updateValueText(flightMode);
}
}
}
void GVarButton::build()
{
lv_obj_set_flex_flow(lvobj, LV_FLEX_FLOW_ROW);
lv_obj_set_style_pad_all(lvobj, 0, LV_PART_MAIN);
lv_obj_set_style_bg_color(lvobj, makeLvColor(COLOR_THEME_SECONDARY2), LV_PART_MAIN);
lv_obj_set_style_bg_opa(lvobj, LV_OPA_COVER, LV_PART_MAIN);
void updateValueText(uint8_t flightMode)
{
StaticText* field = valueTexts[flightMode];
gvar_t value = g_model.flightModeData[flightMode].gvars[gvarIdx];
values[flightMode] = value;
auto t = new StaticText(this, rect_t{}, getGVarString(gvarIdx), 0, COLOR_THEME_PRIMARY1);
t->setWidth(GVAR_NAME_SIZE);
Window* container = new Window(this, rect_t{});
lv_obj_set_style_pad_all(container->getLvObj(), 0, LV_PART_MAIN);
lv_obj_set_style_flex_grow(container->getLvObj(), 2, LV_PART_MAIN);
lv_obj_set_height(container->getLvObj(), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(container->getLvObj(), LV_FLEX_FLOW_ROW_WRAP);
if (value > GVAR_MAX) {
uint8_t fm = value - GVAR_MAX - 1;
if (fm >= flightMode) fm += 1;
char label[16] = {};
getFlightModeString(label, fm + 1);
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
Window* fmCont = new Window(container, rect_t{});
lv_obj_set_width(fmCont->getLvObj(), GVAR_NAME_SIZE);
lv_obj_set_height(fmCont->getLvObj(), PAGE_LINE_HEIGHT*2);
lv_obj_set_style_pad_hor(fmCont->getLvObj(), 3, LV_PART_MAIN);
char label[16] = {};
getFlightModeString(label, flightMode + 1);
lv_obj_set_flex_flow(fmCont->getLvObj(), LV_FLEX_FLOW_COLUMN);
labels[flightMode] = new StaticText(fmCont, rect_t{}, label, 0, COLOR_THEME_PRIMARY1|CENTERED);
labels[flightMode]->setHeight(PAGE_LINE_HEIGHT);
labels[flightMode]->setWidth(GVAR_NAME_SIZE);
valueTexts[flightMode] = new StaticText(fmCont, rect_t{}, "", 0, COLOR_THEME_PRIMARY1|CENTERED);
StaticText* valText = valueTexts[flightMode];
if (flightMode == currentFlightMode)
{
labels[flightMode]->setFont(FONT(BOLD));
valText->setFont(FONT(BOLD));
}
lv_obj_set_style_flex_track_place(valText->getLvObj(), LV_FLEX_ALIGN_END, LV_PART_MAIN);
valText->setWidth(GVAR_NAME_SIZE);
valText->setBackgroundColor(COLOR_THEME_PRIMARY2);
valText->setBackgroudOpacity(LV_OPA_COVER);
valText->setHeight(PAGE_LINE_HEIGHT);
updateValueText(flightMode);
}
}
void GVarButton::updateValueText(uint8_t flightMode)
{
StaticText* field = valueTexts[flightMode];
gvar_t value = g_model.flightModeData[flightMode].gvars[gvarIdx];
values[flightMode] = value;
if (value > GVAR_MAX) {
uint8_t fm = value - GVAR_MAX - 1;
if (fm >= flightMode)
fm += 1;
char label[16] = {};
getFlightModeString(label, fm + 1);
lv_label_set_text(field->getLvObj(), label);
if(flightMode == currentFlightMode)
field->setFont(FONT(BOLD));
else
field->setFont(FONT(STD));
} else {
uint8_t unit = g_model.gvars[gvarIdx].unit;
const char * suffix = (unit == 1) ? "%": "";
uint8_t prec = g_model.gvars[gvarIdx].prec;
if(prec)
lv_label_set_text_fmt(field->getLvObj(), "%d.%01u%s", value/10, (value<0)?(-value)%10:value%10, suffix);
else
lv_label_set_text_fmt(field->getLvObj(), "%d%s", value, suffix);
if(unit)
{
if (value <= -1000 || value >= 1000
|| (prec && (value <= -100)) ) {
field->setFont(FONT(XS));
} else if (value <= -100) {
field->setFont(FONT(STD));
} else {
if(flightMode == currentFlightMode)
field->setFont(FONT(BOLD));
else
field->setFont(FONT(STD));
}
lv_label_set_text(field->getLvObj(), label);
} else {
if(value > -1000 && flightMode == currentFlightMode)
field->setFont(FONT(BOLD));
uint8_t unit = g_model.gvars[gvarIdx].unit;
const char* suffix = (unit == 1) ? "%" : "";
uint8_t prec = g_model.gvars[gvarIdx].prec;
if (prec)
lv_label_set_text_fmt(field->getLvObj(), "%d.%01u%s", value / 10,
(value < 0) ? (-value) % 10 : value % 10, suffix);
else
field->setFont(FONT(STD));
lv_label_set_text_fmt(field->getLvObj(), "%d%s", value, suffix);
if (unit) {
if (value <= -1000 || value >= 1000 || (prec && (value <= -100))) {
field->setFont(FONT(XS));
} else if (value <= -100) {
field->setFont(FONT(STD));
}
}
}
if (flightMode == currentFlightMode)
field->setBackgroundColor(COLOR_THEME_SECONDARY3);
else
field->setBackgroundColor(COLOR_THEME_PRIMARY2);
}
}
};
void GVarRenderer::paint(BitmapBuffer * dc)
class GVarEditWindow : public Page
{
lastFlightMode = getFlightMode();
FlightModeData * fmData = &g_model.flightModeData[lastFlightMode];
lastGVar = fmData->gvars[index];
coord_t x = drawStringWithIndex(dc, 0, FIELD_PADDING_TOP, STR_GV, index + 1,
COLOR_THEME_PRIMARY2, nullptr, "=");
if (lastGVar > GVAR_MAX) {
uint8_t fm = lastGVar - GVAR_MAX - 1;
if (fm >= lastFlightMode)
fm++;
char label[16];
getFlightModeString(label, fm + 1);
dc->drawSizedText(x, FIELD_PADDING_TOP, label, strlen(label), COLOR_THEME_PRIMARY2);
} else {
drawGVarValue(dc, x, FIELD_PADDING_TOP, index, lastGVar, COLOR_THEME_PRIMARY2);
public:
explicit GVarEditWindow(uint8_t gvarIndex) :
Page(ICON_MODEL_GVARS), index(gvarIndex)
{
buildHeader(&header);
buildBody(&body);
}
}
void GVarRenderer::checkEvents()
{
if (lastFlightMode != getFlightMode()) {
invalidate();
updated = true;
}
if (lastGVar != g_model.flightModeData[getFlightMode()].gvars[index]) {
invalidate();
updated = true;
}
}
protected:
uint8_t index;
gvar_t lastGVar = 0;
uint8_t lastFlightMode = 0;
NumberEdit* min = nullptr;
NumberEdit* max = nullptr;
NumberEdit* values[MAX_FLIGHT_MODES] = {};
StaticText* gVarInHeader = nullptr;
bool GVarRenderer::isUpdated()
{
if (!updated)
return false;
updated = false;
return true;
}
void GVarEditWindow::buildHeader(Window * window)
{
header.setTitle(STR_GLOBAL_VAR);
gVarInHeader =
new GVarRenderer(window,
void buildHeader(Window* window)
{
header.setTitle(STR_GLOBAL_VAR);
gVarInHeader =
new StaticText(window,
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT,
LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT},
index);
}
"", 0, COLOR_THEME_PRIMARY2);
}
void GVarEditWindow::checkEvents()
{
Page::checkEvents();
if (gVarInHeader && gVarInHeader->isUpdated()) {
for (auto & value : values) {
value->invalidate();
void checkEvents()
{
Page::checkEvents();
if (gVarInHeader &&
((lastFlightMode != getFlightMode()) ||
(lastGVar != g_model.flightModeData[getFlightMode()].gvars[index]))) {
char label[32];
lastFlightMode = getFlightMode();
FlightModeData* fmData = &g_model.flightModeData[lastFlightMode];
lastGVar = fmData->gvars[index];
sprintf(label, "%s%d=", STR_GV, index + 1);
if (lastGVar > GVAR_MAX) {
uint8_t fm = lastGVar - GVAR_MAX - 1;
if (fm >= lastFlightMode) fm++;
getFlightModeString(label + strlen(label), fm + 1);
} else {
strcat(label, getGVarValue(index, lastGVar, 0).c_str());
}
gVarInHeader->setText(label);
for (auto& value : values) {
value->invalidate();
}
}
}
}
void GVarEditWindow::setProperties(int onlyForFlightMode)
{
GVarData * gvar = &g_model.gvars[index];
int32_t minValue = GVAR_MIN + gvar->min;
int32_t maxValue = GVAR_MAX - gvar->max;
const char * suffix = gvar->unit ? "%" : "";
void setProperties(int onlyForFlightMode = -1)
{
GVarData* gvar = &g_model.gvars[index];
int32_t minValue = GVAR_MIN + gvar->min;
int32_t maxValue = GVAR_MAX - gvar->max;
const char* suffix = gvar->unit ? "%" : "";
LcdFlags prec = gvar->prec ? PREC1 : 0;
if (min && max) {
min->setMax(maxValue);
max->setMin(minValue);
LcdFlags prec = gvar->prec ? PREC1 : 0;
if (min && max) {
min->setMax(maxValue);
max->setMin(minValue);
min->setSuffix(suffix);
max->setSuffix(suffix);
min->setSuffix(suffix);
max->setSuffix(suffix);
LcdFlags minFlags = min->getTextFlags();
LcdFlags maxFlags = max->getTextFlags();
if(gvar->prec) {
minFlags |= PREC1;
maxFlags |= PREC1;
} else {
minFlags &= ~PREC1;
maxFlags &= ~PREC1;
LcdFlags minFlags = min->getTextFlags();
LcdFlags maxFlags = max->getTextFlags();
if (gvar->prec) {
minFlags |= PREC1;
maxFlags |= PREC1;
} else {
minFlags &= ~PREC1;
maxFlags &= ~PREC1;
}
min->setTextFlags(minFlags);
max->setTextFlags(maxFlags);
min->update();
max->update();
}
min->setTextFlags(minFlags);
max->setTextFlags(maxFlags);
FlightModeData* fmData;
for (int fm = 0; fm < MAX_FLIGHT_MODES; fm++) {
if (values[fm] == nullptr) // KLK: the order of calls has changed and
// this might not be initialized yet.
continue;
min->update();
max->update();
}
FlightModeData * fmData;
for (int fm = 0; fm < MAX_FLIGHT_MODES; fm++) {
if (values[fm] == nullptr) // KLK: the order of calls has changed and this might not be initialized yet.
continue;
if (onlyForFlightMode >= 0 && fm != onlyForFlightMode) continue;
fmData = &g_model.flightModeData[fm];
if (onlyForFlightMode >= 0 && fm != onlyForFlightMode)
continue;
fmData = &g_model.flightModeData[fm];
// custom value
if (fmData->gvars[index] <= GVAR_MAX || fm == 0) {
values[fm]->setMin(GVAR_MIN + gvar->min);
values[fm]->setMax(GVAR_MAX - gvar->max);
// custom value
if (fmData->gvars[index] <= GVAR_MAX || fm == 0) {
values[fm]->setMin(GVAR_MIN + gvar->min);
values[fm]->setMax(GVAR_MAX - gvar->max);
LcdFlags flags = values[fm]->getTextFlags();
if (gvar->prec)
flags |= PREC1;
else
flags &= ~PREC1;
values[fm]->setTextFlags(flags);
LcdFlags flags = values[fm]->getTextFlags();
if(gvar->prec)
flags |= PREC1;
else
flags &= ~PREC1;
values[fm]->setTextFlags(flags);
values[fm]->setDisplayHandler(nullptr);
}
else {
values[fm]->setMin(GVAR_MAX + 1);
values[fm]->setMax(GVAR_MAX + MAX_FLIGHT_MODES - 1);
values[fm]->setDisplayHandler([=](int32_t value) {
values[fm]->setDisplayHandler(nullptr);
} else {
values[fm]->setMin(GVAR_MAX + 1);
values[fm]->setMax(GVAR_MAX + MAX_FLIGHT_MODES - 1);
values[fm]->setDisplayHandler([=](int32_t value) {
uint8_t targetFlightMode = value - GVAR_MAX - 1;
if (targetFlightMode >= fm)
targetFlightMode++;
if (targetFlightMode >= fm) targetFlightMode++;
char label[16];
getFlightModeString(label, targetFlightMode + 1);
return std::string(label);
});
}
values[fm]->setSuffix(suffix);
values[fm]->invalidate();
}
if (gVarInHeader) gVarInHeader->invalidate();
}
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(2),
LV_GRID_TEMPLATE_LAST};
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT,
LV_GRID_TEMPLATE_LAST};
void GVarEditWindow::buildBody(FormWindow * window)
{
window->setFlexLayout();
FlexGridLayout grid(col_dsc, row_dsc, 2);
auto line = window->newLine(&grid);
GVarData * gvar = &g_model.gvars[index];
new StaticText(line, rect_t{}, STR_NAME, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
Window* input = new ModelTextEdit(line, rect_t{}, gvar->name, LEN_GVAR_NAME);
lv_obj_set_style_grid_cell_x_align(input->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_UNIT, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
input = new Choice(line, rect_t{}, "\001-%", 0, 1, GET_DEFAULT(gvar->unit),
[=](int16_t newValue) {
gvar->unit = newValue;
SET_DIRTY();
setProperties();
}
);
lv_obj_set_style_grid_cell_x_align(input->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_PRECISION, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
input = new Choice(line, rect_t{}, STR_VPREC, 0, 1, GET_DEFAULT(gvar->prec),
[=](int16_t newValue) {
gvar->prec = newValue;
SET_DIRTY();
setProperties();
}
);
lv_obj_set_style_grid_cell_x_align(input->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_MIN, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
min = new NumberEdit(line, rect_t{}, GVAR_MIN, GVAR_MAX - gvar->max,
[=] { return gvar->min + GVAR_MIN; },
[=](int32_t newValue) {
gvar->min = newValue - GVAR_MIN;
SET_DIRTY();
setProperties();
}
);
min->setAccelFactor(16);
lv_obj_set_style_grid_cell_x_align(min->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_MAX, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
max = new NumberEdit(line, rect_t{}, GVAR_MIN + gvar->min, GVAR_MAX,
[=] { return GVAR_MAX - gvar->max; },
[=](int32_t newValue) {
gvar->max = GVAR_MAX - newValue;
SET_DIRTY();
setProperties();
}
);
max->setAccelFactor(16);
lv_obj_set_style_grid_cell_x_align(max->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
line = window->newLine(&grid);
char flightModeName[16];
FlightModeData * fmData;
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
fmData = &g_model.flightModeData[flightMode];
getFlightModeString(flightModeName, flightMode + 1);
int userNameLen = zlen(fmData->name, LEN_FLIGHT_MODE_NAME);
if (userNameLen > 0) {
strcpy(flightModeName, fmData->name);
}
new StaticText(line, rect_t{}, flightModeName, 0, COLOR_THEME_PRIMARY1);
if (flightMode > 0) {
auto cb = new CheckBox(line, rect_t{},
[=] { return fmData->gvars[index] <= GVAR_MAX; }, [=](uint8_t checked) {
fmData->gvars[index] = checked ? 0 : GVAR_MAX + 1;
setProperties(flightMode);
});
lv_obj_set_style_grid_cell_x_align(cb->getLvObj(), LV_GRID_ALIGN_END, 0);
lv_obj_invalidate(cb->getLvObj());
cb->setLabel(STR_OWN);
}
} else {
grid.nextCell();
values[fm]->setSuffix(suffix);
values[fm]->invalidate();
}
values[flightMode] = new NumberEdit(line, rect_t{}, GVAR_MIN + gvar->min, GVAR_MAX + MAX_FLIGHT_MODES - 1,
GET_SET_DEFAULT(fmData->gvars[index]));
values[flightMode]->setAccelFactor(16);
line = window->newLine(&grid);
if (gVarInHeader) gVarInHeader->invalidate();
}
setProperties();
lv_obj_set_height(window->getLvObj(), LCD_H - lv_obj_get_height(header.getLvObj()));
lv_obj_set_height(lvobj, LCD_H);
}
void buildBody(FormWindow* window)
{
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT,
LV_GRID_TEMPLATE_LAST};
void ModelGVarsPage::rebuild(FormWindow * window)
window->setFlexLayout();
window->padAll(4);
FlexGridLayout grid(col_dsc, row_dsc, 2);
auto line = window->newLine(&grid);
GVarData* gvar = &g_model.gvars[index];
new StaticText(line, rect_t{}, STR_NAME, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
Window* input =
new ModelTextEdit(line, rect_t{}, gvar->name, LEN_GVAR_NAME);
lv_obj_set_style_grid_cell_x_align(input->getLvObj(), LV_GRID_ALIGN_STRETCH,
0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_UNIT, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
input = new Choice(line, rect_t{}, "\001-%", 0, 1, GET_DEFAULT(gvar->unit),
[=](int16_t newValue) {
gvar->unit = newValue;
SET_DIRTY();
setProperties();
});
lv_obj_set_style_grid_cell_x_align(input->getLvObj(), LV_GRID_ALIGN_STRETCH,
0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_PRECISION, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
input = new Choice(line, rect_t{}, STR_VPREC, 0, 1, GET_DEFAULT(gvar->prec),
[=](int16_t newValue) {
gvar->prec = newValue;
SET_DIRTY();
setProperties();
});
lv_obj_set_style_grid_cell_x_align(input->getLvObj(), LV_GRID_ALIGN_STRETCH,
0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_MIN, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
min = new NumberEdit(
line, rect_t{}, GVAR_MIN, GVAR_MAX - gvar->max,
[=] { return gvar->min + GVAR_MIN; },
[=](int32_t newValue) {
gvar->min = newValue - GVAR_MIN;
SET_DIRTY();
setProperties();
});
min->setAccelFactor(16);
lv_obj_set_style_grid_cell_x_align(min->getLvObj(), LV_GRID_ALIGN_STRETCH,
0);
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_MAX, 0, COLOR_THEME_PRIMARY1);
grid.nextCell();
max = new NumberEdit(
line, rect_t{}, GVAR_MIN + gvar->min, GVAR_MAX,
[=] { return GVAR_MAX - gvar->max; },
[=](int32_t newValue) {
gvar->max = GVAR_MAX - newValue;
SET_DIRTY();
setProperties();
});
max->setAccelFactor(16);
lv_obj_set_style_grid_cell_x_align(max->getLvObj(), LV_GRID_ALIGN_STRETCH,
0);
line = window->newLine(&grid);
char flightModeName[16];
FlightModeData* fmData;
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
fmData = &g_model.flightModeData[flightMode];
getFlightModeString(flightModeName, flightMode + 1);
int userNameLen = zlen(fmData->name, LEN_FLIGHT_MODE_NAME);
if (userNameLen > 0) {
strcpy(flightModeName, fmData->name);
}
new StaticText(line, rect_t{}, flightModeName, 0, COLOR_THEME_PRIMARY1);
if (flightMode > 0) {
auto cb = new CheckBox(
line, rect_t{}, [=] { return fmData->gvars[index] <= GVAR_MAX; },
[=](uint8_t checked) {
fmData->gvars[index] = checked ? 0 : GVAR_MAX + 1;
setProperties(flightMode);
});
lv_obj_set_style_grid_cell_x_align(cb->getLvObj(), LV_GRID_ALIGN_END,
0);
lv_obj_invalidate(cb->getLvObj());
cb->setLabel(STR_OWN);
} else {
grid.nextCell();
}
values[flightMode] = new NumberEdit(
line, rect_t{}, GVAR_MIN + gvar->min, GVAR_MAX + MAX_FLIGHT_MODES - 1,
GET_SET_DEFAULT(fmData->gvars[index]));
values[flightMode]->setAccelFactor(16);
line = window->newLine(&grid);
}
setProperties();
lv_obj_set_height(window->getLvObj(),
LCD_H - lv_obj_get_height(header.getLvObj()));
lv_obj_set_height(lvobj, LCD_H);
}
};
void ModelGVarsPage::rebuild(FormWindow* window)
{
auto scroll_y = lv_obj_get_scroll_y(window->getLvObj());
auto scroll_y = lv_obj_get_scroll_y(window->getLvObj());
window->clear();
build(window);
lv_obj_scroll_to_y(window->getLvObj(), scroll_y, LV_ANIM_OFF);
}
void ModelGVarsPage::build(FormWindow * window)
void ModelGVarsPage::build(FormWindow* window)
{
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 1);
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 2);
for (uint8_t index = 0; index < MAX_GVARS; index++) {
Button * button = new GVarButton(window, rect_t{}, index);
Button* button = new GVarButton(window, rect_t{}, index);
button->setPressHandler([=]() {
Menu * menu = new Menu(window);
menu->addLine(STR_EDIT, [=]() {
Window * editWindow = new GVarEditWindow(index);
editWindow->setCloseHandler([=]() {
rebuild(window);
});
});
menu->addLine(STR_CLEAR, [=]() {
for (auto & flightMode : g_model.flightModeData) {
flightMode.gvars[index] = 0;
}
storageDirty(EE_MODEL);
});
return 0;
Menu* menu = new Menu(window);
menu->addLine(STR_EDIT, [=]() {
Window* editWindow = new GVarEditWindow(index);
editWindow->setCloseHandler([=]() { rebuild(window); });
});
menu->addLine(STR_CLEAR, [=]() {
for (auto& flightMode : g_model.flightModeData) {
flightMode.gvars[index] = 0;
}
storageDirty(EE_MODEL);
});
return 0;
});
}
}
+7 -80
View File
@@ -21,89 +21,16 @@
#pragma once
#include "tabsgroup.h"
#include "page.h"
#include "tabsgroup.h"
#include "window.h"
#include "numberedit.h"
class GVarButton: public Button
class ModelGVarsPage : public PageTab
{
public:
GVarButton(FormGroup * parent, const rect_t & rect, uint8_t gvar);
protected:
void checkEvents() override;
protected:
uint8_t gvarIdx;
int lines;
int32_t gvarSum = 0; // used for invalidation
uint8_t currentFlightMode = 0; // used for invalidation
StaticText* labels[MAX_FLIGHT_MODES];
StaticText* valueTexts[MAX_FLIGHT_MODES];
gvar_t values[MAX_FLIGHT_MODES];
void build();
void updateValueText(uint8_t flightMode);
public:
ModelGVarsPage() : PageTab(STR_MENU_GLOBAL_VARS, ICON_MODEL_GVARS) {}
};
class ModelGVarsPage: public PageTab
{
public:
ModelGVarsPage():
PageTab(STR_MENU_GLOBAL_VARS, ICON_MODEL_GVARS)
{
}
protected:
void build(FormWindow * window) override;
void rebuild(FormWindow * window);
};
class GVarRenderer: public Window
{
friend class GVarEditWindow;
public:
GVarRenderer(Window * window, rect_t rect, uint8_t gvarIndex) :
Window(window, rect),
index(gvarIndex)
{
}
protected:
void paint(BitmapBuffer * dc) override;
void checkEvents() override;
bool isUpdated();
protected:
uint8_t index;
gvar_t lastGVar = 0;
uint8_t lastFlightMode = 0;
bool updated = false;
};
class GVarEditWindow: public Page
{
public:
explicit GVarEditWindow(uint8_t gvarIndex) :
Page(ICON_MODEL_GVARS),
index(gvarIndex)
{
buildHeader(&header);
buildBody(&body);
}
protected:
uint8_t index;
NumberEdit * min = nullptr;
NumberEdit * max = nullptr;
NumberEdit * values[MAX_FLIGHT_MODES] = {};
GVarRenderer * gVarInHeader = nullptr;
void buildHeader(Window * window);
void buildBody(FormWindow * window);
void setProperties(int onlyForFlightMode = -1);
void checkEvents() override;
protected:
void build(FormWindow* window) override;
void rebuild(FormWindow* window);
};
+19
View File
@@ -908,6 +908,25 @@ char *getSourceCustomValueString(source_t source, int32_t val, LcdFlags flags)
return getSourceCustomValueString(tmpHelpersString, source, val, flags);
}
std::string getValueWithUnit(int val, uint8_t unit, LcdFlags flags)
{
if ((flags & NO_UNIT) || unit == UNIT_RAW)
return formatNumberAsString(val, flags & (~NO_UNIT));
return formatNumberAsString(val, flags & (~NO_UNIT), 0, nullptr,
STR_VTELEMUNIT[unit]);
}
std::string getGVarValue(uint8_t gvar, gvar_t value, LcdFlags flags)
{
uint8_t prec = g_model.gvars[gvar].prec;
if (prec > 0) {
flags |= (prec == 1 ? PREC1 : PREC2);
}
return getValueWithUnit(
value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags);
}
#endif // defined(LIBOPENUI)
#endif // !defined(BOOT)
+3
View File
@@ -152,4 +152,7 @@ int strncasecmp(char (&s1)[L1], const char *const s2)
return strncasecmp(s1, s2, L1);
}
std::string getValueWithUnit(int val, uint8_t unit, LcdFlags flags);
std::string getGVarValue(uint8_t gvar, gvar_t value, LcdFlags flags);
#endif // _STRHELPERS_H_