Skip to content

Commit

Permalink
Use absolute layout when there are many TextEdit/NumberEdit objects d…
Browse files Browse the repository at this point in the history
…ue to slow performance of lv_textarea in a flex layout.
  • Loading branch information
philmoz committed Dec 22, 2023
1 parent 87b978a commit 783da75
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 99 deletions.
112 changes: 70 additions & 42 deletions radio/src/gui/colorlcd/hw_inputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,22 @@
#define SET_DIRTY() storageDirty(EE_GENERAL)

struct HWInputEdit : public RadioTextEdit {
HWInputEdit(Window* parent, char* name, size_t len) :
RadioTextEdit(parent, rect_t{0, 0, 64, 32}, name, len)
HWInputEdit(Window* parent, char* name, size_t len, coord_t x = 0,
coord_t y = 0) :
RadioTextEdit(parent, rect_t{x, y, 64, 32}, name, len)
{
}
};

static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
LV_GRID_TEMPLATE_LAST};
static const lv_coord_t col_three_dsc[] = {LV_GRID_FR(8), LV_GRID_FR(12), LV_GRID_FR(20),
LV_GRID_TEMPLATE_LAST};
static const lv_coord_t col_three_dsc[] = {
LV_GRID_FR(8), LV_GRID_FR(12), LV_GRID_FR(20), LV_GRID_TEMPLATE_LAST};

