From b0ed4d44a5d10874a57ad033d4ec88f7777b44e5 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 08:52:55 +0200 Subject: [PATCH 01/17] fixed confirm dialog --- radio/src/gui/colorlcd/confirm_dialog.cpp | 49 ++++++++++++++++------- radio/src/gui/colorlcd/confirm_dialog.h | 4 -- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/radio/src/gui/colorlcd/confirm_dialog.cpp b/radio/src/gui/colorlcd/confirm_dialog.cpp index cce81e2df..a6d7d83a9 100644 --- a/radio/src/gui/colorlcd/confirm_dialog.cpp +++ b/radio/src/gui/colorlcd/confirm_dialog.cpp @@ -20,25 +20,46 @@ #include "confirm_dialog.h" #include "static.h" +#include "gridlayout.h" ConfirmDialog::ConfirmDialog(Window * parent, const char * title, const char * message, std::function confirmHandler) : Dialog(parent, title, {50, 73, LCD_W - 100, LCD_H - 146}), confirmHandler(std::move(confirmHandler)) { - new StaticText(this, {0, height() / 2, width(), PAGE_LINE_HEIGHT}, message, CENTERED); + auto form = &content->form; + FormGridLayout grid(content->form.width()); + form->clear(); + + new StaticText(form, grid.getCenteredSlot(), message); + grid.nextLine(); + + auto noButton = new TextButton(form, grid.getSlot(2, 0), "NO", + [=]() -> int8_t { + this->deleteLater(); + return 0; + }); + + new TextButton(form, grid.getSlot(2, 1), "YES", + [=]() -> int8_t { + this->deleteLater(); + this->confirmHandler(); + return 0; + }); + + noButton->setFocus(SET_FOCUS_DEFAULT); } -#if defined(HARDWARE_KEYS) -void ConfirmDialog::onEvent(event_t event) -{ - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); +// #if defined(HARDWARE_KEYS) +// void ConfirmDialog::onEvent(event_t event) +// { +// TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); - if (event == EVT_KEY_BREAK(KEY_ENTER)) { - deleteLater(); // this restore the focus (it can be changed then in confirmHandler) - confirmHandler(); - } - else if (event == EVT_KEY_BREAK(KEY_EXIT)) { - deleteLater(); - } -} -#endif +// if (event == EVT_KEY_BREAK(KEY_ENTER)) { +// deleteLater(); // this restore the focus (it can be changed then in confirmHandler) +// confirmHandler(); +// } +// else if (event == EVT_KEY_BREAK(KEY_EXIT)) { +// deleteLater(); +// } +// } +// #endif diff --git a/radio/src/gui/colorlcd/confirm_dialog.h b/radio/src/gui/colorlcd/confirm_dialog.h index ea1a4401b..9a0a994f5 100644 --- a/radio/src/gui/colorlcd/confirm_dialog.h +++ b/radio/src/gui/colorlcd/confirm_dialog.h @@ -27,10 +27,6 @@ class ConfirmDialog: public Dialog { public: ConfirmDialog(Window * parent, const char * title, const char * message, std::function confirmHandler); -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif - protected: std::function confirmHandler; }; From c5b8ec7707acd3ff3152c12a75a00d87e7721fdb Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 08:53:16 +0200 Subject: [PATCH 02/17] fixed warning --- radio/src/gui/colorlcd/radio_sdmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/gui/colorlcd/radio_sdmanager.cpp b/radio/src/gui/colorlcd/radio_sdmanager.cpp index 155808bae..fab0fa2dd 100644 --- a/radio/src/gui/colorlcd/radio_sdmanager.cpp +++ b/radio/src/gui/colorlcd/radio_sdmanager.cpp @@ -52,7 +52,7 @@ class FilePreview : public Window } #if defined(DEBUG_WINDOWS) - virtual std::string getName() + std::string getName() const override { return "FilePreview"; } From 3ce9ffd846bc7bd1fb748f967e7cad6311be9422 Mon Sep 17 00:00:00 2001 From: 3djc Date: Sun, 4 Apr 2021 10:19:30 +0200 Subject: [PATCH 03/17] improve --- radio/src/gui/colorlcd/confirm_dialog.cpp | 28 ++++++++++++----------- 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 ++ 16 files changed, 45 insertions(+), 13 deletions(-) diff --git a/radio/src/gui/colorlcd/confirm_dialog.cpp b/radio/src/gui/colorlcd/confirm_dialog.cpp index a6d7d83a9..ac6559a6f 100644 --- a/radio/src/gui/colorlcd/confirm_dialog.cpp +++ b/radio/src/gui/colorlcd/confirm_dialog.cpp @@ -18,33 +18,35 @@ * GNU General Public License for more details. */ +#include "opentx.h" #include "confirm_dialog.h" #include "static.h" #include "gridlayout.h" ConfirmDialog::ConfirmDialog(Window * parent, const char * title, const char * message, std::function confirmHandler) : - Dialog(parent, title, {50, 73, LCD_W - 100, LCD_H - 146}), + Dialog(parent, title, {LCD_W / 10 , LCD_H / 4, LCD_W - 2 * LCD_W / 10, LCD_H - 2 * LCD_H / 4}), confirmHandler(std::move(confirmHandler)) { auto form = &content->form; FormGridLayout grid(content->form.width()); form->clear(); - + new StaticText(form, grid.getCenteredSlot(), message); + grid.setLabelWidth(15); + grid.setMarginRight(15); + grid.nextLine(); grid.nextLine(); - auto noButton = new TextButton(form, grid.getSlot(2, 0), "NO", - [=]() -> int8_t { - this->deleteLater(); - return 0; - }); + auto noButton = new TextButton(form, grid.getFieldSlot(2, 0), STR_NO, [=]() -> int8_t { + this->deleteLater(); + return 0; + }); - new TextButton(form, grid.getSlot(2, 1), "YES", - [=]() -> int8_t { - this->deleteLater(); - this->confirmHandler(); - return 0; - }); + new TextButton(form, grid.getFieldSlot(2, 1), STR_YES, [=]() -> int8_t { + this->deleteLater(); + this->confirmHandler(); + return 0; + }); noButton->setFocus(SET_FOCUS_DEFAULT); } diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index ef23ee02f..00029ebb2 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -110,6 +110,8 @@ ISTR(SUBTRIMMODES); const char STR_POPUPS_ENTER_EXIT[] = TR_POPUPS_ENTER_EXIT; const char STR_OK[] = TR_OK; const char STR_FREE[] = TR_FREE; +const char STR_YES[] = TR_YES; +const char STR_NO[] = TR_NO; const char STR_DELETEMODEL[] = TR_DELETEMODEL; const char STR_COPYINGMODEL[] = TR_COPYINGMODEL; const char STR_MOVINGMODEL[] = TR_MOVINGMODEL; diff --git a/radio/src/translations.h b/radio/src/translations.h index 1575f6b9d..04fd1d9f2 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -207,6 +207,8 @@ extern const char STR_NO_TELEMETRY_SCREENS[]; #endif extern const char STR_FREE[]; +extern const char STR_YES[]; +extern const char STR_NO[]; #define LEN_FREE PSIZE(TR_FREE) extern const char STR_DELETEMODEL[]; extern const char STR_COPYINGMODEL[]; diff --git a/radio/src/translations/cn.h.txt b/radio/src/translations/cn.h.txt index 5af97c900..91e172e5c 100644 --- a/radio/src/translations/cn.h.txt +++ b/radio/src/translations/cn.h.txt @@ -348,6 +348,8 @@ #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define TR_FREE "空闲" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "删除" BREAKSPACE "模型" #define TR_COPYINGMODEL "复制模型..." #define TR_MOVINGMODEL "移动模型..." diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 6ebc683a5..d24ac7949 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -423,6 +423,8 @@ #define TR_MENUWHENDONE CENTER "\011" TR_ENTER " > DALŠÍ" #define TR_FREE TR("volné:", "volných") +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "SMAZAT" BREAKSPACE "MODEL" #define TR_COPYINGMODEL "Kopíruji model.." #define TR_MOVINGMODEL "Přesouvám model." diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 6030854aa..fa39e5ce8 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -428,6 +428,8 @@ #endif #define TR_FREE "frei" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "Modell löschen?" #define TR_COPYINGMODEL "Kopiere Modell" #define TR_MOVINGMODEL "Schiebe Modell" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 5bf6819b3..300c50c4a 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -427,6 +427,8 @@ #endif #define TR_FREE "free" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "DELETE" BREAKSPACE "MODEL" #define TR_COPYINGMODEL "Copying model..." #define TR_MOVINGMODEL "Moving model..." diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 403b91683..0bfbb9506 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -426,6 +426,8 @@ #define TR_MENUWHENDONE CENTER "\007" TR_ENTER " AL ACABAR " #define TR_FREE "libre" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "BORRAR MODELO" #define TR_COPYINGMODEL "Copiando modelo.." #define TR_MOVINGMODEL "Moviendo modelo..." diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index ae0a33191..7459d8909 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -436,6 +436,8 @@ #define TR_MENUWHENDONE CENTER "\006" TR_ENTER " WHEN DONE" #define TR_FREE "free" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "DELETE MODEL" #define TR_COPYINGMODEL "Copying model..." #define TR_MOVINGMODEL "Moving model..." diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 04081b185..189cbef48 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -446,6 +446,8 @@ #define TR_MENUWHENDONE CENTER "\006" TR_ENTER " QUAND PRET" #define TR_FREE "disp" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "SUPPRIMER" BREAKSPACE "MODELE" #define TR_COPYINGMODEL "Copie..." #define TR_MOVINGMODEL "Déplacement..." diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index f7b6df8d5..8d514debe 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -451,6 +451,8 @@ #define TR_MENUWHENDONE CENTER "\007" TR_ENTER " Conferma" #define TR_FREE "Disp." +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "CANCELLA" BREAKSPACE "MODELLO" #define TR_COPYINGMODEL "Copia in corso.." #define TR_MOVINGMODEL "Spostamento..." diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 9f8a384a8..5f76c5b3a 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -427,6 +427,8 @@ #endif #define TR_FREE "vrij" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "WIS" BREAKSPACE "MODEL" #define TR_COPYINGMODEL "Kopieer Model" #define TR_MOVINGMODEL "Verplaats Model" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index fdc8c7d8f..9e38e723e 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -447,6 +447,8 @@ #define TR_MENUWHENDONE CENTER "\006" TR_ENTER " > DALEJ" #define TR_FREE "woln" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "SKASUJ MODEL" #define TR_COPYINGMODEL "Kopiuj model.." #define TR_MOVINGMODEL "Przenieś model." diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index b2194d6d0..389eeea00 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -440,6 +440,8 @@ #define TR_MENUWHENDONE CENTER"\006" TR_ENTER "QDO PRONTO" #define TR_FREE "Livre" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "EXCLUI MODELO" #define TR_COPYINGMODEL "Copiando modelo" #define TR_MOVINGMODEL "Movendo modelo" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 585ec8d12..9637b9f65 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -445,6 +445,8 @@ #define TR_MENUWHENDONE CENTER "\011" TR_ENTER " Avslutar " #define TR_FREE "kvar" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "Radera Modell" #define TR_COPYINGMODEL "Kopierar Modell " #define TR_MOVINGMODEL "Flyttar Modell " diff --git a/radio/src/translations/tw.h.txt b/radio/src/translations/tw.h.txt index ff7f1f3e7..915fd406f 100644 --- a/radio/src/translations/tw.h.txt +++ b/radio/src/translations/tw.h.txt @@ -348,6 +348,8 @@ #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #define TR_FREE "空閒" +#define TR_YES "Yes" +#define TR_NO "No" #define TR_DELETEMODEL "刪除" BREAKSPACE "模型" #define TR_COPYINGMODEL "複製模型..." #define TR_MOVINGMODEL "移動模型..." From 7d17bb5e9deab78e3f847e6b52a7dbe0214df320 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 10:32:55 +0200 Subject: [PATCH 04/17] fix another warning --- radio/src/gui/colorlcd/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/gui/colorlcd/page.h b/radio/src/gui/colorlcd/page.h index 1f66c35bf..212993575 100644 --- a/radio/src/gui/colorlcd/page.h +++ b/radio/src/gui/colorlcd/page.h @@ -31,7 +31,7 @@ class PageHeader: public FormGroup PageHeader(Page * parent, uint8_t icon); #if defined(HARDWARE_TOUCH) - void deleteLater(bool detach = true, bool trash = true) + void deleteLater(bool detach = true, bool trash = true) override { if (_deleted) return; From 618e6796310f94678ce0fcabb064374a442a9089 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 10:38:49 +0200 Subject: [PATCH 05/17] clean-up --- radio/src/gui/colorlcd/confirm_dialog.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/radio/src/gui/colorlcd/confirm_dialog.cpp b/radio/src/gui/colorlcd/confirm_dialog.cpp index ac6559a6f..55b7bcd33 100644 --- a/radio/src/gui/colorlcd/confirm_dialog.cpp +++ b/radio/src/gui/colorlcd/confirm_dialog.cpp @@ -50,18 +50,3 @@ ConfirmDialog::ConfirmDialog(Window * parent, const char * title, const char * m noButton->setFocus(SET_FOCUS_DEFAULT); } - -// #if defined(HARDWARE_KEYS) -// void ConfirmDialog::onEvent(event_t event) -// { -// TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); - -// if (event == EVT_KEY_BREAK(KEY_ENTER)) { -// deleteLater(); // this restore the focus (it can be changed then in confirmHandler) -// confirmHandler(); -// } -// else if (event == EVT_KEY_BREAK(KEY_EXIT)) { -// deleteLater(); -// } -// } -// #endif From 5895abc3c0f7ce6467938a8ae8d48d21eeb29a12 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 12:08:22 +0200 Subject: [PATCH 06/17] half working widgets setup --- radio/src/gui/colorlcd/layout.h | 2 - radio/src/gui/colorlcd/layouts/layout2+1.cpp | 2 - radio/src/gui/colorlcd/screen_setup.cpp | 108 ++++++++++++++++++- radio/src/gui/colorlcd/theme.cpp | 1 + radio/src/gui/colorlcd/widget.cpp | 2 +- radio/src/gui/colorlcd/widget.h | 18 ++-- radio/src/gui/colorlcd/widgets/gauge.cpp | 13 ++- radio/src/gui/colorlcd/widgets/modelbmp.cpp | 4 +- radio/src/gui/colorlcd/widgets/outputs.cpp | 3 +- radio/src/gui/colorlcd/widgets/text.cpp | 2 +- radio/src/gui/colorlcd/widgets/timer.cpp | 3 +- radio/src/gui/colorlcd/widgets/value.cpp | 4 +- radio/src/gui/colorlcd/widgets_container.h | 29 ++--- 13 files changed, 143 insertions(+), 48 deletions(-) diff --git a/radio/src/gui/colorlcd/layout.h b/radio/src/gui/colorlcd/layout.h index 4d409357e..2d93297f2 100644 --- a/radio/src/gui/colorlcd/layout.h +++ b/radio/src/gui/colorlcd/layout.h @@ -130,6 +130,4 @@ void loadDefaultLayout(); // intended for existing models void loadCustomScreens(); -void drawTrimsAndSliders(Layout::PersistentData * persistentData); - std::list & getRegisteredLayouts(); diff --git a/radio/src/gui/colorlcd/layouts/layout2+1.cpp b/radio/src/gui/colorlcd/layouts/layout2+1.cpp index 6e68d8e2e..9320ae624 100644 --- a/radio/src/gui/colorlcd/layouts/layout2+1.cpp +++ b/radio/src/gui/colorlcd/layouts/layout2+1.cpp @@ -73,7 +73,6 @@ class Layout2P1: public Layout Layout::decorate(HAS_TOPBAR(), HAS_SLIDERS(), HAS_TRIMS(), HAS_FM()); } - unsigned int getZonesCount() const override { return DIM(ZONES_LAYOUT_2P1); @@ -92,7 +91,6 @@ class Layout2P1: public Layout if (value != newValue) { value = newValue; // TODO call this from the Layout config window - this->clear(); decorate(); } } diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index d5e60bf57..1423557b5 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -21,6 +21,7 @@ #include #include "screen_setup.h" #include "opentx.h" +#include "view_main.h" #define SET_DIRTY() storageDirty(EE_MODEL) @@ -133,6 +134,108 @@ ScreenSetupPage::ScreenSetupPage(ScreenMenu * menu, uint8_t pageIndex): setTitle(title); } +class SetupWidgetsPageSlot: public Button +{ + public: + SetupWidgetsPageSlot(FormGroup * parent, const rect_t & rect, uint8_t pageIndex, uint8_t slotIndex): + Button(parent, rect), + pageIndex(pageIndex), + slotIndex(slotIndex) + { + setPressHandler([=](){ + Menu * menu = new Menu(this); + menu->addLine("Select a widget", [=]() { + Menu * menu = new Menu(this); + for (auto factory: getRegisteredWidgets()) { + menu->addLine(factory->getName(), [=]() { + if (widget) { + widget->deleteLater(); + } + // widget = factory->create(this, {1, 1, width() - 2, height() - 2}, &g_model.screenData[pageIndex].layoutData.zones[slotIndex].widgetData, true); + customScreens[pageIndex]->createWidget(slotIndex, factory); + return 0; + }); + } + return 0; + }); + if (widget /*g_model.screenData[pageIndex].layoutData.zones[slotIndex].widgetName[0]*/) { + menu->addLine(STR_DELETE, [=]() { + widget->deleteLater(); + widget = nullptr; + return 0; + }); + } + return 0; + }); + } + + void paint(BitmapBuffer * dc) override + { + if (hasFocus()) { + dc->drawSolidRect(0, 0, width(), height(), 1, DEFAULT_COLOR); + } + else { + dc->drawRect(0, 0, width(), height(), 1, DOTTED, DEFAULT_COLOR); + } + } + + protected: + uint8_t pageIndex; + uint8_t slotIndex; + Window * widget = nullptr; +}; + +class SetupWidgetsPage: public FormWindow +{ + public: + SetupWidgetsPage(uint8_t pageIndex): + FormWindow(MainWindow::instance(), {0, 0, LCD_W, LCD_H}, OPAQUE | FORM_FORWARD_FOCUS), + pageIndex(pageIndex) + { + Layer::push(this); + clearFocus(); + + auto & customScreen = customScreens[pageIndex]; + + for (unsigned i = 0; i < customScreen->getZonesCount(); i++) { + auto rect = customScreen->getZone(i); + new SetupWidgetsPageSlot(this, {rect.x - 1, rect.y - 1, rect.w + 2, rect.h + 2}, pageIndex, i); + } + } + + void deleteLater(bool detach = true, bool trash = true) override + { + Layer::pop(this); + +#if defined(HARDWARE_TOUCH) + Keyboard::hide(); +#endif + + Window::deleteLater(detach, trash); + } + +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override + { + TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); + + if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) { + killEvents(event); + deleteLater(); + SET_DIRTY(); + } + } +#endif + + void paint(BitmapBuffer * dc) override + { + dc->clear(DEFAULT_BGCOLOR); + } + + protected: + uint8_t pageIndex; +}; + void ScreenSetupPage::build(FormWindow * window) { FormGridLayout grid; @@ -154,10 +257,7 @@ void ScreenSetupPage::build(FormWindow * window) // Setup widgets button... setupWidgetsButton = new TextButton(window, grid.getFieldSlot(), STR_SETUP_WIDGETS); setupWidgetsButton->setPressHandler([=]() { -// auto setupWidgetsPage = new SetupWidgetsPage(); -// setupWidgetsPage->setCloseHandler([=]() { -// setupWidgetsButton->setFocus(); -// }); + new SetupWidgetsPage(pageIndex); return 0; }); grid.nextLine(); diff --git a/radio/src/gui/colorlcd/theme.cpp b/radio/src/gui/colorlcd/theme.cpp index 1b2f33a3c..1a9ba857c 100644 --- a/radio/src/gui/colorlcd/theme.cpp +++ b/radio/src/gui/colorlcd/theme.cpp @@ -242,5 +242,6 @@ MenuWindowContent * createMenuWindow(Menu * menu) DialogWindowContent * createDialogWindow(Dialog * dialog, const rect_t & rect) { + TRACE("createDialogWindow [%d, %d, %d, %d]", rect.x, rect.y, rect.w, rect.h); return new DialogWindowContent(dialog, rect); } diff --git a/radio/src/gui/colorlcd/widget.cpp b/radio/src/gui/colorlcd/widget.cpp index f377be0b6..a99a0f477 100644 --- a/radio/src/gui/colorlcd/widget.cpp +++ b/radio/src/gui/colorlcd/widget.cpp @@ -43,7 +43,7 @@ const WidgetFactory * getWidgetFactory(const char * name) return nullptr; } -Widget * loadWidget(const char * name, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData) +Widget * loadWidget(const char * name, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData) { const WidgetFactory * factory = getWidgetFactory(name); if (factory) { diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index 2014c3990..ca2196f0e 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -18,11 +18,11 @@ * GNU General Public License for more details. */ -#ifndef _WIDGET_H_ -#define _WIDGET_H_ +#pragma once #include #include +#include "form.h" #include "zone.h" #include "debug.h" @@ -34,15 +34,15 @@ #endif class WidgetFactory; -class Widget : public Window +class Widget : public FormField { public: struct PersistentData { ZoneOptionValueTyped options[MAX_WIDGET_OPTIONS] USE_IDX; }; - Widget(const WidgetFactory * factory, Window * parent, const rect_t & rect, PersistentData * persistentData): - Window(parent, rect), + Widget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, PersistentData * persistentData): + FormField(parent, rect), factory(factory), persistentData(persistentData) { @@ -116,7 +116,7 @@ class WidgetFactory } } - virtual Widget * create(Window * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const = 0; + virtual Widget * create(FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const = 0; protected: const char * name; @@ -132,7 +132,7 @@ class BaseWidgetFactory: public WidgetFactory { } - Widget * create(Window * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const override + Widget * create(FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const override { if (init) { initPersistentData(persistentData); @@ -147,8 +147,6 @@ inline const ZoneOption * Widget::getOptions() const return getFactory()->getOptions(); } -Widget * loadWidget(const char * name, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData); +Widget * loadWidget(const char * name, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData); std::list & getRegisteredWidgets(); - -#endif // _WIDGET_H_ diff --git a/radio/src/gui/colorlcd/widgets/gauge.cpp b/radio/src/gui/colorlcd/widgets/gauge.cpp index b358db0e6..f69978467 100644 --- a/radio/src/gui/colorlcd/widgets/gauge.cpp +++ b/radio/src/gui/colorlcd/widgets/gauge.cpp @@ -23,7 +23,7 @@ class GaugeWidget: public Widget { public: - GaugeWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + GaugeWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData): Widget(factory, parent, rect, persistentData) { } @@ -55,15 +55,26 @@ class GaugeWidget: public Widget dc->drawSolidFilledRect(0, 16, width(), 16, FOCUS_COLOR); dc->drawNumber(0+width()/2, 17, percent, FONT(XS) | CUSTOM_COLOR | CENTERED, 0, nullptr, "%"); dc->invertRect(w, 16, width() - w, 16, CUSTOM_COLOR); + + if (hasFocus()) { + dc->clear(HIGHLIGHT_COLOR); + } } void checkEvents() override { + Widget::checkEvents(); + auto newValue = getValue(persistentData->options[0].value.unsignedValue); if (lastValue != newValue) { lastValue = newValue; invalidate(); } + + if (!hasFocus() && g_tmr10ms < 100) { + TRACE("ICI"); + setFocus(SET_FOCUS_FIRST); + } } static const ZoneOption options[]; diff --git a/radio/src/gui/colorlcd/widgets/modelbmp.cpp b/radio/src/gui/colorlcd/widgets/modelbmp.cpp index a7ee84117..43bd75ccc 100644 --- a/radio/src/gui/colorlcd/widgets/modelbmp.cpp +++ b/radio/src/gui/colorlcd/widgets/modelbmp.cpp @@ -23,7 +23,7 @@ class ModelBitmapWidget: public Widget { public: - ModelBitmapWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + ModelBitmapWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData): Widget(factory, parent, rect, persistentData), buffer(nullptr), deps_hash(0) @@ -65,6 +65,8 @@ class ModelBitmapWidget: public Widget void checkEvents() override { + Widget::checkEvents(); + uint32_t new_hash = hash(g_model.header.bitmap, sizeof(g_model.header.bitmap)); new_hash ^= hash(g_model.header.name, sizeof(g_model.header.name)); new_hash ^= hash(g_eeGeneral.themeName, sizeof(g_eeGeneral.themeName)); diff --git a/radio/src/gui/colorlcd/widgets/outputs.cpp b/radio/src/gui/colorlcd/widgets/outputs.cpp index bd223601b..97efed9b2 100644 --- a/radio/src/gui/colorlcd/widgets/outputs.cpp +++ b/radio/src/gui/colorlcd/widgets/outputs.cpp @@ -28,7 +28,7 @@ class OutputsWidget: public Widget { public: - OutputsWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + OutputsWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData): Widget(factory, parent, rect, persistentData) { } @@ -99,6 +99,7 @@ class OutputsWidget: public Widget void checkEvents() override { + Widget::checkEvents(); invalidate(); } diff --git a/radio/src/gui/colorlcd/widgets/text.cpp b/radio/src/gui/colorlcd/widgets/text.cpp index b1068bd78..7fecda88a 100644 --- a/radio/src/gui/colorlcd/widgets/text.cpp +++ b/radio/src/gui/colorlcd/widgets/text.cpp @@ -25,7 +25,7 @@ class TextWidget: public Widget { public: - TextWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + TextWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData): Widget(factory, parent, rect, persistentData) { } diff --git a/radio/src/gui/colorlcd/widgets/timer.cpp b/radio/src/gui/colorlcd/widgets/timer.cpp index cb570a675..ffc0f850e 100644 --- a/radio/src/gui/colorlcd/widgets/timer.cpp +++ b/radio/src/gui/colorlcd/widgets/timer.cpp @@ -23,7 +23,7 @@ class TimerWidget: public Widget { public: - TimerWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + TimerWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData): Widget(factory, parent, rect, persistentData) { } @@ -88,6 +88,7 @@ class TimerWidget: public Widget void checkEvents() override { + Widget::checkEvents(); auto newValue = timersStates[persistentData->options[0].value.unsignedValue].val; if (lastValue != newValue) { lastValue = newValue; diff --git a/radio/src/gui/colorlcd/widgets/value.cpp b/radio/src/gui/colorlcd/widgets/value.cpp index 8f3fa148b..99312d125 100644 --- a/radio/src/gui/colorlcd/widgets/value.cpp +++ b/radio/src/gui/colorlcd/widgets/value.cpp @@ -25,7 +25,7 @@ const coord_t NUMBERS_PADDING = 4; class ValueWidget: public Widget { public: - ValueWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + ValueWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData): Widget(factory, parent, rect, persistentData) { } @@ -112,6 +112,8 @@ class ValueWidget: public Widget void checkEvents() override { + Widget::checkEvents(); + auto newValue = getValue(persistentData->options[0].value.unsignedValue); if (lastValue != newValue) { lastValue = newValue; diff --git a/radio/src/gui/colorlcd/widgets_container.h b/radio/src/gui/colorlcd/widgets_container.h index 341be934b..aefc22aa9 100644 --- a/radio/src/gui/colorlcd/widgets_container.h +++ b/radio/src/gui/colorlcd/widgets_container.h @@ -29,29 +29,14 @@ class WidgetsContainerInterface { public: virtual unsigned int getZonesCount() const = 0; - virtual rect_t getZone(unsigned int index) const = 0; - - inline Widget * getWidget(unsigned int index) - { - return widgets[index]; - } - - inline void setWidget(unsigned int index, Widget * widget) - { - widgets[index] = widget; - } - virtual void createWidget(unsigned int index, const WidgetFactory * factory) = 0; - - protected: - Widget ** widgets; }; #define WIDGET_NAME_LEN 10 template -class WidgetsContainer: public Window, public WidgetsContainerInterface +class WidgetsContainer: public FormGroup, public WidgetsContainerInterface { public: struct ZonePersistentData { @@ -65,7 +50,7 @@ class WidgetsContainer: public Window, public WidgetsContainerInterface }; WidgetsContainer(const rect_t & rect, PersistentData * persistentData): - Window(nullptr, rect), + FormGroup(nullptr, rect, FORM_FORWARD_FOCUS), persistentData(persistentData) { } @@ -96,7 +81,7 @@ class WidgetsContainer: public Window, public WidgetsContainerInterface char name[WIDGET_NAME_LEN + 1]; memset(name, 0, sizeof(name)); strncpy(name, persistentData->zones[i].widgetName, WIDGET_NAME_LEN); - // TODO widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData); + widgets[i] = loadWidget(name, this, getZone(i), &persistentData->zones[i].widgetData); } else { widgets[i] = nullptr; @@ -115,11 +100,9 @@ class WidgetsContainer: public Window, public WidgetsContainerInterface virtual void background() { - if (widgets) { - for (int i = 0; i < N; i++) { - if (widgets[i]) { - widgets[i]->background(); - } + for (int i = 0; i < N; i++) { + if (widgets[i]) { + widgets[i]->background(); } } } From a93aef3151cc87dd85b96dab2c8f8d961bc9838f Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 13:31:44 +0200 Subject: [PATCH 07/17] some clean-up (more to follow) --- radio/src/datastructs.h | 4 +- radio/src/gui/colorlcd/menu_screen.cpp | 9 ++- radio/src/gui/colorlcd/screen_setup.cpp | 82 ++++++++++++++----------- radio/src/gui/colorlcd/screen_setup.h | 7 ++- radio/src/gui/colorlcd/tabsgroup.h | 10 +++ 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 5ba76ce99..0c29eb50a 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -21,6 +21,8 @@ // No include guards here, this file may be included many times in different namespaces // i.e. BACKUP RAM Backup/Restore functions +#pragma once + #include #include "board.h" #include "dataconstants.h" @@ -986,4 +988,4 @@ static inline void check_struct() #undef CHKSIZE } -#endif /* BACKUP */ \ No newline at end of file +#endif /* BACKUP */ diff --git a/radio/src/gui/colorlcd/menu_screen.cpp b/radio/src/gui/colorlcd/menu_screen.cpp index cf63db023..330ddbedf 100644 --- a/radio/src/gui/colorlcd/menu_screen.cpp +++ b/radio/src/gui/colorlcd/menu_screen.cpp @@ -34,7 +34,14 @@ void ScreenMenu::updateTabs() for (int index = 0; index < MAX_CUSTOM_SCREENS; index++) { if (customScreens[index]) { - addTab(new ScreenSetupPage(this, index)); + + auto tab = new ScreenSetupPage(this, customScreens[index], g_model.screenData[index]); + std::string title(STR_MAIN_VIEW_X); + title.back() = index + '1'; + tab->setTitle(title); + tab->setIcon(ICON_THEME_VIEW1 + index); + + addTab(tab); } else { addTab(new ScreenAddPage(this, index)); diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index 1423557b5..888cb5d1a 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -26,23 +26,38 @@ #define SET_DIRTY() storageDirty(EE_MODEL) ScreenAddPage::ScreenAddPage(ScreenMenu * menu, uint8_t pageIndex): - PageTab("", ICON_THEME_ADD_VIEW), + PageTab(), menu(menu), pageIndex(pageIndex) { setTitle(STR_ADD_MAIN_VIEW); + setIcon(ICON_THEME_ADD_VIEW); } void ScreenAddPage::build(FormWindow * window) { - auto button = new TextButton(window, {LCD_W / 2 - 100, (window->height() - 24) / 2, 200, 24}, STR_ADD_MAIN_VIEW); + rect_t buttonRect = {LCD_W / 2 - 100, (window->height() - 24) / 2, 200, 24}; + auto button = new TextButton(window, buttonRect, STR_ADD_MAIN_VIEW); button->setPressHandler([=]() { + + auto& screen = customScreens[pageIndex]; + auto& screenData = g_model.screenData[pageIndex]; + const LayoutFactory * factory = getRegisteredLayouts().front(); - customScreens[pageIndex] = factory->create(&g_model.screenData[pageIndex].layoutData); - strncpy(g_model.screenData[pageIndex].layoutName, factory->getId(), sizeof(g_model.screenData[pageIndex].layoutName)); + + screen = factory->create(&screenData.layoutData); + strncpy(screenData.layoutName, factory->getId(), sizeof(screenData.layoutName)); + + auto tab = new ScreenSetupPage(menu, screen, screenData); + std::string title(STR_MAIN_VIEW_X); + title.back() = pageIndex + '0'; + tab->setTitle(title); + tab->setIcon(ICON_THEME_VIEW1 + pageIndex); + menu->removeTab(pageIndex); - menu->addTab(new ScreenSetupPage(menu, pageIndex)); + menu->addTab(tab); menu->setCurrentTab(pageIndex); + if (pageIndex < MAX_CUSTOM_SCREENS - 1) { menu->addTab(new ScreenAddPage(menu, pageIndex + 1)); } @@ -124,22 +139,20 @@ class LayoutChoice: public FormField { std::function setValue; }; -ScreenSetupPage::ScreenSetupPage(ScreenMenu * menu, uint8_t pageIndex): - PageTab("", ICON_THEME_VIEW1 + pageIndex), +ScreenSetupPage::ScreenSetupPage(ScreenMenu * menu, Layout*& screen, CustomScreenData& screenData): + PageTab(), menu(menu), - pageIndex(pageIndex) + screen(screen), + screenData(screenData) { - char title[] = "Main view X"; - title[sizeof(title) - 2] = '1' + pageIndex; - setTitle(title); } class SetupWidgetsPageSlot: public Button { public: - SetupWidgetsPageSlot(FormGroup * parent, const rect_t & rect, uint8_t pageIndex, uint8_t slotIndex): + SetupWidgetsPageSlot(FormGroup * parent, const rect_t & rect, Layout* screen, uint8_t slotIndex): Button(parent, rect), - pageIndex(pageIndex), + screen(screen), slotIndex(slotIndex) { setPressHandler([=](){ @@ -152,7 +165,7 @@ class SetupWidgetsPageSlot: public Button widget->deleteLater(); } // widget = factory->create(this, {1, 1, width() - 2, height() - 2}, &g_model.screenData[pageIndex].layoutData.zones[slotIndex].widgetData, true); - customScreens[pageIndex]->createWidget(slotIndex, factory); + screen->createWidget(slotIndex, factory); return 0; }); } @@ -180,7 +193,7 @@ class SetupWidgetsPageSlot: public Button } protected: - uint8_t pageIndex; + Layout * screen; uint8_t slotIndex; Window * widget = nullptr; }; @@ -188,18 +201,16 @@ class SetupWidgetsPageSlot: public Button class SetupWidgetsPage: public FormWindow { public: - SetupWidgetsPage(uint8_t pageIndex): + SetupWidgetsPage(Layout * screen): FormWindow(MainWindow::instance(), {0, 0, LCD_W, LCD_H}, OPAQUE | FORM_FORWARD_FOCUS), - pageIndex(pageIndex) + screen(screen) { Layer::push(this); clearFocus(); - auto & customScreen = customScreens[pageIndex]; - - for (unsigned i = 0; i < customScreen->getZonesCount(); i++) { - auto rect = customScreen->getZone(i); - new SetupWidgetsPageSlot(this, {rect.x - 1, rect.y - 1, rect.w + 2, rect.h + 2}, pageIndex, i); + for (unsigned i = 0; i < screen->getZonesCount(); i++) { + auto rect = screen->getZone(i); + new SetupWidgetsPageSlot(this, {rect.x - 1, rect.y - 1, rect.w + 2, rect.h + 2}, screen, i); } } @@ -233,7 +244,7 @@ class SetupWidgetsPage: public FormWindow } protected: - uint8_t pageIndex; + Layout* screen; }; void ScreenSetupPage::build(FormWindow * window) @@ -245,10 +256,10 @@ void ScreenSetupPage::build(FormWindow * window) new StaticText(window, grid.getLabelSlot(false), STR_LAYOUT); auto layoutSlot = grid.getFieldSlot(); layoutSlot.h = 2 * PAGE_LINE_HEIGHT - 1; - layoutChoice = new LayoutChoice(window, layoutSlot, GET_VALUE(customScreens[pageIndex]->getFactory()), [=](const LayoutFactory *factory) { - delete customScreens[pageIndex]; - customScreens[pageIndex] = factory->create(&g_model.screenData[pageIndex].layoutData); - strncpy(g_model.screenData[pageIndex].layoutName, factory->getId(), sizeof(g_model.screenData[pageIndex].layoutName)); + layoutChoice = new LayoutChoice(window, layoutSlot, GET_VALUE(screen->getFactory()), [=](const LayoutFactory *factory) { + delete screen; + screen = factory->create(&screenData.layoutData); + strncpy(screenData.layoutName, factory->getId(), sizeof(CustomScreenData::layoutName)); SET_DIRTY(); updateLayoutOptions(); }); @@ -257,7 +268,7 @@ void ScreenSetupPage::build(FormWindow * window) // Setup widgets button... setupWidgetsButton = new TextButton(window, grid.getFieldSlot(), STR_SETUP_WIDGETS); setupWidgetsButton->setPressHandler([=]() { - new SetupWidgetsPage(pageIndex); + new SetupWidgetsPage(screen); return 0; }); grid.nextLine(); @@ -273,8 +284,6 @@ void ScreenSetupPage::updateLayoutOptions() FormGridLayout grid; optionsWindow->clear(); - auto screen = customScreens[pageIndex]; - // Layout options... int index = 0; for (auto * option = screen->getFactory()->getOptions(); option->name; option++, index++) { @@ -299,19 +308,20 @@ void ScreenSetupPage::updateLayoutOptions() grid.nextLine(); } - if (pageIndex > 0 || customScreens[1]) { + //if (pageIndex > 0 || customScreens[1]) { auto button = new TextButton(optionsWindow, grid.getFieldSlot(), STR_REMOVE_SCREEN); button->setPressHandler([=]() { - if (pageIndex < MAX_CUSTOM_SCREENS - 1) { - memmove(&g_model.screenData[pageIndex], &g_model.screenData[pageIndex + 1], sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - pageIndex - 1)); - } - memset(&g_model.screenData[MAX_CUSTOM_SCREENS - 1], 0, sizeof(CustomScreenData)); + // if (pageIndex < MAX_CUSTOM_SCREENS - 1) { + // memmove(&g_model.screenData[pageIndex], &g_model.screenData[pageIndex + 1], sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - pageIndex - 1)); + // } + // memset(&g_model.screenData[MAX_CUSTOM_SCREENS - 1], 0, sizeof(CustomScreenData)); + memset(&screenData, 0, sizeof(CustomScreenData)); loadCustomScreens(); menu->updateTabs(); storageDirty(EE_MODEL); return 0; }); - } + //} optionsWindow->adjustHeight(); optionsWindow->getParent()->adjustInnerHeight(); diff --git a/radio/src/gui/colorlcd/screen_setup.h b/radio/src/gui/colorlcd/screen_setup.h index b7f4d51b9..d8372ffb6 100644 --- a/radio/src/gui/colorlcd/screen_setup.h +++ b/radio/src/gui/colorlcd/screen_setup.h @@ -19,6 +19,8 @@ */ #include "menu_screen.h" +#include "layout.h" +#include "datastructs.h" class ScreenAddPage: public PageTab { public: @@ -33,13 +35,14 @@ class ScreenAddPage: public PageTab { class ScreenSetupPage: public PageTab { public: - ScreenSetupPage(ScreenMenu * menu, uint8_t pageIndex); + ScreenSetupPage(ScreenMenu * menu, Layout*& screen, CustomScreenData& screenData); void build(FormWindow * window) override; protected: ScreenMenu * menu; - uint8_t pageIndex; + Layout *& screen; + CustomScreenData& screenData; FormGroup * optionsWindow = nullptr; TextButton * setupWidgetsButton = nullptr; FormField * layoutChoice = nullptr; diff --git a/radio/src/gui/colorlcd/tabsgroup.h b/radio/src/gui/colorlcd/tabsgroup.h index 383fcaac1..9092d4932 100644 --- a/radio/src/gui/colorlcd/tabsgroup.h +++ b/radio/src/gui/colorlcd/tabsgroup.h @@ -32,6 +32,11 @@ class PageTab { friend class TabsGroup; public: + PageTab(): + icon(0) + { + } + PageTab(std::string title, unsigned icon): title(std::move(title)), icon(icon) @@ -64,6 +69,11 @@ class PageTab { title = std::move(value); } + void setIcon(unsigned icon) + { + this->icon = icon; + } + unsigned getIcon() const { return icon; From bfad5b2ad80038f63cc916dba8b4ac3b59b414b9 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 13:40:05 +0200 Subject: [PATCH 08/17] remove useless TR_MAINVIEWX TR_MAIN_VIEW_X is already existing and used. --- radio/src/translations/cn.h.txt | 1 - radio/src/translations/cz.h.txt | 1 - radio/src/translations/de.h.txt | 1 - radio/src/translations/en.h.txt | 1 - radio/src/translations/es.h.txt | 1 - radio/src/translations/fr.h.txt | 1 - radio/src/translations/it.h.txt | 1 - radio/src/translations/nl.h.txt | 1 - radio/src/translations/pl.h.txt | 1 - radio/src/translations/pt.h.txt | 1 - radio/src/translations/se.h.txt | 1 - radio/src/translations/tw.h.txt | 1 - 12 files changed, 12 deletions(-) diff --git a/radio/src/translations/cn.h.txt b/radio/src/translations/cn.h.txt index 91e172e5c..6e2c14d53 100644 --- a/radio/src/translations/cn.h.txt +++ b/radio/src/translations/cn.h.txt @@ -1126,7 +1126,6 @@ #define TR_USER_INTERFACE "用户界面" #define TR_THEME "主题" #define TR_SETUP "设置" -#define TR_MAINVIEWX "Main view X" #define TR_LAYOUT "布局" #define TR_ADD_MAIN_VIEW "添加主视图" #define TR_BACKGROUND_COLOR "背景颜色" diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index d24ac7949..df4680df0 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -1226,7 +1226,6 @@ #define TR_USER_INTERFACE "Uživatelké rozhraní" #define TR_THEME "Téma" #define TR_SETUP "Nastavení" -#define TR_MAINVIEWX "Hlavní panel X" #define TR_LAYOUT "Rozložení" #define TR_ADD_MAIN_VIEW "Přidat hlavní panel" #define TR_BACKGROUND_COLOR "Barva pozadí" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index fa39e5ce8..6edf51683 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -1235,7 +1235,6 @@ #define TR_USER_INTERFACE "User interface" #define TR_THEME "Theme" #define TR_SETUP "Setup" -#define TR_MAINVIEWX "Ansicht X" #define TR_LAYOUT "Layout" #define TR_ADD_MAIN_VIEW "Ansicht hinzufügen" #define TR_BACKGROUND_COLOR "Hintergrundfarbe" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 300c50c4a..946ad558e 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -1241,7 +1241,6 @@ #define TR_USER_INTERFACE "User interface" #define TR_THEME "Theme" #define TR_SETUP "Setup" -#define TR_MAINVIEWX "Main view X" #define TR_LAYOUT "Layout" #define TR_ADD_MAIN_VIEW "Add main view" #define TR_BACKGROUND_COLOR "Background color" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 0bfbb9506..564e7ef1a 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -1234,7 +1234,6 @@ #define TR_USER_INTERFACE "Interfaz" #define TR_THEME "Tema" #define TR_SETUP "Configuración" -#define TR_MAINVIEWX "Vista pral. X" #define TR_LAYOUT "Diseño" #define TR_ADD_MAIN_VIEW "Añadir vista pral." #define TR_BACKGROUND_COLOR "Color de fondo" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 189cbef48..a49f803ac 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -1265,7 +1265,6 @@ #define TR_USER_INTERFACE "Interface utilisateur" #define TR_THEME "Thème" #define TR_SETUP "Configuration" -#define TR_MAINVIEWX "Vue principale X" #define TR_LAYOUT "Disposition" #define TR_ADD_MAIN_VIEW "Ajouter vue principale" #define TR_BACKGROUND_COLOR "Couleur de fond" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 8d514debe..9842dc7ed 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -1254,7 +1254,6 @@ #define TR_USER_INTERFACE "Interfaccia utente" #define TR_THEME "Tema" #define TR_SETUP "Imposta" -#define TR_MAINVIEWX "Vista princ. X" #define TR_LAYOUT "Layout" #define TR_ADD_MAIN_VIEW "Aggiungi vista princ." #define TR_BACKGROUND_COLOR "Colore background" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 5f76c5b3a..6d2acdc7c 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -1240,7 +1240,6 @@ #define TR_USER_INTERFACE "User interface" #define TR_THEME "Theme" #define TR_SETUP "Setup" -#define TR_MAINVIEWX "Main view X" #define TR_LAYOUT "Layout" #define TR_ADD_MAIN_VIEW "Add main view" #define TR_BACKGROUND_COLOR "Background color" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 9e38e723e..ef15f9922 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -1250,7 +1250,6 @@ #define TR_USER_INTERFACE "User interface" #define TR_THEME "Theme" #define TR_SETUP "Setup" -#define TR_MAINVIEWX "Main view X" #define TR_LAYOUT "Layout" #define TR_ADD_MAIN_VIEW "Add main view" #define TR_BACKGROUND_COLOR "Background color" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 389eeea00..60a0db1e0 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -1250,7 +1250,6 @@ #define TR_USER_INTERFACE "User interface" #define TR_THEME "Theme" #define TR_SETUP "Setup" -#define TR_MAINVIEWX "Main view X" #define TR_LAYOUT "Layout" #define TR_ADD_MAIN_VIEW "Add main view" #define TR_BACKGROUND_COLOR "Background color" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 9637b9f65..4f869131b 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -1253,7 +1253,6 @@ #define TR_USER_INTERFACE "User interface" #define TR_THEME "Theme" #define TR_SETUP "Setup" -#define TR_MAINVIEWX "Main view X" #define TR_LAYOUT "Layout" #define TR_ADD_MAIN_VIEW "Add main view" #define TR_BACKGROUND_COLOR "Background color" diff --git a/radio/src/translations/tw.h.txt b/radio/src/translations/tw.h.txt index 915fd406f..218e96c31 100644 --- a/radio/src/translations/tw.h.txt +++ b/radio/src/translations/tw.h.txt @@ -1134,7 +1134,6 @@ #define TR_USER_INTERFACE "用戶界面" #define TR_THEME "主題" #define TR_SETUP "設置" -#define TR_MAINVIEWX "Main view X" #define TR_LAYOUT "佈局" #define TR_ADD_MAIN_VIEW "添加主視圖" #define TR_BACKGROUND_COLOR "背景顏色" From f389d364d609a2d0f18884ecce28b883f845751d Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 15:05:44 +0200 Subject: [PATCH 09/17] fix datacopy --- radio/src/targets/horus/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index c5ea0b24f..2fe767e56 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -328,7 +328,7 @@ if(PYTHONINTERP_FOUND) add_custom_command( OUTPUT ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp WORKING_DIRECTORY ${RADIO_DIRECTORY}/src - COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBHORUS -DPCBX10 -DCPUARM -DSTM32F4 -DSTM32F429_439xx -DCOLORLCD -DBACKUP -DSIMU -I. -Igui/colorlcd -Itargets/horus -Itargets/common/arm/stm32 -I${THIRDPARTY_DIR} -I${THIRDPARTY_DIR}/libopenui/src -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/STM32F4xx_StdPeriph_Driver/inc -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Include ${arm_gcc_include_path} > ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp + COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBHORUS -DPCBX10 -DCPUARM -DSTM32F4 -DSTM32F429_439xx -DCOLORLCD -DBACKUP -DSIMU -I. -Igui/colorlcd -Itargets/horus -Itargets/common/arm/stm32 -I${THIRDPARTY_DIR} -I${THIRDPARTY_DIR}/libopenui/src -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/STM32F4xx_StdPeriph_Driver/inc -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Include ${arm_gcc_include_path} -Wno-pragma-once-outside-header > ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py ) From aff897550ec18ff436e92c5820d789aebf0ebc58 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 15:46:05 +0200 Subject: [PATCH 10/17] widget preview while setting up --- radio/src/gui/colorlcd/screen_setup.cpp | 14 +++++++------- radio/src/gui/colorlcd/widget.h | 10 ++++++++++ radio/src/gui/colorlcd/widgets_container.h | 22 ++++++++++++++++------ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index 888cb5d1a..f36658835 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -155,23 +155,21 @@ class SetupWidgetsPageSlot: public Button screen(screen), slotIndex(slotIndex) { + widget = screen->getWidget(slotIndex); setPressHandler([=](){ Menu * menu = new Menu(this); menu->addLine("Select a widget", [=]() { Menu * menu = new Menu(this); for (auto factory: getRegisteredWidgets()) { menu->addLine(factory->getName(), [=]() { - if (widget) { - widget->deleteLater(); - } - // widget = factory->create(this, {1, 1, width() - 2, height() - 2}, &g_model.screenData[pageIndex].layoutData.zones[slotIndex].widgetData, true); - screen->createWidget(slotIndex, factory); + if (widget) widget->deleteLater(); + widget = screen->createWidget(slotIndex, factory); return 0; }); } return 0; }); - if (widget /*g_model.screenData[pageIndex].layoutData.zones[slotIndex].widgetName[0]*/) { + if (widget) { menu->addLine(STR_DELETE, [=]() { widget->deleteLater(); widget = nullptr; @@ -190,12 +188,14 @@ class SetupWidgetsPageSlot: public Button else { dc->drawRect(0, 0, width(), height(), 1, DOTTED, DEFAULT_COLOR); } + if (widget) + widget->paint(dc); } protected: Layout * screen; uint8_t slotIndex; - Window * widget = nullptr; + Widget * widget = nullptr; }; class SetupWidgetsPage: public FormWindow diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index ca2196f0e..e5c4f54f5 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -71,6 +71,16 @@ class Widget : public FormField return &persistentData->options[index].value; } + inline PersistentData * getPersistentData() + { + return persistentData; + } + + void paint(BitmapBuffer * dc) override + { + FormField::paint(dc); + } + virtual void background() { } diff --git a/radio/src/gui/colorlcd/widgets_container.h b/radio/src/gui/colorlcd/widgets_container.h index aefc22aa9..d1f020a5d 100644 --- a/radio/src/gui/colorlcd/widgets_container.h +++ b/radio/src/gui/colorlcd/widgets_container.h @@ -30,7 +30,8 @@ class WidgetsContainerInterface public: virtual unsigned int getZonesCount() const = 0; virtual rect_t getZone(unsigned int index) const = 0; - virtual void createWidget(unsigned int index, const WidgetFactory * factory) = 0; + virtual Widget * createWidget(unsigned int index, const WidgetFactory * factory) = 0; + virtual Widget * getWidget(unsigned int index) = 0; }; #define WIDGET_NAME_LEN 10 @@ -55,16 +56,25 @@ class WidgetsContainer: public FormGroup, public WidgetsContainerInterface { } - void createWidget(unsigned int index, const WidgetFactory * factory) override + Widget * createWidget(unsigned int index, const WidgetFactory * factory) override { + Widget * widget = nullptr; memset(persistentData->zones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName)); if (factory) { strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(persistentData->zones[index].widgetName)); - widgets[index] = factory->create(this, getZone(index), &persistentData->zones[index].widgetData); - } - else { - widgets[index] = nullptr; + widget = factory->create(this, getZone(index), &persistentData->zones[index].widgetData); } + widgets[index] = widget; + + return widget; + } + + Widget * getWidget(unsigned int index) override + { + if (index < N) + return widgets[index]; + + return nullptr; } virtual void create() From 5d5fcbcc2ee5a1c59d45b8468d28166980bd62dd Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 4 Apr 2021 21:00:22 +0200 Subject: [PATCH 11/17] WYSIWYG custom screen setup not yet very nice, but working. --- radio/src/gui/colorlcd/screen_setup.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index f36658835..576ef13a8 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -188,8 +188,6 @@ class SetupWidgetsPageSlot: public Button else { dc->drawRect(0, 0, width(), height(), 1, DOTTED, DEFAULT_COLOR); } - if (widget) - widget->paint(dc); } protected: @@ -203,11 +201,15 @@ class SetupWidgetsPage: public FormWindow public: SetupWidgetsPage(Layout * screen): FormWindow(MainWindow::instance(), {0, 0, LCD_W, LCD_H}, OPAQUE | FORM_FORWARD_FOCUS), - screen(screen) + screen(screen), + oldParent(screen->getParent()) { Layer::push(this); clearFocus(); + // attach this custom screen here so we can display it + screen->attach(this); + for (unsigned i = 0; i < screen->getZonesCount(); i++) { auto rect = screen->getZone(i); new SetupWidgetsPageSlot(this, {rect.x - 1, rect.y - 1, rect.w + 2, rect.h + 2}, screen, i); @@ -221,8 +223,10 @@ class SetupWidgetsPage: public FormWindow #if defined(HARDWARE_TOUCH) Keyboard::hide(); #endif + // give it back to its old parent before it gets deleted + screen->attach(oldParent); - Window::deleteLater(detach, trash); + FormWindow::deleteLater(detach, trash); } #if defined(HARDWARE_KEYS) @@ -238,13 +242,15 @@ class SetupWidgetsPage: public FormWindow } #endif + protected: + Layout* screen; + Window* oldParent; + void paint(BitmapBuffer * dc) override { dc->clear(DEFAULT_BGCOLOR); } - protected: - Layout* screen; }; void ScreenSetupPage::build(FormWindow * window) From 766c1f6b798627c30d41fce05e844fe3243e2461 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 5 Apr 2021 08:40:49 +0200 Subject: [PATCH 12/17] WiP widget settings --- radio/src/gui/colorlcd/CMakeLists.txt | 1 + radio/src/gui/colorlcd/screen_setup.cpp | 13 ++- radio/src/gui/colorlcd/widget.h | 5 + radio/src/gui/colorlcd/widget_settings.cpp | 129 +++++++++++++++++++++ radio/src/gui/colorlcd/widget_settings.h | 32 +++++ 5 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 radio/src/gui/colorlcd/widget_settings.cpp create mode 100644 radio/src/gui/colorlcd/widget_settings.h diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index 3151e92d6..9a2c1db3a 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -23,6 +23,7 @@ set(GUI_SRC topbar.cpp layout.cpp widget.cpp + widget_settings.cpp ${THEMES_SRC} ${LAYOUTS_SRC} ${WIDGETS_SRC} diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index 576ef13a8..1d88962be 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -22,6 +22,7 @@ #include "screen_setup.h" #include "opentx.h" #include "view_main.h" +#include "widget_settings.h" #define SET_DIRTY() storageDirty(EE_MODEL) @@ -158,7 +159,7 @@ class SetupWidgetsPageSlot: public Button widget = screen->getWidget(slotIndex); setPressHandler([=](){ Menu * menu = new Menu(this); - menu->addLine("Select a widget", [=]() { + menu->addLine(TR_SELECT_WIDGET, [=]() { Menu * menu = new Menu(this); for (auto factory: getRegisteredWidgets()) { menu->addLine(factory->getName(), [=]() { @@ -170,7 +171,15 @@ class SetupWidgetsPageSlot: public Button return 0; }); if (widget) { - menu->addLine(STR_DELETE, [=]() { + menu->addLine(TR_WIDGET_SETTINGS, [=]() { + new WidgetSettings(this, widget, [=]() { + TRACE("WidgetSettings confirmed"); + deleteLater(); + return; + }); + }); + + menu->addLine(STR_REMOVE_WIDGET, [=]() { widget->deleteLater(); widget = nullptr; return 0; diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index e5c4f54f5..e1bb59aae 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -71,6 +71,11 @@ class Widget : public FormField return &persistentData->options[index].value; } + inline void setOptionValue(unsigned int index, const ZoneOptionValue& value) + { + persistentData->options[index].value = value; + } + inline PersistentData * getPersistentData() { return persistentData; diff --git a/radio/src/gui/colorlcd/widget_settings.cpp b/radio/src/gui/colorlcd/widget_settings.cpp new file mode 100644 index 000000000..6659fe915 --- /dev/null +++ b/radio/src/gui/colorlcd/widget_settings.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" +#include "widget_settings.h" + +static const rect_t widgetSettingsDialogRect = { + LCD_W / 10, // x + LCD_H / 4, // y + LCD_W - 2 * LCD_W / 10, // width + LCD_H - 2 * LCD_H / 4 // height +}; + +WidgetSettings::WidgetSettings(Window * parent, Widget * widget, std::function confirmHandler) : + Dialog(parent, TR_WIDGET_SETTINGS, widgetSettingsDialogRect), + confirmHandler(std::move(confirmHandler)) +{ + auto form = &content->form; + FormGridLayout grid(content->form.width()); + form->clear(); + + uint8_t optIdx = 0; + auto optPtr = widget->getOptions(); + + while (optPtr->name != nullptr) { + + auto option = *optPtr; + new StaticText(form, grid.getLabelSlot(), option.name); + + switch (option.type) { + + case ZoneOption::Integer: + new NumberEdit(form, grid.getFieldSlot(), + option.min.signedValue, // Minimum + option.max.signedValue, // Maximum + [=]() -> int { // getValue + return widget->getOptionValue(optIdx)->signedValue; + }, + [=](int32_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_SIGNED(newValue)); + }); + break; + + case ZoneOption::Source: + new SourceChoice(form, grid.getFieldSlot(), + option.min.unsignedValue, // min + option.max.unsignedValue, // max + [=]() -> int16_t { // getValue + return (int16_t)widget->getOptionValue(optIdx)->unsignedValue; + }, + [=](int16_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t)newValue)); + }); + break; + + case ZoneOption::Bool: + new CheckBox(form, grid.getFieldSlot(), + [=]() -> uint8_t { // getValue + return (uint8_t)widget->getOptionValue(optIdx)->boolValue; + }, + [=](int8_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_BOOL((uint32_t)newValue)); + }); + break; + + case ZoneOption::String: + break; + + case ZoneOption::File: + break; + + case ZoneOption::TextSize: + break; + + case ZoneOption::Timer: // Unsigned + { + auto tmChoice = new Choice(form, grid.getFieldSlot(), + 0, TIMERS - 1, + [=]() -> int { // getValue + return (int)widget->getOptionValue(optIdx)->unsignedValue; + }, + [=](int newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t)newValue)); + }); + + tmChoice->setTextHandler([](int value) { + return std::string(STR_TIMER) + std::to_string(value + 1); + }); + } + break; + + case ZoneOption::Switch: + new SwitchChoice(form, grid.getFieldSlot(), + option.min.unsignedValue, // min + option.max.unsignedValue, // max + [=]() -> int16_t { // getValue + return (uint8_t)widget->getOptionValue(optIdx)->unsignedValue; + }, + [=](int16_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t)newValue)); + }); + break; + + case ZoneOption::Color: + break; + } + + optIdx++; + optPtr++; + grid.nextLine(); + } +} diff --git a/radio/src/gui/colorlcd/widget_settings.h b/radio/src/gui/colorlcd/widget_settings.h new file mode 100644 index 000000000..9f59e95db --- /dev/null +++ b/radio/src/gui/colorlcd/widget_settings.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "dialog.h" +#include "widget.h" + +class WidgetSettings: public Dialog +{ + std::function confirmHandler; + + public: + WidgetSettings(Window * parent, Widget * widget, std::function confirmHandler); +}; From 8ccf3c0437be870ad72aa884bc625f968afc9390 Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 5 Apr 2021 08:46:57 +0200 Subject: [PATCH 13/17] Fix trainer SF --- radio/src/gui/colorlcd/special_functions.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/radio/src/gui/colorlcd/special_functions.cpp b/radio/src/gui/colorlcd/special_functions.cpp index 779b08f9f..2b076a32a 100644 --- a/radio/src/gui/colorlcd/special_functions.cpp +++ b/radio/src/gui/colorlcd/special_functions.cpp @@ -82,11 +82,20 @@ class SpecialFunctionEditPage : public Page { grid.nextLine(); break; - case FUNC_TRAINER: - new StaticText(specialFunctionOneWindow, grid.getLabelSlot(), STR_TIMER); - new SourceChoice(specialFunctionOneWindow, grid.getFieldSlot(), 0, 4, GET_SET_DEFAULT(CFN_TIMER_INDEX(cfn))); + case FUNC_TRAINER: { + new StaticText(specialFunctionOneWindow, grid.getLabelSlot(), STR_VALUE); + auto choice = new Choice(specialFunctionOneWindow, grid.getFieldSlot(), 0,NUM_STICKS + 1,GET_SET_DEFAULT(CFN_PARAM(cfn))); + choice->setTextHandler([=](int32_t value) { + if (value == 0) + return std::string(STR_STICKS); + else if (value == NUM_STICKS + 1) + return std::string(STR_CHANS); + else + return TEXT_AT_INDEX(STR_VSRCRAW, value);; + }); grid.nextLine(); break; + } case FUNC_RESET: if (CFN_PARAM(cfn) < FUNC_RESET_PARAM_FIRST_TELEM) { From 0ac2a814a1c676e71ab606ed0d59cdc57f9ac941 Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 5 Apr 2021 09:02:36 +0200 Subject: [PATCH 14/17] Cosmetcis + add colorchoice --- radio/src/gui/colorlcd/widget_settings.cpp | 175 +++++++++++---------- 1 file changed, 91 insertions(+), 84 deletions(-) diff --git a/radio/src/gui/colorlcd/widget_settings.cpp b/radio/src/gui/colorlcd/widget_settings.cpp index 6659fe915..caf862712 100644 --- a/radio/src/gui/colorlcd/widget_settings.cpp +++ b/radio/src/gui/colorlcd/widget_settings.cpp @@ -22,108 +22,115 @@ #include "widget_settings.h" static const rect_t widgetSettingsDialogRect = { - LCD_W / 10, // x - LCD_H / 4, // y - LCD_W - 2 * LCD_W / 10, // width - LCD_H - 2 * LCD_H / 4 // height + LCD_W / 10, // x + LCD_H / 4, // y + LCD_W - 2 * LCD_W / 10, // width + LCD_H - 2 * LCD_H / 4 // height }; WidgetSettings::WidgetSettings(Window * parent, Widget * widget, std::function confirmHandler) : - Dialog(parent, TR_WIDGET_SETTINGS, widgetSettingsDialogRect), - confirmHandler(std::move(confirmHandler)) + Dialog(parent, TR_WIDGET_SETTINGS, widgetSettingsDialogRect), + confirmHandler(std::move(confirmHandler)) { - auto form = &content->form; - FormGridLayout grid(content->form.width()); - form->clear(); + auto form = &content->form; + FormGridLayout grid(content->form.width()); + grid.setLabelWidth(width() / 5); + form->clear(); - uint8_t optIdx = 0; - auto optPtr = widget->getOptions(); + uint8_t optIdx = 0; + auto optPtr = widget->getOptions(); - while (optPtr->name != nullptr) { + while (optPtr->name != nullptr) { - auto option = *optPtr; - new StaticText(form, grid.getLabelSlot(), option.name); + auto option = *optPtr; + new StaticText(form, grid.getLabelSlot(), option.name); - switch (option.type) { + switch (option.type) { - case ZoneOption::Integer: - new NumberEdit(form, grid.getFieldSlot(), - option.min.signedValue, // Minimum - option.max.signedValue, // Maximum - [=]() -> int { // getValue - return widget->getOptionValue(optIdx)->signedValue; - }, - [=](int32_t newValue) { // setValue - widget->setOptionValue(optIdx, OPTION_VALUE_SIGNED(newValue)); - }); - break; + case ZoneOption::Integer: + new NumberEdit(form, grid.getFieldSlot(), + option.min.signedValue, // Minimum + option.max.signedValue, // Maximum + [=]() -> int { // getValue + return widget->getOptionValue(optIdx)->signedValue; + }, + [=](int32_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_SIGNED(newValue)); + }); + break; - case ZoneOption::Source: - new SourceChoice(form, grid.getFieldSlot(), - option.min.unsignedValue, // min - option.max.unsignedValue, // max - [=]() -> int16_t { // getValue - return (int16_t)widget->getOptionValue(optIdx)->unsignedValue; - }, - [=](int16_t newValue) { // setValue - widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t)newValue)); - }); - break; - - case ZoneOption::Bool: - new CheckBox(form, grid.getFieldSlot(), - [=]() -> uint8_t { // getValue - return (uint8_t)widget->getOptionValue(optIdx)->boolValue; + case ZoneOption::Source: + new SourceChoice(form, grid.getFieldSlot(), + option.min.unsignedValue, // min + option.max.unsignedValue, // max + [=]() -> int16_t { // getValue + return (int16_t) widget->getOptionValue(optIdx)->unsignedValue; }, - [=](int8_t newValue) { // setValue - widget->setOptionValue(optIdx, OPTION_VALUE_BOOL((uint32_t)newValue)); + [=](int16_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t) newValue)); }); - break; + break; - case ZoneOption::String: - break; + case ZoneOption::Bool: + new CheckBox(form, grid.getFieldSlot(), + [=]() -> uint8_t { // getValue + return (uint8_t) widget->getOptionValue(optIdx)->boolValue; + }, + [=](int8_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_BOOL((uint32_t) newValue)); + }); + break; - case ZoneOption::File: - break; + case ZoneOption::String: + break; - case ZoneOption::TextSize: - break; + case ZoneOption::File: + break; - case ZoneOption::Timer: // Unsigned - { - auto tmChoice = new Choice(form, grid.getFieldSlot(), - 0, TIMERS - 1, - [=]() -> int { // getValue - return (int)widget->getOptionValue(optIdx)->unsignedValue; - }, - [=](int newValue) { // setValue - widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t)newValue)); - }); + case ZoneOption::TextSize: + break; - tmChoice->setTextHandler([](int value) { - return std::string(STR_TIMER) + std::to_string(value + 1); - }); - } - break; + case ZoneOption::Timer: // Unsigned + { + auto tmChoice = new Choice(form, grid.getFieldSlot(), + 0, TIMERS - 1, + [=]() -> int { // getValue + return (int) widget->getOptionValue(optIdx)->unsignedValue; + }, + [=](int newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t) newValue)); + }); - case ZoneOption::Switch: - new SwitchChoice(form, grid.getFieldSlot(), - option.min.unsignedValue, // min - option.max.unsignedValue, // max - [=]() -> int16_t { // getValue - return (uint8_t)widget->getOptionValue(optIdx)->unsignedValue; - }, - [=](int16_t newValue) { // setValue - widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t)newValue)); - }); - break; + tmChoice->setTextHandler([](int value) { + return std::string(STR_TIMER) + std::to_string(value + 1); + }); + } + break; - case ZoneOption::Color: - break; - } + case ZoneOption::Switch: + new SwitchChoice(form, grid.getFieldSlot(), + option.min.unsignedValue, // min + option.max.unsignedValue, // max + [=]() -> int16_t { // getValue + return (uint8_t) widget->getOptionValue(optIdx)->unsignedValue; + }, + [=](int16_t newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t) newValue)); + }); + break; - optIdx++; - optPtr++; - grid.nextLine(); - } + case ZoneOption::Color: + new ColorEdit(form, grid.getFieldSlot(), [=]() -> int { // getValue + return (int) widget->getOptionValue(optIdx)->unsignedValue; + }, + [=](int newValue) { // setValue + widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t) newValue)); + }); + break; + } + + optIdx++; + optPtr++; + grid.nextLine(); + } } From 27410fe20a223b063e7e4aa3d83d0f2b8f3ae60b Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 5 Apr 2021 09:46:02 +0200 Subject: [PATCH 15/17] cleaned up widget settings --- radio/src/gui/colorlcd/screen_setup.cpp | 17 +++++------------ radio/src/gui/colorlcd/widget_settings.cpp | 19 ++++++++++++++++--- radio/src/gui/colorlcd/widget_settings.h | 6 +++++- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index 1d88962be..ca083cbaa 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -39,7 +39,7 @@ void ScreenAddPage::build(FormWindow * window) { rect_t buttonRect = {LCD_W / 2 - 100, (window->height() - 24) / 2, 200, 24}; auto button = new TextButton(window, buttonRect, STR_ADD_MAIN_VIEW); - button->setPressHandler([=]() { + button->setPressHandler([=]() -> uint8_t { auto& screen = customScreens[pageIndex]; auto& screenData = g_model.screenData[pageIndex]; @@ -157,7 +157,7 @@ class SetupWidgetsPageSlot: public Button slotIndex(slotIndex) { widget = screen->getWidget(slotIndex); - setPressHandler([=](){ + setPressHandler([=]() -> uint8_t { Menu * menu = new Menu(this); menu->addLine(TR_SELECT_WIDGET, [=]() { Menu * menu = new Menu(this); @@ -165,24 +165,17 @@ class SetupWidgetsPageSlot: public Button menu->addLine(factory->getName(), [=]() { if (widget) widget->deleteLater(); widget = screen->createWidget(slotIndex, factory); - return 0; }); } - return 0; }); if (widget) { menu->addLine(TR_WIDGET_SETTINGS, [=]() { - new WidgetSettings(this, widget, [=]() { - TRACE("WidgetSettings confirmed"); - deleteLater(); - return; - }); + new WidgetSettings(this, widget); }); menu->addLine(STR_REMOVE_WIDGET, [=]() { widget->deleteLater(); widget = nullptr; - return 0; }); } return 0; @@ -282,7 +275,7 @@ void ScreenSetupPage::build(FormWindow * window) // Setup widgets button... setupWidgetsButton = new TextButton(window, grid.getFieldSlot(), STR_SETUP_WIDGETS); - setupWidgetsButton->setPressHandler([=]() { + setupWidgetsButton->setPressHandler([=]() -> uint8_t { new SetupWidgetsPage(screen); return 0; }); @@ -325,7 +318,7 @@ void ScreenSetupPage::updateLayoutOptions() //if (pageIndex > 0 || customScreens[1]) { auto button = new TextButton(optionsWindow, grid.getFieldSlot(), STR_REMOVE_SCREEN); - button->setPressHandler([=]() { + button->setPressHandler([=]() -> uint8_t { // if (pageIndex < MAX_CUSTOM_SCREENS - 1) { // memmove(&g_model.screenData[pageIndex], &g_model.screenData[pageIndex + 1], sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - pageIndex - 1)); // } diff --git a/radio/src/gui/colorlcd/widget_settings.cpp b/radio/src/gui/colorlcd/widget_settings.cpp index caf862712..d571f4bb2 100644 --- a/radio/src/gui/colorlcd/widget_settings.cpp +++ b/radio/src/gui/colorlcd/widget_settings.cpp @@ -28,10 +28,11 @@ static const rect_t widgetSettingsDialogRect = { LCD_H - 2 * LCD_H / 4 // height }; -WidgetSettings::WidgetSettings(Window * parent, Widget * widget, std::function confirmHandler) : - Dialog(parent, TR_WIDGET_SETTINGS, widgetSettingsDialogRect), - confirmHandler(std::move(confirmHandler)) +WidgetSettings::WidgetSettings(Window * parent, Widget * widget) : + Dialog(parent, TR_WIDGET_SETTINGS, widgetSettingsDialogRect) { + setCloseWhenClickOutside(true); + auto form = &content->form; FormGridLayout grid(content->form.width()); grid.setLabelWidth(width() / 5); @@ -134,3 +135,15 @@ WidgetSettings::WidgetSettings(Window * parent, Widget * widget, std::function confirmHandler; public: - WidgetSettings(Window * parent, Widget * widget, std::function confirmHandler); + WidgetSettings(Window * parent, Widget * widget); + +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override; +#endif }; From 7c5028cd36fcc629a6198d1218d2a5153d53f54d Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 5 Apr 2021 10:12:49 +0200 Subject: [PATCH 16/17] Fix source + Cosmetics --- radio/src/gui/colorlcd/widget_settings.cpp | 27 ++++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/radio/src/gui/colorlcd/widget_settings.cpp b/radio/src/gui/colorlcd/widget_settings.cpp index d571f4bb2..510769b3d 100644 --- a/radio/src/gui/colorlcd/widget_settings.cpp +++ b/radio/src/gui/colorlcd/widget_settings.cpp @@ -35,7 +35,7 @@ WidgetSettings::WidgetSettings(Window * parent, Widget * widget) : auto form = &content->form; FormGridLayout grid(content->form.width()); - grid.setLabelWidth(width() / 5); + grid.setLabelWidth(width() / 3); form->clear(); uint8_t optIdx = 0; @@ -49,35 +49,31 @@ WidgetSettings::WidgetSettings(Window * parent, Widget * widget) : switch (option.type) { case ZoneOption::Integer: - new NumberEdit(form, grid.getFieldSlot(), - option.min.signedValue, // Minimum - option.max.signedValue, // Maximum - [=]() -> int { // getValue + new NumberEdit(form, grid.getFieldSlot(), option.min.signedValue, option.max.signedValue, + [=]() -> int { return widget->getOptionValue(optIdx)->signedValue; }, - [=](int32_t newValue) { // setValue + [=](int32_t newValue) { widget->setOptionValue(optIdx, OPTION_VALUE_SIGNED(newValue)); }); break; case ZoneOption::Source: - new SourceChoice(form, grid.getFieldSlot(), - option.min.unsignedValue, // min - option.max.unsignedValue, // max - [=]() -> int16_t { // getValue + new SourceChoice(form, grid.getFieldSlot(), 0, MIXSRC_LAST_TELEM, + [=]() -> int16_t { return (int16_t) widget->getOptionValue(optIdx)->unsignedValue; }, - [=](int16_t newValue) { // setValue + [=](int16_t newValue) { widget->setOptionValue(optIdx, OPTION_VALUE_UNSIGNED((uint32_t) newValue)); }); break; case ZoneOption::Bool: new CheckBox(form, grid.getFieldSlot(), - [=]() -> uint8_t { // getValue + [=]() -> uint8_t { return (uint8_t) widget->getOptionValue(optIdx)->boolValue; }, - [=](int8_t newValue) { // setValue + [=](int8_t newValue) { widget->setOptionValue(optIdx, OPTION_VALUE_BOOL((uint32_t) newValue)); }); break; @@ -93,8 +89,7 @@ WidgetSettings::WidgetSettings(Window * parent, Widget * widget) : case ZoneOption::Timer: // Unsigned { - auto tmChoice = new Choice(form, grid.getFieldSlot(), - 0, TIMERS - 1, + auto tmChoice = new Choice(form, grid.getFieldSlot(), 0, TIMERS - 1, [=]() -> int { // getValue return (int) widget->getOptionValue(optIdx)->unsignedValue; }, @@ -138,6 +133,7 @@ WidgetSettings::WidgetSettings(Window * parent, Widget * widget) : #if defined(HARDWARE_KEYS) + void WidgetSettings::onEvent(event_t event) { TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); @@ -146,4 +142,5 @@ void WidgetSettings::onEvent(event_t event) deleteLater(); } } + #endif From 18ec048dd017f477d4d3b99722c46ad593476ccd Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 5 Apr 2021 10:20:18 +0200 Subject: [PATCH 17/17] clean-up --- radio/src/gui/colorlcd/tabsgroup.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/radio/src/gui/colorlcd/tabsgroup.h b/radio/src/gui/colorlcd/tabsgroup.h index 9092d4932..ba49076de 100644 --- a/radio/src/gui/colorlcd/tabsgroup.h +++ b/radio/src/gui/colorlcd/tabsgroup.h @@ -32,8 +32,7 @@ class PageTab { friend class TabsGroup; public: - PageTab(): - icon(0) + PageTab() { } @@ -81,7 +80,7 @@ class PageTab { protected: std::string title; - unsigned icon; + unsigned icon = 0; std::function onPageDestroyed; };