From 3dedcad75a5f718d7382cca534d571537256d07d Mon Sep 17 00:00:00 2001 From: Cliff Date: Sat, 18 Sep 2021 04:21:57 -0700 Subject: [PATCH] Category editor (#725) * Allow model moving between categories * Initial Commit - Categories Editor * Don't allow move of active models & save * Create group for categories, add, remove, delete working. One glitch on add still... * allow index choice on tabs page build * Don't allow setting name null * Change layout * Null terminate string + save * Optionally hide delete button * Allow add a new model on touch if there are none * Remove seperator * Fix compiler warning * Assign not compare * Add Translation Strings for Model Categories and Models * Use translated strings * Update libopenui * Add extra newline so scrolls proper * Update libopenui --- radio/src/gui/colorlcd/model_select.cpp | 171 ++++++++++++++++++++++-- radio/src/gui/colorlcd/model_select.h | 1 + radio/src/thirdparty/libopenui | 2 +- radio/src/translations.cpp | 2 + radio/src/translations.h | 2 + radio/src/translations/cn.h.txt | 2 + radio/src/translations/cz.h.txt | 2 + radio/src/translations/de.h.txt | 2 + radio/src/translations/en.h.txt | 2 + radio/src/translations/es.h.txt | 2 + radio/src/translations/fi.h.txt | 2 + radio/src/translations/fr.h.txt | 2 + radio/src/translations/it.h.txt | 2 + radio/src/translations/nl.h.txt | 2 + radio/src/translations/pl.h.txt | 2 + radio/src/translations/pt.h.txt | 2 + radio/src/translations/se.h.txt | 2 + radio/src/translations/tw.h.txt | 2 + 18 files changed, 194 insertions(+), 10 deletions(-) diff --git a/radio/src/gui/colorlcd/model_select.cpp b/radio/src/gui/colorlcd/model_select.cpp index 076775649..3e1c63eba 100644 --- a/radio/src/gui/colorlcd/model_select.cpp +++ b/radio/src/gui/colorlcd/model_select.cpp @@ -264,8 +264,23 @@ class ModelCategoryPageBody : public FormWindow POPUP_WARNING("Invalid File"); } }); - // menu->addLine(STR_MOVE_MODEL); if (model != modelslist.getCurrentModel()) { + // Move + if(modelslist.getCategories().size() > 1) { + menu->addLine(STR_MOVE_MODEL, [=]() { + auto moveToMenu = new Menu(parent); + moveToMenu->setTitle(STR_MOVE_MODEL); + for (auto newcategory: modelslist.getCategories()) { + if(category != newcategory) { + moveToMenu->addLine(std::string(newcategory->name, sizeof(newcategory->name)), [=]() { + modelslist.moveModel(model, category, newcategory); + update(index < (int)category->size() - 1 ? index : index - 1); + modelslist.save(); + }); + } + } + }); + } menu->addLine(STR_DELETE_MODEL, [=]() { new ConfirmDialog( parent, STR_DELETE_MODEL, @@ -313,19 +328,34 @@ class ModelCategoryPageBody : public FormWindow } } + void addFirstModel() { + Menu *menu = new Menu(this); + menu->addLine(STR_CREATE_MODEL, getCreateModelAction()); + } + #if defined(HARDWARE_KEYS) void onEvent(event_t event) override { if (event == EVT_KEY_BREAK(KEY_ENTER)) { - Menu *menu = new Menu(this); - menu->addLine(STR_CREATE_MODEL, getCreateModelAction()); - // TODO: create category? + addFirstModel(); } else { FormWindow::onEvent(event); } } #endif +#if defined(HARDWARE_TOUCH) + bool onTouchEnd(coord_t x, coord_t y) + { + if(category->size() == 0) + addFirstModel(); + else + FormWindow::onTouchEnd(x,y); + return true; + } +#endif + + void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window *from = nullptr) override { @@ -370,18 +400,141 @@ class ModelCategoryPage : public PageTab } }; +class CategoryGroup: public FormGroup +{ + public: + CategoryGroup(Window * parent, const rect_t & rect, ModelsCategory *category) : + FormGroup(parent, rect), + category(category) + { + } + + void paint(BitmapBuffer * dc) override + { + dc->drawSolidFilledRect(0, 0, width(), height(), COLOR_THEME_PRIMARY2); + FormGroup::paint(dc); + } + + protected: + ModelsCategory *category; +}; + +class CategoryEditPage : public PageTab +{ + public: + explicit CategoryEditPage(ModelSelectMenu *modelselectmenu, bool scrolltobot=false) : + + PageTab(STR_MODEL_CATEGORIES, ICON_MODEL_SETUP), + modelselectmenu(modelselectmenu), + scrolltobot(scrolltobot) + { + } + + protected: + void update() + { + modelselectmenu->build(0); + } + + void build(FormWindow *window) override + { + FormGridLayout grid; + grid.setMarginRight(15); + grid.setLabelWidth(0); + grid.spacer(); + + coord_t y = 2; + + for (auto category: modelslist.getCategories()) { + // NAME + auto catname = new TextEdit(window, grid.getFieldSlot(3,0), category->name, sizeof(category->name)); + catname->setChangeHandler([=]() { + if(category->name[0] == '\0') { + category->name[0] = ' '; category->name[1] = '\0'; + } + modelslist.save(); + update(); + }); + + // Details + char cnt[19]; + snprintf(cnt, sizeof(cnt), "%d %s", category->size(), STR_MODELS); + new StaticText(window, grid.getFieldSlot(3,1), cnt); + + if(category->empty()) { + new TextButton(window, grid.getFieldSlot(3,2),TR_DELETE, [=]() -> uint8_t { + new ConfirmDialog(window, STR_DELETE_CATEGORY, + std::string(category->name, sizeof(category->name)).c_str(), + [=] { + modelslist.removeCategory(category); + modelslist.save(); + update(); + }); + return 0; + }); + } else { +#ifdef CATEGORIES_SHOW_DELETE_NON_EMPTY + new TextButton(window, grid.getFieldSlot(3,2),STR_DELETE, [=]() -> uint8_t { + new MessageDialog(window, STR_DELETE_CATEGORY, TR_CAT_NOT_EMPTY); + return 0; + }); +#endif + } + + grid.nextLine(); + + grid.spacer(); + coord_t height = grid.getWindowHeight(); + //window->setHeight(height); + y += height + 2; + } + + new TextButton(window, grid.getCenteredSlot(LCD_W/2), STR_CREATE_CATEGORY, [=]() -> uint8_t { + modelslist.createCategory("New"); + update(); + return 0; + }); + + grid.nextLine(); + + window->setInnerHeight(grid.getWindowHeight()); + + if(scrolltobot) + window->setScrollPositionY(y+40); + } + private: + ModelSelectMenu *modelselectmenu; + bool scrolltobot; +}; + ModelSelectMenu::ModelSelectMenu(): TabsGroup(ICON_MODEL_SELECT) -{ +{ + build(); +} + +void ModelSelectMenu::build(int index) +{ + modelslist.clear(); modelslist.load(); - TRACE("TabsGroup: %p", this); + removeAllTabs(); + + TRACE("TabsGroup: %p", this); + + addTab(new CategoryEditPage(this)); + for (auto category: modelslist.getCategories()) { addTab(new ModelCategoryPage(category)); } - int idx = modelslist.getCurrentCategoryIdx(); - if (idx >= 0) { - setCurrentTab(idx); + if(index < 0) { + int idx = modelslist.getCurrentCategoryIdx(); + if (idx >= 0) { + setCurrentTab(idx+1); + } + } else { + if(index < static_cast(modelslist.getCategories().size())) + setCurrentTab(index); } } diff --git a/radio/src/gui/colorlcd/model_select.h b/radio/src/gui/colorlcd/model_select.h index 05ad387bf..69a6cfc04 100644 --- a/radio/src/gui/colorlcd/model_select.h +++ b/radio/src/gui/colorlcd/model_select.h @@ -26,6 +26,7 @@ class ModelSelectMenu: public TabsGroup { public: ModelSelectMenu(); + void build(int index=-1); }; #endif // _MODEL_SELECT_H_ diff --git a/radio/src/thirdparty/libopenui b/radio/src/thirdparty/libopenui index 1e1940bc5..253bc6a89 160000 --- a/radio/src/thirdparty/libopenui +++ b/radio/src/thirdparty/libopenui @@ -1 +1 @@ -Subproject commit 1e1940bc59c4db9215ac7dd3b5c2ab317e937775 +Subproject commit 253bc6a897a21495cd6e722467ff55535a2d8190 diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index e44692d2a..1e81cd8d9 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -319,6 +319,8 @@ const char STR_BEEP_VOLUME[] = INDENT TR_BEEP_VOLUME; const char STR_WAV_VOLUME[] = INDENT TR_WAV_VOLUME; const char STR_BG_VOLUME[] = INDENT TR_BG_VOLUME; const char STR_SELECT_MODEL[] = TR_SELECT_MODEL; +const char STR_MODEL_CATEGORIES[] = TR_MODEL_CATEGORIES; +const char STR_MODELS[] = TR_MODELS; const char STR_SELECT_MODE[] = TR_SELECT_MODE; const char STR_CREATE_CATEGORY[] = TR_CREATE_CATEGORY; const char STR_RENAME_CATEGORY[] = TR_RENAME_CATEGORY; diff --git a/radio/src/translations.h b/radio/src/translations.h index a036513aa..00b752045 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -512,6 +512,8 @@ extern const char STR_BEEP_VOLUME[]; extern const char STR_WAV_VOLUME[]; extern const char STR_BG_VOLUME[]; extern const char STR_SELECT_MODEL[]; +extern const char STR_MODEL_CATEGORIES[]; +extern const char STR_MODELS[]; extern const char STR_SELECT_MODE[]; extern const char STR_CREATE_CATEGORY[]; extern const char STR_RENAME_CATEGORY[]; diff --git a/radio/src/translations/cn.h.txt b/radio/src/translations/cn.h.txt index 1e0b03293..58a4a76e1 100644 --- a/radio/src/translations/cn.h.txt +++ b/radio/src/translations/cn.h.txt @@ -632,6 +632,8 @@ #define TR_VOLTAGE TR(INDENT "Voltage", INDENT "电压来源") #define TR_CURRENT TR(INDENT "Current", INDENT "电流来源") #define TR_SELECT_MODEL "选择模型" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "选择模式" #define TR_CREATE_CATEGORY "创建分类" #define TR_RENAME_CATEGORY "分类改名" diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 58248fecb..3ffc0bc58 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -719,6 +719,8 @@ #define TR_VOLTAGE INDENT"Napětí" #define TR_CURRENT INDENT"Proud" #define TR_SELECT_MODEL "Vyber model" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Nová kategorie" #define TR_RENAME_CATEGORY "Přejmenovat kategorii" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index e2db8c03c..66ce123fa 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -724,6 +724,8 @@ #define TR_VOLTAGE TR(INDENT "Spg", INDENT "Spannungsquelle") //9XR-Pro #define TR_CURRENT TR(INDENT "Strom", INDENT "Stromquelle") #define TR_SELECT_MODEL "Modell auswählen" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Modelltyp erstellen" #define TR_RENAME_CATEGORY "Modelltyp umbenennen" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index cd6f2e519..657b5462b 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -728,6 +728,8 @@ #define TR_VOLTAGE TR(INDENT "Voltage", INDENT "Voltage source") #define TR_CURRENT TR(INDENT "Current", INDENT "Current source") #define TR_SELECT_MODEL "Select model" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Create category" #define TR_RENAME_CATEGORY "Rename category" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 666e960a6..47dfa8042 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -726,6 +726,8 @@ #define TR_VOLTAGE INDENT"Voltaje" #define TR_CURRENT INDENT"Actual" #define TR_SELECT_MODEL TR("Selec. modelo", "Seleccionar modelo") +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Crear categoría" #define TR_RENAME_CATEGORY "Renombrar categoría" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index ce657eeab..dd2773709 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -740,6 +740,8 @@ #define TR_VOLTAGE INDENT"Voltage" #define TR_CURRENT INDENT"Current" #define TR_SELECT_MODEL "Select Model" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Create Category" #define TR_RENAME_CATEGORY "Rename Category" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index d1005b541..b040a1b6a 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -745,6 +745,8 @@ #define TR_VOLTAGE TR(INDENT "Tension",INDENT "Source tension") #define TR_CURRENT TR(INDENT "Courant",INDENT "Source courant") #define TR_SELECT_MODEL "Sélect. modèle" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Créer une catégorie" #define TR_RENAME_CATEGORY "Renommer la catégorie" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index efaa97448..7fbb562df 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -746,6 +746,8 @@ #define TR_VOLTAGE TR(INDENT "Voltagg.",INDENT "Voltaggio") #define TR_CURRENT TR(INDENT "Corrente",INDENT "Corrente") #define TR_SELECT_MODEL TR("Scegli mod.", "Scegli Modello") +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Crea Categoria" #define TR_RENAME_CATEGORY "Rinomina Categoria" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 93b210d68..080e16caf 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -729,6 +729,8 @@ #define TR_VOLTAGE TR(INDENT "Spg", INDENT "Spanningsbron") //9XR-Pro #define TR_CURRENT TR(INDENT "Stroom", INDENT "Stroombron") #define TR_SELECT_MODEL "Kies Model" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Create Category" #define TR_RENAME_CATEGORY "Rename Category" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 0e8c9cb18..414367a9b 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -743,6 +743,8 @@ #define TR_VOLTAGE TR (INDENT"Napięcie",INDENT"Źródło Napięcia") #define TR_CURRENT TR (INDENT"Prąd",INDENT"Źródło Prądu") #define TR_SELECT_MODEL "Wybór modelu" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Create Category" #define TR_RENAME_CATEGORY "Rename Category" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 672bfb9e3..2d1637cef 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -744,6 +744,8 @@ #define TR_VOLTAGE INDENT"Volts" #define TR_CURRENT INDENT"Amperes" #define TR_SELECT_MODEL "Selec. Modelo" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Create Category" #define TR_RENAME_CATEGORY "Rename Category" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 585b82000..4a33a79a6 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -745,6 +745,8 @@ #define TR_VOLTAGE INDENT"Volt" #define TR_CURRENT INDENT"Ampere" #define TR_SELECT_MODEL "Välj Modell" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "Select mode" #define TR_CREATE_CATEGORY "Skapa Kategori" #define TR_RENAME_CATEGORY "Byt Kat.namn" diff --git a/radio/src/translations/tw.h.txt b/radio/src/translations/tw.h.txt index 86fdd0bfa..2ded09e8f 100644 --- a/radio/src/translations/tw.h.txt +++ b/radio/src/translations/tw.h.txt @@ -632,6 +632,8 @@ #define TR_VOLTAGE TR(INDENT "Voltage", INDENT "電壓來源") #define TR_CURRENT TR(INDENT "Current", INDENT "電流來源") #define TR_SELECT_MODEL "選擇模型" +#define TR_MODEL_CATEGORIES "Model Categories" +#define TR_MODELS "Models" #define TR_SELECT_MODE "選擇模式" #define TR_CREATE_CATEGORY "創建分類" #define TR_RENAME_CATEGORY "分類改名"