Speed up the initial menu filling (#77)

* Preset menu line counter. Disable update position during the fill.

* Code formating

* Redesign attempt with addLines() functions.

* .

* Menu::addLines fix for icons.

* Redesign to clean up

* Selection fix. Choice implementation.

* One more redesign.
This commit is contained in:
Gábor Bányász
2022-10-12 13:05:18 +10:00
committed by GitHub
parent df7d9a0fe0
commit 8a4a1b1b38
4 changed files with 66 additions and 17 deletions
+7 -4
View File
@@ -210,19 +210,22 @@ void Choice::fillMenu(Menu *menu, const FilterFct& filter)
auto value = _getValue();
int count = 0;
int selectedIx = -1;
for (int i = vmin; i <= vmax; ++i) {
if (filter && !filter(i)) continue;
if (isValueAvailable && !isValueAvailable(i)) continue;
if (textHandler) {
menu->addLine(textHandler(i), [=]() { setValue(i); });
menu->addLineBuffered(textHandler(i), [=]() { setValue(i); });
} else if (unsigned(i - vmin) < values.size()) {
menu->addLine(values[i - vmin], [=]() { setValue(i); });
menu->addLineBuffered(values[i - vmin], [=]() { setValue(i); });
} else {
menu->addLine(std::to_string(i), [=]() { setValue(i); });
menu->addLineBuffered(std::to_string(i), [=]() { setValue(i); });
}
if (value == i) { menu->select(count); }
if (value == i) { selectedIx = count; }
++count;
}
menu->updateLines();
if (selectedIx >= 0) { menu->select(selectedIx); }
}
void Choice::openMenu()
+2 -1
View File
@@ -101,7 +101,7 @@ bool FileChoice::openMenu()
int current = -1;
std::string value = getValue();
for (const auto &file : files) {
menu->addLine(file, [=]() {
menu->addLineBuffered(file, [=]() {
setValue(file);
lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr);
});
@@ -113,6 +113,7 @@ bool FileChoice::openMenu()
}
++count;
}
menu->updateLines();
if (current >= 0) {
menu->select(current);
+40 -8
View File
@@ -98,28 +98,41 @@ MenuBody::MenuBody(Window * parent, const rect_t & rect):
}
void MenuBody::addLine(const std::string &text, std::function<void()> onPress,
std::function<bool()> isChecked)
std::function<bool()> isChecked, bool update)
{
lines.emplace_back(std::move(onPress), std::move(isChecked), nullptr);
lines.emplace_back(text, std::move(onPress), std::move(isChecked), nullptr);
auto idx = lines.size() - 1;
lv_table_set_cell_value(lvobj, idx, 0, text.c_str());
if (update) {
auto idx = lines.size() - 1;
lv_table_set_cell_value(lvobj, idx, 0, text.c_str());
}
}
void MenuBody::addLine(const uint8_t *icon_mask, const std::string &text,
std::function<void()> onPress,
std::function<bool()> isChecked)
std::function<bool()> isChecked,
bool update)
{
lv_obj_t* canvas = lv_canvas_create(nullptr);
lines.emplace_back(std::move(onPress), std::move(isChecked), canvas);
lines.emplace_back(text, std::move(onPress), std::move(isChecked), canvas);
lv_coord_t w = *((uint16_t *)icon_mask);
lv_coord_t h = *(((uint16_t *)icon_mask)+1);
void* buf = (void*)(icon_mask + 4);
lv_canvas_set_buffer(canvas, buf, w, h, LV_IMG_CF_ALPHA_8BIT);
auto idx = lines.size() - 1;
lv_table_set_cell_value_fmt(lvobj, idx, 0, text.c_str());
if (update) {
auto idx = lines.size() - 1;
lv_table_set_cell_value_fmt(lvobj, idx, 0, text.c_str());
}
}
void MenuBody::updateLines()
{
setRowCount(lines.size());
for(unsigned int idx = 0; idx < lines.size(); idx++) {
lv_table_set_cell_value_fmt(lvobj, idx, 0, lines[idx].text.c_str());
}
}
void MenuBody::removeLines()
@@ -327,6 +340,25 @@ void Menu::addLine(const uint8_t *icon_mask, const std::string &text,
updatePosition();
}
void Menu::addLineBuffered(const std::string &text, std::function<void()> onPress,
std::function<bool()> isChecked)
{
content->body.addLine(text, std::move(onPress), std::move(isChecked), false);
}
void Menu::addLineBuffered(const uint8_t *icon_mask, const std::string &text,
std::function<void()> onPress,
std::function<bool()> isChecked)
{
content->body.addLine(icon_mask, text, std::move(onPress), std::move(isChecked), false);
}
void Menu::updateLines()
{
content->body.updateLines();
updatePosition();
}
void Menu::removeLines()
{
content->body.removeLines();
+17 -4
View File
@@ -53,9 +53,9 @@ class MenuBody: public TableField
friend class MenuBody;
public:
MenuLine(std::function<void()> onPress, std::function<bool()> isChecked,
MenuLine(const std::string& text, std::function<void()> onPress, std::function<bool()> isChecked,
lv_obj_t *icon) :
onPress(std::move(onPress)), isChecked(std::move(isChecked)), icon(icon)
text(text), onPress(std::move(onPress)), isChecked(std::move(isChecked)), icon(icon)
{
}
@@ -65,6 +65,7 @@ class MenuBody: public TableField
lv_obj_t* getIcon() { return icon.get(); }
protected:
std::string text;
std::function<void()> onPress;
std::function<bool()> isChecked;
std::unique_ptr<lv_obj_t, lvobj_delete> icon;
@@ -96,11 +97,14 @@ class MenuBody: public TableField
void onCancel() override;
void addLine(const std::string &text, std::function<void()> onPress,
std::function<bool()> isChecked);
std::function<bool()> isChecked, bool update = true);
void addLine(const uint8_t *icon_mask, const std::string &text,
std::function<void()> onPress,
std::function<bool()> isChecked);
std::function<bool()> isChecked,
bool update = true);
void updateLines();
void removeLines();
@@ -185,6 +189,15 @@ class Menu: public ModalWindow
std::function<void()> onPress,
std::function<bool()> isChecked = nullptr);
void addLineBuffered(const std::string &text, std::function<void()> onPress,
std::function<bool()> isChecked = nullptr);
void addLineBuffered(const uint8_t *icon_mask, const std::string &text,
std::function<void()> onPress,
std::function<bool()> isChecked = nullptr);
void updateLines();
void addSeparator();
void removeLines();