fix(color): issues with menus (possible EM, double loading of content) (#5208)

This commit is contained in:
philmoz
2024-06-22 12:05:39 +10:00
committed by GitHub
parent 139a09685e
commit 5c422581ca
5 changed files with 38 additions and 25 deletions
+2 -1
View File
@@ -69,7 +69,8 @@ class LayoutChoice : public Button
std::distance(LayoutFactory::getRegisteredLayouts().begin(), it)); std::distance(LayoutFactory::getRegisteredLayouts().begin(), it));
menu->setCloseHandler([=]() { menu->setCloseHandler([=]() {
update(); if (!menu->deleted())
update();
}); });
} }
+1 -1
View File
@@ -214,7 +214,7 @@ void SourceChoice::openMenu()
}); });
#endif #endif
fillMenu(menu); // fillMenu(menu); - called by MenuToolbar
menu->setCloseHandler([=]() { setEditMode(false); }); menu->setCloseHandler([=]() { setEditMode(false); });
} }
+1 -1
View File
@@ -161,7 +161,7 @@ void SwitchChoice::openMenu()
}); });
#endif #endif
fillMenu(menu); // fillMenu(menu); - called by MenuToolbar
menu->setCloseHandler([=]() { setEditMode(false); }); menu->setCloseHandler([=]() { setEditMode(false); });
} }
+1 -1
View File
@@ -188,7 +188,7 @@ void FileChoice::openMenu()
auto tb = new FileChoiceMenuToolbar(this, menu); auto tb = new FileChoiceMenuToolbar(this, menu);
menu->setToolbar(tb); menu->setToolbar(tb);
fillMenu(menu); // fillMenu(menu); - called by MenuToolbar
menu->setCloseHandler([=]() { setEditMode(false); }); menu->setCloseHandler([=]() { setEditMode(false); });
} else { } else {
+33 -21
View File
@@ -25,15 +25,8 @@
#include "table.h" #include "table.h"
#include "themes/etx_lv_theme.h" #include "themes/etx_lv_theme.h"
#include <memory>
constexpr coord_t MENUS_WIDTH = 200; constexpr coord_t MENUS_WIDTH = 200;
struct lvobj_delete {
constexpr lvobj_delete() = default;
void operator()(lv_obj_t* obj) const { lv_obj_del(obj); }
};
static void _force_editing(lv_group_t* g) { lv_group_set_editing(g, true); } static void _force_editing(lv_group_t* g) { lv_group_set_editing(g, true); }
class MenuBody : public TableField class MenuBody : public TableField
@@ -57,16 +50,19 @@ class MenuBody : public TableField
{ {
} }
MenuLine(MenuLine&) = delete; ~MenuLine()
MenuLine(MenuLine&&) = default; {
if (icon)
lv_obj_del(icon);
}
lv_obj_t* getIcon() { return icon.get(); } lv_obj_t* getIcon() const { return icon; }
protected: protected:
std::string text; std::string text;
std::function<void()> onPress; std::function<void()> onPress;
std::function<bool()> isChecked; std::function<bool()> isChecked;
std::unique_ptr<lv_obj_t, lvobj_delete> icon; lv_obj_t* icon;
}; };
public: public:
@@ -93,6 +89,11 @@ class MenuBody : public TableField
} }
} }
~MenuBody()
{
clearLines();
}
#if defined(DEBUG_WINDOWS) #if defined(DEBUG_WINDOWS)
std::string getName() const override { return "MenuBody"; } std::string getName() const override { return "MenuBody"; }
#endif #endif
@@ -166,7 +167,8 @@ class MenuBody : public TableField
lv_canvas_set_buffer(canvas, buf, w, h, LV_IMG_CF_ALPHA_8BIT); lv_canvas_set_buffer(canvas, buf, w, h, LV_IMG_CF_ALPHA_8BIT);
} }
lines.emplace_back(text, std::move(onPress), std::move(isChecked), canvas); auto l = new MenuLine(text, onPress, isChecked, canvas);
lines.push_back(l);
if (update) { if (update) {
auto idx = lines.size() - 1; auto idx = lines.size() - 1;
@@ -178,13 +180,23 @@ class MenuBody : public TableField
{ {
setRowCount(lines.size()); setRowCount(lines.size());
for (unsigned int idx = 0; idx < lines.size(); idx++) { for (unsigned int idx = 0; idx < lines.size(); idx++) {
lv_table_set_cell_value(lvobj, idx, 0, lines[idx].text.c_str()); lv_table_set_cell_value(lvobj, idx, 0, lines[idx]->text.c_str());
} }
} }
void clearLines()
{
for (auto itr = lines.begin(); itr != lines.end();) {
auto l = *itr;
itr = lines.erase(itr);
delete l;
}
lines.clear();
}
void removeLines() void removeLines()
{ {
lines.clear(); clearLines();
setRowCount(0); setRowCount(0);
selectedIndex = 0; selectedIndex = 0;
@@ -199,16 +211,16 @@ class MenuBody : public TableField
if (row < lines.size()) { if (row < lines.size()) {
if (menu->multiple) { if (menu->multiple) {
if (selectedIndex == (int)row) if (selectedIndex == (int)row)
lines[row].onPress(); lines[row]->onPress();
else { else {
setIndex(row); setIndex(row);
lines[row].onPress(); lines[row]->onPress();
} }
} else { } else {
// delete menu first to avoid // delete menu first to avoid
// focus issues with onPress() // focus issues with onPress()
menu->deleteLater(); menu->deleteLater();
lines[row].onPress(); lines[row]->onPress();
} }
} }
} }
@@ -219,7 +231,7 @@ class MenuBody : public TableField
void onDrawBegin(uint16_t row, uint16_t col, void onDrawBegin(uint16_t row, uint16_t col,
lv_obj_draw_part_dsc_t* dsc) override lv_obj_draw_part_dsc_t* dsc) override
{ {
lv_canvas_t* icon = (lv_canvas_t*)lines[row].getIcon(); lv_canvas_t* icon = (lv_canvas_t*)lines[row]->getIcon();
if (!icon) return; if (!icon) return;
lv_img_t* img = &icon->img; lv_img_t* img = &icon->img;
@@ -232,7 +244,7 @@ class MenuBody : public TableField
{ {
if (row >= lines.size()) return; if (row >= lines.size()) return;
lv_obj_t* icon = lines[row].getIcon(); lv_obj_t* icon = lines[row]->getIcon();
if (icon) { if (icon) {
lv_draw_img_dsc_t img_dsc; lv_draw_img_dsc_t img_dsc;
lv_draw_img_dsc_init(&img_dsc); lv_draw_img_dsc_init(&img_dsc);
@@ -251,7 +263,7 @@ class MenuBody : public TableField
lv_draw_img(dsc->draw_ctx, &img_dsc, &coords, img); lv_draw_img(dsc->draw_ctx, &img_dsc, &coords, img);
} }
if (lines[row].isChecked != nullptr && lines[row].isChecked()) { if (lines[row]->isChecked != nullptr && lines[row]->isChecked()) {
lv_area_t coords; lv_area_t coords;
lv_coord_t area_h = lv_area_get_height(dsc->draw_area); lv_coord_t area_h = lv_area_get_height(dsc->draw_area);
lv_coord_t cell_right = lv_obj_get_style_pad_right(lvobj, LV_PART_ITEMS); lv_coord_t cell_right = lv_obj_get_style_pad_right(lvobj, LV_PART_ITEMS);
@@ -270,7 +282,7 @@ class MenuBody : public TableField
protected: protected:
bool isLongPressed = false; bool isLongPressed = false;
std::vector<MenuLine> lines; std::vector<MenuLine*> lines;
int selectedIndex = 0; int selectedIndex = 0;
Menu* getParentMenu() { return static_cast<Menu*>(getParent()->getParent()); } Menu* getParentMenu() { return static_cast<Menu*>(getParent()->getParent()); }