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:
+7
-4
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user