#if LCD_W > LCD_H
static const lv_coord_t pots_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(2), LV_GRID_FR(5),
LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};
static const lv_coord_t pots_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(2),
LV_GRID_FR(5), LV_GRID_FR(2),
LV_GRID_TEMPLATE_LAST};
#else
static const lv_coord_t pots_col_dsc[] = {LV_GRID_FR(13), LV_GRID_FR(7),
LV_GRID_TEMPLATE_LAST};
Expand All @@ -59,7 +61,7 @@ HWSticks::HWSticks(Window* parent) : Window(parent, rect_t{})
auto max_sticks = adcGetMaxInputs(ADC_INPUT_MAIN);
for (int i = 0; i < max_sticks; i++) {
auto line = newLine(grid);
new StaticText(line, rect_t{}, analogGetCanonicalName(ADC_INPUT_MAIN, i),
new StaticText(line, rect_t{}, analogGetCanonicalName(ADC_INPUT_MAIN, i),
COLOR_THEME_PRIMARY1);
new HWInputEdit(line, (char*)analogGetCustomLabel(ADC_INPUT_MAIN, i),
LEN_ANA_NAME);
Expand All @@ -76,11 +78,33 @@ HWSticks::HWSticks(Window* parent) : Window(parent, rect_t{})
#endif
}

HWPots::HWPots(Window* parent) : Window(parent, rect_t{})
{
FlexGridLayout grid(pots_col_dsc, row_dsc, PAD_TINY);
setFlexLayout();
// Absolute layout for Pots popup - due to performance issues with lv_textarea
// in a flex layout
#if LCD_W > LCD_H
#define P_LBL_X 0
#define P_LBL_W ((coord_t)((DIALOG_DEFAULT_WIDTH - 30) * 2 / 11))
#define P_NM_X (P_LBL_X + P_LBL_W + 6)
#define P_TYP_X (P_NM_X + 70)
#define P_TYP_W 160
#define P_INV_X (P_TYP_X + P_TYP_W + 6)
#define P_INV_W 52
#define P_Y(i) (i * 36 + 2)
#define P_OFST_Y 0
#else
#define P_LBL_X 0
#define P_LBL_W ((coord_t)((DIALOG_DEFAULT_WIDTH - 18) * 13 / 21))
#define P_NM_X (P_LBL_X + P_LBL_W + 6)
#define P_TYP_X 0
#define P_TYP_W P_LBL_W
#define P_INV_X (P_TYP_X + P_TYP_W + 6)
#define P_INV_W 52
#define P_Y(i) (i * 72 + 2)
#define P_OFST_Y 36
#endif

HWPots::HWPots(Window* parent) :
Window(parent, rect_t{0, 0, DIALOG_DEFAULT_WIDTH - 12, LV_SIZE_CONTENT})
{
potsChanged = false;

setCloseHandler([=]() {
Expand All @@ -99,20 +123,15 @@ HWPots::HWPots(Window* parent) : Window(parent, rect_t{})
// #if !defined(SIMU) && defined(RADIO_FAMILY_T16)
// if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
// #endif
auto line = newLine(grid);
new StaticText(line, rect_t{}, adcGetInputLabel(ADC_INPUT_FLEX, i),
COLOR_THEME_PRIMARY1);

new HWInputEdit(line, (char*)analogGetCustomLabel(ADC_INPUT_FLEX, i),
LEN_ANA_NAME);
new StaticText(this, rect_t{P_LBL_X, P_Y(i) + 6, P_LBL_W, 32},
adcGetInputLabel(ADC_INPUT_FLEX, i), COLOR_THEME_PRIMARY1);

#if LCD_H > LCD_W
line = newLine(grid);
#endif
new HWInputEdit(this, (char*)analogGetCustomLabel(ADC_INPUT_FLEX, i),
LEN_ANA_NAME, P_NM_X, P_Y(i));

auto pot = new Choice(
line, rect_t{}, STR_POTTYPES, FLEX_NONE, FLEX_SWITCH,
[=]() -> int { return getPotType(i); },
this, rect_t{P_TYP_X, P_Y(i) + P_OFST_Y, P_TYP_W, 32}, STR_POTTYPES,
FLEX_NONE, FLEX_SWITCH, [=]() -> int { return getPotType(i); },
[=](int newValue) {
setPotType(i, newValue);
switchFixFlexConfig();
Expand All @@ -122,19 +141,29 @@ HWPots::HWPots(Window* parent) : Window(parent, rect_t{})
pot->setAvailableHandler([=](int val) { return isPotTypeAvailable(val); });

new ToggleSwitch(
line, rect_t{}, [=]() -> uint8_t { return (uint8_t)getPotInversion(i); },
this, rect_t{P_INV_X, P_Y(i) + P_OFST_Y, P_INV_W, 32},
[=]() -> uint8_t { return (uint8_t)getPotInversion(i); },
[=](int8_t newValue) {
setPotInversion(i, newValue);
SET_DIRTY();
});
}
}

// Absolute layout for Switches popup - due to performance issues with
// lv_textarea in a flex layout
#if LCD_W > LCD_H
#define SW_CTRL_W 86
#else
#define SW_CTRL_W 75
#endif

class SwitchDynamicLabel : public StaticText
{
public:
SwitchDynamicLabel(Window* parent, uint8_t index) :
StaticText(parent, rect_t{}, "", COLOR_THEME_PRIMARY1), index(index)
SwitchDynamicLabel(Window* parent, uint8_t index, coord_t x, coord_t y) :
StaticText(parent, rect_t{x, y, SW_CTRL_W, 32}, "", COLOR_THEME_PRIMARY1),
index(index)
{
checkEvents();
}
Expand Down Expand Up @@ -186,38 +215,36 @@ static void flex_channel_changed(lv_event_t* e)
}
}

HWSwitches::HWSwitches(Window* parent) : Window(parent, rect_t{})
HWSwitches::HWSwitches(Window* parent) :
Window(parent, rect_t{0, 0, DIALOG_DEFAULT_WIDTH - 12, LV_SIZE_CONTENT})
{
FlexGridLayout grid(col_three_dsc, row_dsc, PAD_TINY);
setFlexLayout();

auto max_switches = switchGetMaxSwitches();
for (int i = 0; i < max_switches; i++) {
auto line = newLine(grid);
new SwitchDynamicLabel(line, i);
new HWInputEdit(line, (char*)switchGetCustomName(i), LEN_SWITCH_NAME);

auto box = new Window(line, rect_t{});
box->padAll(PAD_TINY);
box->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_SMALL, LV_SIZE_CONTENT);
new SwitchDynamicLabel(this, i, 2, i * 36 + 2);
new HWInputEdit(this, (char*)switchGetCustomName(i), LEN_SWITCH_NAME,
SW_CTRL_W + 8, i * 36 + 2);

coord_t x = SW_CTRL_W * 2 + 14;
Choice* channel = nullptr;
if (switchIsFlex(i)) {
channel = new Choice(
box, rect_t{}, -1, adcGetMaxInputs(ADC_INPUT_FLEX) - 1,
this, rect_t{x, i * 36 + 2, SW_CTRL_W, 32}, -1,
adcGetMaxInputs(ADC_INPUT_FLEX) - 1,
[=]() -> int { return switchGetFlexConfig(i); },
[=](int newValue) { switchConfigFlex(i, newValue); });
channel->setAvailableHandler(
[=](int val) { return val < 0 || switchIsFlexInputAvailable(i, val); });
channel->setAvailableHandler([=](int val) {
return val < 0 || switchIsFlexInputAvailable(i, val);
});
channel->setTextHandler([=](int val) -> std::string {
if (val < 0) return STR_NONE;
return adcGetInputLabel(ADC_INPUT_FLEX, val);
});
x += SW_CTRL_W + 6;
}

auto sw_cfg = new Choice(
box, rect_t{}, STR_SWTYPES, SWITCH_NONE, switchGetMaxType(i),
[=]() -> int { return SWITCH_CONFIG(i); },
this, rect_t{x, i * 36 + 2, SW_CTRL_W, 32}, STR_SWTYPES, SWITCH_NONE,
switchGetMaxType(i), [=]() -> int { return SWITCH_CONFIG(i); },
[=](int newValue) {
swconfig_t mask = (swconfig_t)SWITCH_CONFIG_MASK(i);
g_eeGeneral.switchConfig =
Expand All @@ -228,7 +255,8 @@ HWSwitches::HWSwitches(Window* parent) : Window(parent, rect_t{})

if (channel) {
lv_obj_t* obj = channel->getLvObj();
lv_obj_add_event_cb(obj, flex_channel_changed, LV_EVENT_VALUE_CHANGED, sw_cfg);
lv_obj_add_event_cb(obj, flex_channel_changed, LV_EVENT_VALUE_CHANGED,
sw_cfg);
lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
}
}
Expand Down
Loading

0 comments on commit 783da75

Please sign in to comment.