From 5a420c381abb1cc926481d33c88206e01c239292 Mon Sep 17 00:00:00 2001 From: KlausMu Date: Sun, 21 Apr 2024 17:53:28 +0200 Subject: [PATCH] reorganized deletion and creation of tabs --- .../ESP32/preferencesStorage_hal_esp32.cpp | 39 +- .../ESP32/preferencesStorage_hal_esp32.h | 10 +- .../preferencesStorage_hal_windows_linux.cpp | 57 ++- .../preferencesStorage_hal_windows_linux.h | 10 +- .../src/applicationInternal/gui/guiBase.cpp | 55 ++- .../src/applicationInternal/gui/guiBase.h | 5 +- .../gui/guiMemoryOptimizer.cpp | 440 ++++++++++-------- .../gui/guiMemoryOptimizer.h | 26 +- .../hardware/hardwarePresenter.cpp | 22 +- .../hardware/hardwarePresenter.h | 10 +- Platformio/src/applicationInternal/keys.cpp | 17 +- .../scenes/sceneHandler.cpp | 48 +- .../applicationInternal/scenes/sceneHandler.h | 2 +- .../scenes/sceneRegistry.cpp | 60 +-- .../scenes/sceneRegistry.h | 4 +- Platformio/src/guis/gui_numpad.cpp | 4 +- Platformio/src/main.cpp | 2 +- 17 files changed, 469 insertions(+), 342 deletions(-) diff --git a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp index 6666e4b..2577482 100644 --- a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp +++ b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp @@ -4,8 +4,9 @@ Preferences preferences; -std::string currentScene; -std::string currentGUIname; +std::string activeScene; +std::string activeGUIname; +int activeGUIlist; void init_preferences_HAL(void) { // Restore settings from internal flash memory @@ -17,10 +18,11 @@ void init_preferences_HAL(void) { // from tft.h set_backlightBrightness_HAL(preferences.getUChar("blBrightness")); // from here - currentScene = std::string(preferences.getString("currentScene").c_str()); - currentGUIname = std::string(preferences.getString("currentGUIname").c_str()); + activeScene = std::string(preferences.getString("currentScene").c_str()); + activeGUIname = std::string(preferences.getString("currentGUIname").c_str()); + activeGUIlist =(preferences.getInt("currentGUIlist")); - // Serial.printf("Preferences restored: brightness %d, GUI %s, scene %s\r\n", get_backlightBrightness_HAL(), get_currentGUIname().c_str(), get_currentScene().c_str()); + // Serial.printf("Preferences restored: brightness %d, GUI %s, scene %s\r\n", get_backlightBrightness_HAL(), get_activeGUIname().c_str(), get_activeScene().c_str()); } else { // Serial.printf("No preferences to restore\r\n"); } @@ -35,23 +37,30 @@ void save_preferences_HAL(void) { preferences.putUInt("slpTimeout", get_sleepTimeout_HAL()); preferences.putUChar("blBrightness", get_backlightBrightness_HAL()); // from here - preferences.putString("currentScene", currentScene.c_str()); - preferences.putString("currentGUIname", currentGUIname.c_str()); + preferences.putString("currentScene", activeScene.c_str()); + preferences.putString("currentGUIname", activeGUIname.c_str()); + preferences.putInt("currentGUIlist", activeGUIlist); if (!preferences.getBool("alreadySetUp")) { preferences.putBool("alreadySetUp", true); } preferences.end(); } -std::string get_currentScene_HAL() { - return currentScene; +std::string get_activeScene_HAL() { + return activeScene; } -void set_currentScene_HAL(std::string aCurrentScene) { - currentScene = aCurrentScene; +void set_activeScene_HAL(std::string anActiveScene) { + activeScene = anActiveScene; } -std::string get_currentGUIname_HAL(){ - return currentGUIname; +std::string get_activeGUIname_HAL(){ + return activeGUIname; } -void set_currentGUIname_HAL(std::string aCurrentGUIname) { - currentGUIname = aCurrentGUIname; +void set_activeGUIname_HAL(std::string anActiveGUIname) { + activeGUIname = anActiveGUIname; +} +int get_activeGUIlist_HAL() { + return activeGUIlist; +} +void set_activeGUIlist_HAL(int anActiveGUIlist) { + activeGUIlist = anActiveGUIlist; } diff --git a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h index f94f0f4..9f4d98e 100644 --- a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h +++ b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h @@ -5,7 +5,9 @@ void init_preferences_HAL(void); void save_preferences_HAL(void); -std::string get_currentScene_HAL(); -void set_currentScene_HAL(std::string aCurrentScene); -std::string get_currentGUIname_HAL(); -void set_currentGUIname_HAL(std::string aCurrentGUIname); +std::string get_activeScene_HAL(); +void set_activeScene_HAL(std::string anActiveScene); +std::string get_activeGUIname_HAL(); +void set_activeGUIname_HAL(std::string anActiveGUIname); +int get_activeGUIlist_HAL(); +void set_activeGUIlist_HAL(int anActiveGUIlist); diff --git a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp index af5d257..5d45c89 100644 --- a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp +++ b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp @@ -1,31 +1,50 @@ #include -std::string currentScene; -std::string currentGUIname; +enum GUIlists { +// MAIN_GUI_LIST: we are in the main_gui_list (with the scene selector as first gui), either if a scene is active or not +// SCENE_GUI_LIST: a scene is active and we are not in the main_gui_list. In that case, we try to use the scene specific gui list, if the scene defined one. + MAIN_GUI_LIST, + SCENE_GUI_LIST +}; + +/* +Possible example: +main_gui_list : "Scene selection", "Smart Home", "Settings", "IR Receiver"}; + +"Off" : +"TV" : "Numpad" +"Fire TV" : "Numpad", "Settings" +"Chromecast" : +"Apple TV" : "Apple TV", "Settings", "IR Receiver" +*/ +std::string activeScene; +std::string activeGUIname; +int activeGUIlist; void init_preferences_HAL(void) { + // set some values for tests + activeScene = ""; // "Off", "TV", "Fire TV", "Chromecast", "Apple TV"; + activeGUIname = ""; // "Scene selection", "Smart Home", "Settings", "IR Receiver" // "Numpad", "Apple TV" + activeGUIlist = MAIN_GUI_LIST; // // MAIN_GUI_LIST, SCENE_GUI_LIST; } void save_preferences_HAL(void) { } -std::string get_currentScene_HAL() { - // if (currentScene == "") { - // // set here something if you need it for a test at startup - // return "Apple TV"; - // } else - {return currentScene;} - +std::string get_activeScene_HAL() { + return activeScene; } -void set_currentScene_HAL(std::string aCurrentScene) { - currentScene = aCurrentScene; +void set_activeScene_HAL(std::string anActiveScene) { + activeScene = anActiveScene; } -std::string get_currentGUIname_HAL(){ - // if (currentGUIname == "") { - // // set here something if you need it for a test at startup - // return "IR Receiver"; // "Numpad"; // "Apple TV"; - // } else - {return currentGUIname;} +std::string get_activeGUIname_HAL(){ + return activeGUIname; } -void set_currentGUIname_HAL(std::string aCurrentGUIname) { - currentGUIname = aCurrentGUIname; +void set_activeGUIname_HAL(std::string anActiveGUIname) { + activeGUIname = anActiveGUIname; +} +int get_activeGUIlist_HAL() { + return activeGUIlist; +} +void set_activeGUIlist_HAL(int anActiveGUIlist) { + activeGUIlist = anActiveGUIlist; } diff --git a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h index f94f0f4..9f4d98e 100644 --- a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h +++ b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h @@ -5,7 +5,9 @@ void init_preferences_HAL(void); void save_preferences_HAL(void); -std::string get_currentScene_HAL(); -void set_currentScene_HAL(std::string aCurrentScene); -std::string get_currentGUIname_HAL(); -void set_currentGUIname_HAL(std::string aCurrentGUIname); +std::string get_activeScene_HAL(); +void set_activeScene_HAL(std::string anActiveScene); +std::string get_activeGUIname_HAL(); +void set_activeGUIname_HAL(std::string anActiveGUIname); +int get_activeGUIlist_HAL(); +void set_activeGUIlist_HAL(int anActiveGUIlist); diff --git a/Platformio/src/applicationInternal/gui/guiBase.cpp b/Platformio/src/applicationInternal/gui/guiBase.cpp index b96d232..c8e9f86 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.cpp +++ b/Platformio/src/applicationInternal/gui/guiBase.cpp @@ -13,8 +13,6 @@ lv_obj_t* BluetoothLabel = NULL; lv_obj_t* BattPercentageLabel = NULL; lv_obj_t* BattIconLabel = NULL; lv_obj_t* SceneLabel = NULL; -uint32_t currentTabID = -1; // id of the current tab -uint32_t oldTabID = -1; lv_obj_t* tabview = NULL; // page indicator @@ -28,8 +26,8 @@ lv_style_t panel_style; lv_style_t style_red_border; #endif -void guis_doTabCreationAtStartup(); -void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList); +void guis_doTabCreationOnStartup(); +void guis_doTabCreationAfterSliding(int newTabID); // Helper Functions ----------------------------------------------------------------------------------------------------------------------- @@ -87,28 +85,28 @@ void tabview_content_is_scrolling_event_cb(lv_event_t* e){ // ----------------------- static bool waitBeforeActionAfterSlidingAnimationEnded = false; static unsigned long waitBeforeActionAfterSlidingAnimationEnded_timerStart; +static int newTabID_forLateTabCreation; // This is the callback when the animation of the tab sliding ended static void tabview_animation_ready_cb(lv_anim_t* a) { // Unfortunately, the animation has not completely ended here. We cannot do the recreation of the tabs here. // We have to wait some more milliseconds or at least one cycle of lv_timer_handler(); // calling lv_timer_handler(); here does not help // lv_timer_handler(); - // guis_doAfterSliding(oldTabID, currentTabID, false); + // guis_doTabCreationAfterSliding(newTabID_forLateTabCreation); waitBeforeActionAfterSlidingAnimationEnded = true; waitBeforeActionAfterSlidingAnimationEnded_timerStart = millis(); } -// Update currentTabID when a new tab is selected +// Update gui when a new tab is selected // this is a callback if the tabview is changed (LV_EVENT_VALUE_CHANGED) // Sent when a new tab is selected by sliding or clicking the tab button. lv_tabview_get_tab_act(tabview) returns the zero based index of the current tab. void tabview_tab_changed_event_cb(lv_event_t* e) { if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) { - oldTabID = currentTabID; - currentTabID = lv_tabview_get_tab_act(lv_event_get_target(e)); + int newTabID = lv_tabview_get_tab_active((lv_obj_t*)lv_event_get_target(e)); - // Wait until the animation ended, then call "guis_doAfterSliding(oldTabID, currentTabID, false);" + // Wait until the animation ended, then call "guis_doTabCreationAfterSliding(newTabID);" // https://forum.lvgl.io/t/delete-a-tab-after-the-tabview-scroll-animation-is-complete/3155/4 lv_obj_t* myTabview = lv_event_get_target(e); lv_obj_t* tabContainer = lv_tabview_get_content(myTabview); @@ -116,11 +114,12 @@ void tabview_tab_changed_event_cb(lv_event_t* e) { if(anim) { // Swipe is not yet complete. User released the touch screen, an animation will bring it to the end. // That's the normal (and only?) case for the tft touchscreen + newTabID_forLateTabCreation = newTabID; lv_anim_set_ready_cb(anim, tabview_animation_ready_cb); } else { // Swipe is complete, no additional animation is needed. Most likely only possible in simulator Serial.println("Change of tab detected, without animation at the end. Will directly do my job after sliding."); - guis_doAfterSliding(oldTabID, currentTabID, false); + guis_doTabCreationAfterSliding(newTabID); } } } @@ -154,8 +153,8 @@ void init_gui(void) { lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), LV_PART_MAIN); // set default height and position of main widgets setMainWidgetsHeightAndPosition(); - // At startup, set current GUI according to get_currentGUIname(), and create the content of that tab (and the previous and the next) for the first time - guis_doTabCreationAtStartup(); + // On startup, set current GUIname and GUIlist according to last state before going to sleep + guis_doTabCreationOnStartup(); // memoryUsage bar init_gui_memoryUsage_bar(); // status bar @@ -288,12 +287,12 @@ void gui_loop(void) { waitBeforeActionAfterSlidingAnimationEnded = false; } else if (waitOneLoop) { waitOneLoop = false; - guis_doAfterSliding(oldTabID, currentTabID, false); + guis_doTabCreationAfterSliding(newTabID_forLateTabCreation); }; // // as alternative, we could wait some milliseconds. But one cycle of gui_loop() works well. // if (waitBeforeActionAfterSlidingAnimationEnded) { // if (millis() - waitBeforeActionAfterSlidingAnimationEnded_timerStart >= 5) { - // guis_doAfterSliding(oldTabID, currentTabID, false); + // guis_doTabCreationAfterSliding(newTabID_forLateTabCreation); // waitBeforeActionAfterSlidingAnimationEnded = false; // } // } @@ -301,19 +300,25 @@ void gui_loop(void) { lv_timer_handler(); } -void guis_doTabCreationAtStartup() { - gui_memoryOptimizer_prepare_startup(); - - guis_doAfterSliding(-1, -1, false); -} - -void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList) { - // With parameter newGuiList it is signaled that we are changing from a scene specific list to the main list or vice versa - // In that case, we have to do special treatment because we are not simply sliding to the left or to the right, but we start newly with a different gui list. - gui_memoryOptimizer_doAfterSliding_deletionAndCreation(&tabview, oldTabID, newTabID, newGuiList, &panel, &img1, &img2); - +// ------------------------------------------------------------------------------------------------------------ +// There are several reasons why the tabs could get recreated. All are going through these functions in "guiBase.cpp", which are calling functions in "guiMemoryOptimizer.cpp" +// 1. tab creation on startup (called by init_gui()) +void guis_doTabCreationOnStartup() { + Serial.printf("Startup: try to resume at scene \"%s\" with GUI \"%s\"\r\n", gui_memoryOptimizer_getActiveSceneName().c_str(), gui_memoryOptimizer_getActiveGUIname().c_str()); + gui_memoryOptimizer_onStartup(&tabview, &panel, &img1, &img2); doLogMemoryUsage(); } +// 2. tab creation after sliding (called by tabview_tab_changed_event_cb()) +void guis_doTabCreationAfterSliding(int newTabID) { + gui_memoryOptimizer_afterSliding(&tabview, &panel, &img1, &img2, newTabID); + doLogMemoryUsage(); +} +// 3. after gui list has changed (called by handleScene()), when switching between main_gui_list and scene specific list +void guis_doTabCreationAfterGUIlistChanged(GUIlists newGUIlist) { + gui_memoryOptimizer_afterGUIlistChanged(&tabview, &panel, &img1, &img2, newGUIlist); + doLogMemoryUsage(); +} +// ------------------------------------------------------------------------------------------------------------ void setActiveTab(uint32_t index, lv_anim_enable_t anim_en, bool send_tab_changed_event) { // unsigned long startTime = millis(); diff --git a/Platformio/src/applicationInternal/gui/guiBase.h b/Platformio/src/applicationInternal/gui/guiBase.h index eb7ceab..2a8c2a0 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.h +++ b/Platformio/src/applicationInternal/gui/guiBase.h @@ -1,6 +1,7 @@ #pragma once #include +#include "applicationInternal/gui/guiMemoryOptimizer.h" // used by memoryUsage.cpp extern lv_obj_t* MemoryUsageLabel; @@ -15,7 +16,6 @@ extern lv_style_t panel_style; extern int tabviewTop; extern int tabviewHeight; extern int panelHeight; -extern uint32_t currentTabID; // used by almost all gui_*.cpp extern lv_color_t color_primary; @@ -32,10 +32,9 @@ void tabview_content_is_scrolling_event_cb(lv_event_t* e); void tabview_tab_changed_event_cb(lv_event_t* e); void sceneLabel_or_pageIndicator_event_cb(lv_event_t* e); void pageIndicator_navigate_event_cb(lv_event_t* e); +void guis_doTabCreationAfterGUIlistChanged(GUIlists newGUIlist); void setActiveTab(uint32_t index, lv_anim_enable_t anim_en, bool send_tab_changed_event = false); // used by memoryUsage.cpp void showMemoryUsageBar(bool showBar); // used by commandHandler to show WiFi status void showWiFiConnected(bool connected); - -void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList); diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp index 8c03a70..e3a1643 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp @@ -1,47 +1,90 @@ #include #include "applicationInternal/gui/guiBase.h" +#include "applicationInternal/gui/guiMemoryOptimizer.h" #include "applicationInternal/gui/guiRegistry.h" -#include "applicationInternal/scenes/sceneRegistry.h" #include "applicationInternal/hardware/hardwarePresenter.h" +#include "applicationInternal/scenes/sceneRegistry.h" -struct tab_in_memory { +struct t_gui_on_tab { lv_obj_t* tab; - int listIndex; - std::string guiName; + std::string GUIname; + int gui_list_index; + int gui_list_index_previous; }; -tab_in_memory tabs_in_memory[3] = {{NULL, -1, ""}, {NULL, -1, ""}, {NULL, -1, ""}}; -// holds the ids of the tabs we had in memory before, so that we can determine the next or previous id -int tabs_in_memory_previous_listIndex[3]= {-1 , -1, -1}; +struct t_gui_state { + // the next three are saved in the preferenceStorage every time they change + std::string activeScene_internalDontUse; + std::string activeGUIname_internalDontUse; + GUIlists activeGUIlist_internalDontUse; + // --- + int activeTabID = -1; // id of the active tab (one of 0,1,2) + int oldTabID = -1; // id of the tab before swiping (one of 0,1,2) + t_gui_on_tab gui_on_tab[3] = {{NULL, "", -1, -1}, {NULL, "", -1, -1}, {NULL, "", -1, -1}}; +}; +t_gui_state gui_state; + +// Both the gui_state and the preferenceStorage should know at any time the current state (scene, GUIname, and GUIlist) +// preferenceStorage should know it because when going to sleep, it should persist the state in NVM. +// So whenever values change, it should be done through these functions. +// On startup, the gui_state is set by gui_memoryOptimizer_onStartup() +std::string gui_memoryOptimizer_getActiveSceneName() { + gui_state.activeScene_internalDontUse = get_activeScene(); + return gui_state.activeScene_internalDontUse; +} +void gui_memoryOptimizer_setActiveSceneName(std::string aSceneName) { + gui_state.activeScene_internalDontUse = aSceneName; + set_activeScene(aSceneName); +} +std::string gui_memoryOptimizer_getActiveGUIname() { + gui_state.activeGUIname_internalDontUse = get_activeGUIname(); + return gui_state.activeGUIname_internalDontUse; +} +void gui_memoryOptimizer_setActiveGUIname(std::string aGUIname) { + gui_state.activeGUIname_internalDontUse = aGUIname; + set_activeGUIname(aGUIname); +} +GUIlists gui_memoryOptimizer_getActiveGUIlist() { + gui_state.activeGUIlist_internalDontUse = (GUIlists)get_activeGUIlist(); + return gui_state.activeGUIlist_internalDontUse; +} +void gui_memoryOptimizer_setActiveGUIlist(GUIlists aGUIlist) { + gui_state.activeGUIlist_internalDontUse = aGUIlist; + set_activeGUIlist(aGUIlist); +} + +int gui_memoryOptimizer_getActiveTabID() { + return gui_state.activeTabID; +} bool gui_memoryOptimizer_isTabIDInMemory(int tabID) { // range check if ((tabID < 0) || (tabID >= 3)) { return false; } - return (tabs_in_memory[tabID].listIndex != -1); + return (gui_state.gui_on_tab[tabID].gui_list_index != -1); } -bool gui_memoryOptimizer_isGUInameInMemory(std::string guiName) { +bool gui_memoryOptimizer_isGUInameInMemory(std::string GUIname) { for (uint8_t index=0; index <= 2; index++) { - if (tabs_in_memory[index].guiName == guiName) { + if (gui_state.gui_on_tab[index].GUIname == GUIname) { return true; } } return false; } -void notify_active_tabs_before_delete() { +void notify_active_tabs_before_delete(t_gui_state *gui_state) { Serial.printf(" Will notify tabs about deletion\r\n"); std::string nameOfTab; for (int index=0; index <= 2; index++) { - if (tabs_in_memory[index].listIndex == -1) { + if (gui_state->gui_on_tab[index].gui_list_index == -1) { Serial.printf(" Will not notify tab %d about deletion because it does not exist\r\n", index); continue; } - // For deletion, do not use the listIndex, but the name of the gui. + // For deletion, do not use the gui_list_index, but the name of the gui. // The gui_list might have changed (when switching from a scene specific list to the main list or vice versa), so index could have changed as well. - nameOfTab = tabs_in_memory[index].guiName; + nameOfTab = gui_state->gui_on_tab[index].GUIname; if (nameOfTab == "") { Serial.printf(" Will not notify tab %d about deletion because it is not set\r\n", index); } else if (registered_guis_byName_map.count(nameOfTab) == 0) { @@ -53,7 +96,7 @@ void notify_active_tabs_before_delete() { } } -void clear_tabview(lv_obj_t* tabview) { +void clear_tabview(lv_obj_t* tabview, t_gui_state *gui_state) { if (tabview != NULL) { // first remove events for the tabview lv_obj_remove_event_cb(tabview, tabview_tab_changed_event_cb); @@ -63,10 +106,10 @@ void clear_tabview(lv_obj_t* tabview) { tabview = NULL; } - // set struct tabs_in_memory to NULL - tabs_in_memory[0] = {NULL, -1, ""}; - tabs_in_memory[1] = {NULL, -1, ""}; - tabs_in_memory[2] = {NULL, -1, ""}; + // the gui_list_index_previous is needed for setGUIlistIndicesToBeShown_afterSlide(); + gui_state->gui_on_tab[0] = {NULL, "", -1, gui_state->gui_on_tab[0].gui_list_index}; + gui_state->gui_on_tab[1] = {NULL, "", -1, gui_state->gui_on_tab[1].gui_list_index}; + gui_state->gui_on_tab[2] = {NULL, "", -1, gui_state->gui_on_tab[2].gui_list_index}; } @@ -114,162 +157,161 @@ lv_obj_t* create_panel() { std::string get_name_of_gui_to_be_shown(int index) { if (index == -1) { return ""; - } else if (index <= get_gui_list(get_currentScene())->size() -1) { - return get_gui_list(get_currentScene())->at(index); + } else if (index <= get_gui_list_active()->size() -1) { + return get_gui_list_active()->at(index); } else { return ""; } } -void create_new_tab(lv_obj_t* tabview, uint32_t tabs_in_memory_index) { - std::string nameOfTab = get_name_of_gui_to_be_shown(tabs_in_memory[tabs_in_memory_index].listIndex); +void create_new_tab(lv_obj_t* tabview, t_gui_on_tab *gui_on_tab) { + std::string nameOfTab = get_name_of_gui_to_be_shown(gui_on_tab->gui_list_index); if (nameOfTab == "") { - Serial.printf(" Will not create new tab at index %d because no name was provided\r\n", tabs_in_memory_index); + Serial.printf(" Will not create new tab because no name was provided\r\n"); } else if (registered_guis_byName_map.count(nameOfTab) == 0) { - Serial.printf(" Will not create new tab at index %d because name %s was not found in registry\r\n", tabs_in_memory_index, nameOfTab.c_str()); + Serial.printf(" Will not create new tab because name %s was not found in registry\r\n", nameOfTab.c_str()); } else { - Serial.printf(" Will create tab with name \"%s\" at index %d\r\n", nameOfTab.c_str(), tabs_in_memory_index); + Serial.printf(" Will create tab with name \"%s\" \r\n", nameOfTab.c_str()); // save name of tab for deletion later - tabs_in_memory[tabs_in_memory_index].guiName = nameOfTab; - // create tab and save pointer to tab in tabs_in_memory - tabs_in_memory[tabs_in_memory_index].tab = lv_tabview_add_tab(tabview, nameOfTab.c_str()); + gui_on_tab->GUIname = nameOfTab; + // create tab and save pointer to tab in gui_on_tab + gui_on_tab->tab = lv_tabview_add_tab(tabview, nameOfTab.c_str()); // let the gui create it's content - registered_guis_byName_map.at(nameOfTab).this_create_tab_content(tabs_in_memory[tabs_in_memory_index].tab); + registered_guis_byName_map.at(nameOfTab).this_create_tab_content(gui_on_tab->tab); } } -void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t newTabID) { - // create up to three tabs and the content of the tabs - /* - example: gui_list: 0 1 2 3 4 - in memory active - 0 1 -1 0 <- first state, special case - also the initial state - 0 1 2 1 - 1 2 3 1 - 2 3 4 1 - 3 4 -1 1 <- last state, special case - */ +// create up to three tabs and the content of the tabs +/* +example: gui_list: 0 1 2 3 4 +in memory active +0 1 -1 0 <- first state, special case - also the initial state +0 1 2 1 +1 2 3 1 +2 3 4 1 +3 4 -1 1 <- last state, special case +*/ +void setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(int gui_list_index, t_gui_state *gui_state) { + // Set the gui_list_indeces to be shown for a specific gui_list_index + if (gui_list_index == 0) { + // first state + Serial.printf(" GUIlistIndices: will resume at specific index with \"first state\"\r\n"); + gui_state->gui_on_tab[0] = {NULL, "", 0}; + // take care if there is only one gui in list + gui_state->gui_on_tab[1] = {NULL, "", get_gui_list_active()->size() >= 2 ? 1 : -1}; + gui_state->gui_on_tab[2] = {NULL, "", -1}; + gui_state->activeTabID = 0; + } else if (gui_list_index == get_gui_list_active()->size() -1) { + // last state + Serial.printf(" GUIlistIndices: will resume at specific index with \"last state\"\r\n"); + gui_state->gui_on_tab[0] = {NULL, "", gui_list_index -1}; + gui_state->gui_on_tab[1] = {NULL, "", gui_list_index}; + gui_state->gui_on_tab[2] = {NULL, "", -1}; + gui_state->activeTabID = 1; + } else { + // any other state + Serial.printf(" GUIlistIndices: will resume at specific index with \"state between\"\r\n"); + gui_state->gui_on_tab[0] = {NULL, "", gui_list_index -1}; + gui_state->gui_on_tab[1] = {NULL, "", gui_list_index}; + gui_state->gui_on_tab[2] = {NULL, "", gui_list_index +1}; + gui_state->activeTabID = 1; + } +} - int tabToBeActivated = -1; +void setGUIlistIndicesToBeShown_forFirstGUIinGUIlist(t_gui_state *gui_state) { + Serial.printf(" GUIlistIndices: will show the first gui from \"gui_list\" as initial state\r\n"); + // take care if there is no gui in list + gui_state->gui_on_tab[0] = {NULL, "", get_gui_list_active()->size() != 0 ? 0 : -1}; + // take care if there is only one gui in list + gui_state->gui_on_tab[1] = {NULL, "", get_gui_list_active()->size() >= 2 ? 1 : -1}; + gui_state->gui_on_tab[2] = {NULL, "", -1}; + gui_state->activeTabID = 0; +} + +void setGUIlistIndicesToBeShown_afterSlide(t_gui_state *gui_state) { int oldListIndex = -1; - - if ((oldTabID == -1) && (newTabID == -1)) { - // This is the initialization after the ESP32 has booted. - - if ((tabs_in_memory_previous_listIndex[0] < get_gui_list(get_currentScene())->size()) && (tabs_in_memory_previous_listIndex[0] != -1)) { - // In gui_memoryOptimizer_prepare_startup, the index of get_currentGUIname() in gui_list was saved, if found. - // We can resume at this old state. - oldListIndex = tabs_in_memory_previous_listIndex[0] ; - if (oldListIndex == 0) { - // first state - Serial.printf(" Startup: will resume where we went to sleep with \"first state\"\r\n"); - tabs_in_memory[0] = {NULL, 0}; - // take care if there is only one gui in list - tabs_in_memory[1] = {NULL, get_gui_list(get_currentScene())->size() >= 2 ? 1 : -1}; - tabs_in_memory[2] = {NULL, -1}; - tabToBeActivated = 0; - } else if (oldListIndex == get_gui_list(get_currentScene())->size() -1) { - // last state - Serial.printf(" Startup: will resume where we went to sleep with \"last state\"\r\n"); - tabs_in_memory[0] = {NULL, oldListIndex -1}; - tabs_in_memory[1] = {NULL, oldListIndex}; - tabs_in_memory[2] = {NULL, -1}; - tabToBeActivated = 1; - } else { - // any other state - Serial.printf(" Startup: will resume where we went to sleep with \"state between\"\r\n"); - tabs_in_memory[0] = {NULL, oldListIndex -1}; - tabs_in_memory[1] = {NULL, oldListIndex}; - tabs_in_memory[2] = {NULL, oldListIndex +1}; - tabToBeActivated = 1; - } - } else { - Serial.printf(" Startup: cannot resume old state, so we will show the first tabs from \"gui_list\" as initial state\r\n"); - // take care if there is no gui in list - tabs_in_memory[0] = {NULL, get_gui_list(get_currentScene())->size() != 0 ? 0 : -1}; - // take care if there is only one gui in list - tabs_in_memory[1] = {NULL, get_gui_list(get_currentScene())->size() >= 2 ? 1 : -1}; - tabs_in_memory[2] = {NULL, -1}; - tabToBeActivated = 0; - } - } else if (oldTabID > newTabID) { + + if (gui_state->oldTabID > gui_state->activeTabID) { // swipe to previous item in list Serial.printf(" Will swipe to previous item in list\r\n"); - oldListIndex = tabs_in_memory_previous_listIndex[1]; + oldListIndex = gui_state->gui_on_tab[1].gui_list_index_previous; if ((oldListIndex == 1)) { // next state is the "first state" - tabs_in_memory[0] = {NULL, 0}; - tabs_in_memory[1] = {NULL, 1}; - tabs_in_memory[2] = {NULL, -1}; - tabToBeActivated = 0; + gui_state->gui_on_tab[0] = {NULL, "", 0}; + gui_state->gui_on_tab[1] = {NULL, "", 1}; + gui_state->gui_on_tab[2] = {NULL, "", -1}; + gui_state->activeTabID = 0; } else { - tabs_in_memory[0] = {NULL, oldListIndex -2}; - tabs_in_memory[1] = {NULL, oldListIndex -1}; - tabs_in_memory[2] = {NULL, oldListIndex}; - tabToBeActivated = 1; + gui_state->gui_on_tab[0] = {NULL, "", oldListIndex -2}; + gui_state->gui_on_tab[1] = {NULL, "", oldListIndex -1}; + gui_state->gui_on_tab[2] = {NULL, "", oldListIndex}; + gui_state->activeTabID = 1; } } else { // swipe to next item in list Serial.printf(" Will swipe to next item in list\r\n"); - if (tabs_in_memory_previous_listIndex[2] == -1) { + if (gui_state->gui_on_tab[2].gui_list_index_previous == -1) { // last state was the first state - oldListIndex = tabs_in_memory_previous_listIndex[0]; // is always 0 + oldListIndex = gui_state->gui_on_tab[0].gui_list_index_previous; // is always 0 } else { - oldListIndex = tabs_in_memory_previous_listIndex[1]; + oldListIndex = gui_state->gui_on_tab[1].gui_list_index_previous; } - if (oldListIndex == get_gui_list(get_currentScene())->size() -2) { + if (oldListIndex == get_gui_list_active()->size() -2) { // next state is the "last state" - tabs_in_memory[0] = {NULL, oldListIndex}; - tabs_in_memory[1] = {NULL, oldListIndex +1}; - tabs_in_memory[2] = {NULL, -1}; - tabToBeActivated = 1; + gui_state->gui_on_tab[0] = {NULL, "", oldListIndex}; + gui_state->gui_on_tab[1] = {NULL, "", oldListIndex +1}; + gui_state->gui_on_tab[2] = {NULL, "", -1}; + gui_state->activeTabID = 1; } else { - tabs_in_memory[0] = {NULL, oldListIndex}; - tabs_in_memory[1] = {NULL, oldListIndex +1}; - tabs_in_memory[2] = {NULL, oldListIndex +2}; - tabToBeActivated = 1; + gui_state->gui_on_tab[0] = {NULL, "", oldListIndex}; + gui_state->gui_on_tab[1] = {NULL, "", oldListIndex +1}; + gui_state->gui_on_tab[2] = {NULL, "", oldListIndex +2}; + gui_state->activeTabID = 1; } } + +} +void doTabCreation_strategyMax3(lv_obj_t* tabview, t_gui_state *gui_state) { + // create the tabs - Serial.printf(" Will create tabs. List indices of the three tabs are %d, %d, %d, tab nr %d will be activated\r\n", tabs_in_memory[0].listIndex, tabs_in_memory[1].listIndex, tabs_in_memory[2].listIndex, tabToBeActivated); + Serial.printf(" Will create tabs. List indices of the three tabs are %d, %d, %d, tab nr %d will be activated\r\n", gui_state->gui_on_tab[0].gui_list_index, gui_state->gui_on_tab[1].gui_list_index, gui_state->gui_on_tab[2].gui_list_index, gui_state->activeTabID); for (int i=0; i<3; i++) { - create_new_tab(tabview, i); + create_new_tab(tabview, &gui_state->gui_on_tab[i]); } - if (get_gui_list(get_currentScene())->size() > 0) { - std::string nameOfNewActiveTab = get_gui_list(get_currentScene())->at(tabs_in_memory[tabToBeActivated].listIndex); + if (get_gui_list_active()->size() > 0) { + std::string nameOfNewActiveTab = get_gui_list_active()->at(gui_state->gui_on_tab[gui_state->activeTabID].gui_list_index); Serial.printf(" New visible tab is \"%s\"\r\n", nameOfNewActiveTab.c_str()); - // set the tab we swiped to as active - setActiveTab(tabToBeActivated, LV_ANIM_OFF); - set_currentGUIname(nameOfNewActiveTab); - currentTabID = tabToBeActivated; + // set active tab + setActiveTab(gui_state->activeTabID, LV_ANIM_OFF); + gui_memoryOptimizer_setActiveGUIname(nameOfNewActiveTab); } } LV_IMG_DECLARE(gradientLeft); LV_IMG_DECLARE(gradientRight); -void getBreadcrumpPosition(uint8_t* breadcrumpPosition, std::string nameOfTab) { +void getBreadcrumpPosition(uint8_t* breadcrumpPosition, std::string nameOfGUI) { *breadcrumpPosition = 0; - gui_list currentGUIlist = get_gui_list(get_currentScene()); + gui_list gui_list_active = get_gui_list_active(); uint8_t counter = 0; - for (std::vector::iterator it = currentGUIlist->begin() ; it != currentGUIlist->end(); ++it) { + for (std::vector::iterator it = gui_list_active->begin() ; it != gui_list_active->end(); ++it) { counter++; - if (*it == nameOfTab) { + if (*it == nameOfGUI) { *breadcrumpPosition = counter; return; } } } -void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv_obj_t* img2) { +void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv_obj_t* img2, t_gui_state *gui_state) { Serial.printf(" Will fill panel with page indicators\r\n"); - if (get_gui_list(get_currentScene())->size() == 0) { + if (get_gui_list_active()->size() == 0) { Serial.printf(" no tab available, so no page indicators\r\n"); // at least add the style lv_obj_add_style(panel, &panel_style, 0); @@ -301,33 +343,33 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv btn = lv_btn_create(panel); lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE); lv_obj_set_size(btn, 150, lv_pct(100)); - if (tabs_in_memory[0].listIndex == 0) { + if (gui_state->gui_on_tab[0].gui_list_index == 0) { lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN); } else { lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN); } - uint8_t breadcrumpLength = get_gui_list(get_currentScene())->size(); + uint8_t breadcrumpLength = get_gui_list_active()->size(); uint8_t breadcrumpDotSize = 8; // should be an even number uint8_t breadcrumpDotDistance = 2; // should be an even number int8_t breadcrumpStartPositionX = (-1) * (breadcrumpLength -1) * (breadcrumpDotSize + breadcrumpDotDistance) / 2; // create the panel content for the three guis (or less) which are currently in memory - std::string nameOfTab; + std::string nameOfGUI; uint8_t breadcrumpPosition; for (int i=0; i<3; i++) { - if (tabs_in_memory[i].listIndex != -1) { - nameOfTab = tabs_in_memory[i].guiName; - getBreadcrumpPosition(&breadcrumpPosition, nameOfTab); + if (gui_state->gui_on_tab[i].gui_list_index != -1) { + nameOfGUI = gui_state->gui_on_tab[i].GUIname; + getBreadcrumpPosition(&breadcrumpPosition, nameOfGUI); // Create actual buttons for every tab lv_obj_t* btn = lv_btn_create(panel); // only if this is the button for the currently active tab, make it clickable to get to scene selection gui - if (nameOfTab == get_currentGUIname()) { + if (nameOfGUI == gui_memoryOptimizer_getActiveGUIname()) { lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_event_cb(btn, sceneLabel_or_pageIndicator_event_cb, LV_EVENT_CLICKED, NULL); - } else if ((i==0 || i==1) && (tabs_in_memory[i+1].listIndex != -1)) { + } else if ((i==0 || i==1) && (gui_state->gui_on_tab[i+1].gui_list_index != -1)) { // this is the button on the previous tab, which can be seen on the active tab // activate click to prev tab lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE); @@ -367,7 +409,7 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv } lv_obj_t* label = lv_label_create(btn); lv_obj_set_style_text_font(label, &lv_font_montserrat_10, LV_PART_MAIN); - lv_label_set_text_fmt(label, "%s", nameOfTab.c_str()); + lv_label_set_text_fmt(label, "%s", nameOfGUI.c_str()); lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, 6); } @@ -377,8 +419,8 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv btn = lv_btn_create(panel); lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE); lv_obj_set_size(btn, 150, lv_pct(100)); - // 4 at last position 4 at middle position only one tab available overall - if ((tabs_in_memory[2].listIndex == get_gui_list(get_currentScene())->size()-1) || (tabs_in_memory[1].listIndex == get_gui_list(get_currentScene())->size()-1) || (tabs_in_memory[1].listIndex == -1)) { + // 4 at last position 4 at middle position only one tab available overall + if ((gui_state->gui_on_tab[2].gui_list_index == get_gui_list_active()->size()-1) || (gui_state->gui_on_tab[1].gui_list_index == get_gui_list_active()->size()-1) || (gui_state->gui_on_tab[1].gui_list_index == -1)) { lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN); } else { lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN); @@ -419,71 +461,76 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv } -void gui_memoryOptimizer_prepare_startup() { - // find index of get_currentGUIname() in gui_list - for (int i=0; isize(); i++) { - if (get_gui_list(get_currentScene())->at(i) == get_currentGUIname()) { - Serial.printf("Startup: found GUI with name \"%s\" in \"gui_list\" at position %d\r\n", get_currentGUIname().c_str(), i); - // save position so that "guis_doAfterSliding" can use it - tabs_in_memory[0].listIndex = i; - } - } +void gui_memoryOptimizer_notifyAndClear(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, t_gui_state *gui_state) { - // if the gui was not found in main_gui_list, try to find it in scene specific list - if (tabs_in_memory[0].listIndex == -1) { - useSceneGUIlist = true; - for (int i=0; isize(); i++) { - if (get_gui_list(get_currentScene())->at(i) == get_currentGUIname()) { - Serial.printf("Startup: found GUI with name \"%s\" in scene specific \"gui_list\" at position %d\r\n", get_currentGUIname().c_str(), i); - // save position so that "guis_doAfterSliding" can use it - tabs_in_memory[0].listIndex = i; - } - } - } - - // if the gui was still not found, reset useSceneGUIlist - if (tabs_in_memory[0].listIndex == -1) { - useSceneGUIlist = false; - } + // 1. notify old guis that they will be deleted so that they can persist their state if needed + notify_active_tabs_before_delete(gui_state); + // 2. clear current tabview and save gui_list_index_previous (needed for swipe) + clear_tabview(*tabview, gui_state); + // 3. clear current panel for page indicator + clear_panel(*panel, *img1, *img2); } -void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview, int oldTabID, int newTabID, bool newGuiList, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2) { +void gui_memoryOptimizer_doContentCreation(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, t_gui_state *gui_state); + +// find the position of the current GUI in the gui list which was active last (both were automatically saved in the preferences) +void gui_memoryOptimizer_onStartup(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2) { + + // Get last state from preferences and save it in gui_state + // So it is ok to call them without using the return values. + gui_memoryOptimizer_getActiveSceneName(); + gui_memoryOptimizer_getActiveGUIname(); + gui_memoryOptimizer_getActiveGUIlist(); + + // 1. find last used gui + int gui_list_index = -1; + // find index of gui_memoryOptimizer_getActiveGUIname() in gui_list_active + for (int i=0; isize(); i++) { + if (get_gui_list_active()->at(i) == gui_memoryOptimizer_getActiveGUIname()) { + Serial.printf("Startup: found GUI with name \"%s\" in \"gui_list_active\" at position %d\r\n", gui_memoryOptimizer_getActiveGUIname().c_str(), i); + gui_list_index = i; + break; + } + } + + // 2. set gui_list_indices and the tab to be activated + if ((gui_list_index >= 0) && (gui_list_index < get_gui_list_active()->size())) { + // gui was found + setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(gui_list_index, &gui_state); + + } else { + // gui was not found + Serial.printf("Startup: GUI with name \"%s\" was not found. Will start with first GUI of main_gui_list\r\n", gui_memoryOptimizer_getActiveGUIname().c_str()); + gui_memoryOptimizer_setActiveGUIlist(MAIN_GUI_LIST); + setGUIlistIndicesToBeShown_forFirstGUIinGUIlist(&gui_state); + + } + + // 3. create content + gui_memoryOptimizer_doContentCreation(tabview, panel, img1, img2, &gui_state); + +} + +void gui_memoryOptimizer_afterSliding(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, int newTabID) { + // Here the magic for dynamic creation and deletion of lvgl objects happens to keep memory usage low. // The next and previous tab must always be available in the tabview, because they can already been seen during the animation. // And you always need 3 tabs, otherwise you even could not slide to the next or previous tab. // So we always have 3 tabs. // After the animation, the tabview and hence all tabs are deleted and recreated. - // With parameter newGuiList it is signaled that we are changing from a scene specific list to the main list or vice versa - // In that case, we have to do special treatment because we are not simply sliding to the left or to the right, but we start newly with a different gui list. - // only called by guis_doTabCreationAtStartup(): - // oldTabID = -1, newTabID = -1, newGuiList = false - // called by handleScene() - // oldTabID = -1, newTabID = -1, newGuiList = true - Serial.printf("--- Start of tab deletion and creation\r\n"); - bool isInitialization = ((oldTabID == -1) && (newTabID == -1)); - if (isInitialization) { - Serial.printf("Startup: will initially create the tabs to be shown\r\n"); - } else { - Serial.printf("Changing from oldTabID %d \"%s\" to newTabID %d \"%s\"\r\n", - oldTabID, get_gui_list(get_currentScene())->at(tabs_in_memory[oldTabID].listIndex).c_str(), - newTabID, get_gui_list(get_currentScene())->at(tabs_in_memory[newTabID].listIndex).c_str()); - } + gui_state.oldTabID = gui_state.activeTabID; + gui_state.activeTabID = newTabID; - // Save the ids of the tabs we had in memory before. This is only used by doTabCreation_strategyMax3() to know where we come from and where we have to go to. - for (int i=0; i<3; i++) { - tabs_in_memory_previous_listIndex[i] = tabs_in_memory[i].listIndex; - } + Serial.printf("Changing from oldTabID %d \"%s\" to newTabID %d \"%s\"\r\n", + gui_state.oldTabID, gui_state.gui_on_tab[gui_state.oldTabID].GUIname.c_str(), + gui_state.activeTabID, gui_state.gui_on_tab[gui_state.activeTabID].GUIname.c_str()); - // the old tabs need to be notified that they will be deleted so that they can persist their state if needed - notify_active_tabs_before_delete(); - // clear current tabview - clear_tabview(*tabview); - // clear current panel for page indicator - clear_panel(*panel, *img1, *img2); + // 1. notify old guis and clear tabview and panel + gui_memoryOptimizer_notifyAndClear(tabview, panel, img1, img2, &gui_state); // only optional: delete and create the whole screen. Not necessary. // Only used for a test. init_gui_status_bar() would need to be called again at a suitable place, because the status bar would also be deleted. @@ -494,25 +541,44 @@ void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview, // lv_scr_load(newscr); // lv_obj_del(oldscr); - if (newGuiList) { - // If we are switching to a new gui list, then we need to set tabs_in_memory_previous_listIndex[0] = -1; - // Doing so, doTabCreation_strategyMax3() knows that we cannot resume an old state. - tabs_in_memory_previous_listIndex[0] = -1; - } + // 2. set gui_list_indices and the tab to be activated + setGUIlistIndicesToBeShown_afterSlide(&gui_state); + // 3. create content + gui_memoryOptimizer_doContentCreation(tabview, panel, img1, img2, &gui_state); +} + +void gui_memoryOptimizer_afterGUIlistChanged(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, GUIlists newGUIlist) { + + Serial.printf("--- Will change to new gui_list\r\n"); + + // 1. notify old guis and clear tabview and panel + gui_memoryOptimizer_notifyAndClear(tabview, panel, img1, img2, &gui_state); + + // 2. set gui_list_indices and the tab to be activated + gui_memoryOptimizer_setActiveGUIlist(newGUIlist); + setGUIlistIndicesToBeShown_forFirstGUIinGUIlist(&gui_state); + + // 3. create content + gui_memoryOptimizer_doContentCreation(tabview, panel, img1, img2, &gui_state); + +} + +void gui_memoryOptimizer_doContentCreation(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, t_gui_state *gui_state) { // recreate the tabview lv_obj_t* newTabview = create_tabview(); *tabview = newTabview; + // Create the tabs. Use strategy "3 tabs at maximum" to keep memory usage low. // Set the tab we swiped to as active - doTabCreation_strategyMax3(*tabview, oldTabID, newTabID); + doTabCreation_strategyMax3(*tabview, gui_state); // Create the panel for the page indicator. Panel itself takes about 2136 bytes for three tabs. lv_obj_t* newPanel = create_panel(); *panel = newPanel; *img1 = lv_img_create(lv_scr_act()); *img2 = lv_img_create(lv_scr_act()); - fillPanelWithPageIndicator_strategyMax3(*panel, *img1, *img2); + fillPanelWithPageIndicator_strategyMax3(*panel, *img1, *img2, gui_state); // now, as the correct tab is active, register again the events for the tabview lv_obj_add_event_cb(*tabview, tabview_tab_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL); diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h index 83a87c4..47ec812 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h @@ -1,6 +1,26 @@ #pragma once +#include +#include -void gui_memoryOptimizer_prepare_startup(); -void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview, int oldTabID, int newTabID, bool newGuiList, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2); +enum GUIlists { +// MAIN_GUI_LIST: we are in the main_gui_list (with the scene selector as first gui), either if a scene is active or not +// SCENE_GUI_LIST: a scene is active and we are not in the main_gui_list. In that case, we try to use the scene specific gui list, if the scene defined one. + MAIN_GUI_LIST, + SCENE_GUI_LIST +}; + +void gui_memoryOptimizer_onStartup(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2); +void gui_memoryOptimizer_afterSliding(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, int newTabID); +void gui_memoryOptimizer_afterGUIlistChanged(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, GUIlists newGUIlist); + +int gui_memoryOptimizer_getActiveTabID(); bool gui_memoryOptimizer_isTabIDInMemory(int tabID); -bool gui_memoryOptimizer_isGUInameInMemory(std::string guiName); +bool gui_memoryOptimizer_isGUInameInMemory(std::string GUIname); + +std::string gui_memoryOptimizer_getActiveSceneName(); +void gui_memoryOptimizer_setActiveSceneName(std::string aSceneName); +std::string gui_memoryOptimizer_getActiveGUIname(); +void gui_memoryOptimizer_setActiveGUIname(std::string aGUIname); +GUIlists gui_memoryOptimizer_getActiveGUIlist(); +void gui_memoryOptimizer_setActiveGUIlist(GUIlists aGUIlist); + diff --git a/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp b/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp index eeb20b3..4a78631 100644 --- a/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp +++ b/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp @@ -26,17 +26,23 @@ void init_preferences(void) { void save_preferences(void) { save_preferences_HAL(); }; -std::string get_currentScene() { - return get_currentScene_HAL(); +std::string get_activeScene() { + return get_activeScene_HAL(); } -void set_currentScene(std::string aCurrentScene) { - set_currentScene_HAL(aCurrentScene); +void set_activeScene(std::string anActiveScene) { + set_activeScene_HAL(anActiveScene); } -std::string get_currentGUIname() { - return get_currentGUIname_HAL(); +std::string get_activeGUIname() { + return get_activeGUIname_HAL(); } -void set_currentGUIname(std::string aCurrentGUIname) { - set_currentGUIname_HAL(aCurrentGUIname); +void set_activeGUIname(std::string anActiveGUIname) { + set_activeGUIname_HAL(anActiveGUIname); +} +int get_activeGUIlist() { + return get_activeGUIlist_HAL(); +} +void set_activeGUIlist(int anActiveGUIlist) { + set_activeGUIlist_HAL(anActiveGUIlist); } // --- user led --------------------------------------------------------------- diff --git a/Platformio/src/applicationInternal/hardware/hardwarePresenter.h b/Platformio/src/applicationInternal/hardware/hardwarePresenter.h index 1145f1c..f01111e 100644 --- a/Platformio/src/applicationInternal/hardware/hardwarePresenter.h +++ b/Platformio/src/applicationInternal/hardware/hardwarePresenter.h @@ -10,10 +10,12 @@ void init_hardware_general(void); // --- preferences ------------------------------------------------------------ void init_preferences(void); void save_preferences(void); -std::string get_currentScene(); -void set_currentScene(std::string aCurrentScene); -std::string get_currentGUIname(); -void set_currentGUIname(std::string aCurrentGUIname); +std::string get_activeScene(); +void set_activeScene(std::string anActiveScene); +std::string get_activeGUIname(); +void set_activeGUIname(std::string anActiveGUIname); +int get_activeGUIlist(); +void set_activeGUIlist(int anActiveGUIlist); // --- user led --------------------------------------------------------------- void init_userled(void); diff --git a/Platformio/src/applicationInternal/keys.cpp b/Platformio/src/applicationInternal/keys.cpp index 75f2241..f46cdcb 100644 --- a/Platformio/src/applicationInternal/keys.cpp +++ b/Platformio/src/applicationInternal/keys.cpp @@ -1,7 +1,8 @@ #include +#include "applicationInternal/gui/guiMemoryOptimizer.h" +#include "applicationInternal/hardware/hardwarePresenter.h" #include "applicationInternal/scenes/sceneRegistry.h" #include "applicationInternal/commandHandler.h" -#include "applicationInternal/hardware/hardwarePresenter.h" const uint8_t ROWS = 5; //five rows const uint8_t COLS = 5; //five columns @@ -33,7 +34,7 @@ void doShortPress(char keyChar, int keyCode){ if ((currentMillis - lastTimeSent[keyCode/ROWS][keyCode%ROWS]) > repeatRate) { lastTimeSent[keyCode/ROWS][keyCode%ROWS] = currentMillis; - uint16_t command = get_command_short(get_currentScene(), keyChar); + uint16_t command = get_command_short(gui_memoryOptimizer_getActiveSceneName(), keyChar); if (command != COMMAND_UNKNOWN) { Serial.printf("key: key '%c', will use command '%u'\r\n", keyChar, command); executeCommand(command); @@ -44,7 +45,7 @@ void doShortPress(char keyChar, int keyCode){ } void doLongPress(char keyChar, int keyCode){ - uint16_t command = get_command_long(get_currentScene(), keyChar); + uint16_t command = get_command_long(gui_memoryOptimizer_getActiveSceneName(), keyChar); if (command != COMMAND_UNKNOWN) { Serial.printf("key: key '%c' (long press), will use command '%u'\r\n", keyChar, command); executeCommand(command); @@ -70,11 +71,11 @@ void keypad_loop(void) { if (keypad_keys[i].kstate == PRESSED) { // Serial.println("pressed"); - if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORT) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) { + if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORT) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) { // Serial.printf("key: PRESSED of SHORT key %c (%d)\r\n", keyChar, keyCode); doShortPress(keyChar, keyCode); - } else if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORT_REPEATED) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) { // here do not repeat it too early, do the repeat only in HOLD + } else if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORT_REPEATED) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) { // here do not repeat it too early, do the repeat only in HOLD // Serial.printf("key: PRESSED of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode); doShortPress(keyChar, keyCode); @@ -84,13 +85,13 @@ void keypad_loop(void) { } else if (keypad_keys[i].kstate == HOLD) { // Serial.println("hold"); - if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORTorLONG) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != HOLD)) { + if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORTorLONG) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != HOLD)) { // Serial.printf("key: HOLD of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode); // Serial.printf("will set keyIsHold to TRUE for keycode %d\r\n", keyCode); keyIsHold[keyCode/ROWS][keyCode%ROWS] = true; doLongPress(keyChar, keyCode); - } else if (get_key_repeatMode(get_currentScene(), keyChar) == SHORT_REPEATED) { // this is the only case where we do not check the lastKeyState, because here it is intended to repeat the action + } else if (get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORT_REPEATED) { // this is the only case where we do not check the lastKeyState, because here it is intended to repeat the action // Serial.printf("key: HOLD of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode); doShortPress(keyChar, keyCode); @@ -99,7 +100,7 @@ void keypad_loop(void) { } else if (keypad_keys[i].kstate == RELEASED) { // Serial.println("released"); - if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORTorLONG) && !keyIsHold[keyCode/ROWS][keyCode%ROWS] && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != RELEASED)) { + if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORTorLONG) && !keyIsHold[keyCode/ROWS][keyCode%ROWS] && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != RELEASED)) { // Serial.printf("value of keyIsHold for keycode %d is %d\r\n", keyCode, keyIsHold[keyCode/ROWS][keyCode%ROWS]); // Serial.printf("key: RELEASED of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode); doShortPress(keyChar, keyCode); diff --git a/Platformio/src/applicationInternal/scenes/sceneHandler.cpp b/Platformio/src/applicationInternal/scenes/sceneHandler.cpp index 8e35b94..fc0f4aa 100644 --- a/Platformio/src/applicationInternal/scenes/sceneHandler.cpp +++ b/Platformio/src/applicationInternal/scenes/sceneHandler.cpp @@ -7,6 +7,12 @@ #include "applicationInternal/commandHandler.h" #include "scenes/scene__default.h" +void setLabelActiveScene() { + if ((SceneLabel != NULL) && sceneExists(gui_memoryOptimizer_getActiveSceneName())) { + lv_label_set_text(SceneLabel, gui_memoryOptimizer_getActiveSceneName().c_str()); + } +} + void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") { // FORCE can be either as second payload in commandData @@ -25,27 +31,26 @@ void handleScene(uint16_t command, commandData commandData, std::string addition // do not really switch scene, but show sceneSelection gui. From that on, we are in the main_gui_list. if (scene_name == scene_name_selection) { - useSceneGUIlist = false; - guis_doAfterSliding(-1, -1, true); + guis_doTabCreationAfterGUIlistChanged(MAIN_GUI_LIST); return; } // do not switch scene, but navigate to the prev or next gui in the currently active list of guis if ((scene_name == scene_gui_next) || (scene_name == scene_gui_prev)) { if (scene_name == scene_gui_prev) { - if (currentTabID == 0) { + if (gui_memoryOptimizer_getActiveTabID() == 0) { Serial.println("scene: cannot navigate to prev gui, because there is none"); } else { Serial.println("scene: will navigate to prev gui"); - setActiveTab(currentTabID -1, LV_ANIM_ON, true); + setActiveTab(gui_memoryOptimizer_getActiveTabID() -1, LV_ANIM_ON, true); } } else if (scene_name == scene_gui_next) { - if (!gui_memoryOptimizer_isTabIDInMemory(currentTabID +1)) { + if (!gui_memoryOptimizer_isTabIDInMemory(gui_memoryOptimizer_getActiveTabID() +1)) { Serial.println("scene: cannot navigate to next gui, because there is none"); } else { Serial.println("scene: will navigate to next gui"); - setActiveTab(currentTabID +1, LV_ANIM_ON, true); + setActiveTab(gui_memoryOptimizer_getActiveTabID() +1, LV_ANIM_ON, true); } } @@ -57,15 +62,15 @@ void handleScene(uint16_t command, commandData commandData, std::string addition Serial.printf("scene: cannot start scene %s, because it is unknown\r\n", scene_name.c_str()); return; } else { - Serial.printf("scene: will switch from old scene %s to new scene %s\r\n", get_currentScene().c_str(), scene_name.c_str()); + Serial.printf("scene: will switch from old scene %s to new scene %s\r\n", gui_memoryOptimizer_getActiveSceneName().c_str(), scene_name.c_str()); } // do not activate the same scene again, only when forced to do so (e.g. by long press on the gui or when selected by hardware key) bool callEndAndStartSequences; - if ((scene_name == get_currentScene()) && ((isForcePayload != "FORCE") && (additionalPayload != "FORCE"))) { + if ((scene_name == gui_memoryOptimizer_getActiveSceneName()) && ((isForcePayload != "FORCE") && (additionalPayload != "FORCE"))) { Serial.printf("scene: will not start scene again, because it is already active\r\n"); callEndAndStartSequences = false; - } else if ((scene_name == get_currentScene()) && ((isForcePayload == "FORCE") || (additionalPayload == "FORCE"))) { + } else if ((scene_name == gui_memoryOptimizer_getActiveSceneName()) && ((isForcePayload == "FORCE") || (additionalPayload == "FORCE"))) { Serial.printf("scene: scene is already active, but FORCE was set, so start scene again\r\n"); callEndAndStartSequences = true; } else { @@ -78,13 +83,13 @@ void handleScene(uint16_t command, commandData commandData, std::string addition if (callEndAndStartSequences) { // end old scene - if (!sceneExists(get_currentScene()) && (get_currentScene() != "")) { - Serial.printf("scene: WARNING: cannot end scene %s, because it is unknown\r\n", get_currentScene().c_str()); + if (!sceneExists(gui_memoryOptimizer_getActiveSceneName()) && (gui_memoryOptimizer_getActiveSceneName() != "")) { + Serial.printf("scene: WARNING: cannot end scene %s, because it is unknown\r\n", gui_memoryOptimizer_getActiveSceneName().c_str()); } else { - if (get_currentScene() != "") { - Serial.printf("scene: will call end sequence for scene %s\r\n", get_currentScene().c_str()); - scene_end_sequence_from_registry(get_currentScene()); + if (gui_memoryOptimizer_getActiveSceneName() != "") { + Serial.printf("scene: will call end sequence for scene %s\r\n", gui_memoryOptimizer_getActiveSceneName().c_str()); + scene_end_sequence_from_registry(gui_memoryOptimizer_getActiveSceneName()); } } @@ -94,19 +99,12 @@ void handleScene(uint16_t command, commandData commandData, std::string addition scene_start_sequence_from_registry(scene_name); } - set_currentScene(scene_name); + gui_memoryOptimizer_setActiveSceneName(scene_name); - if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, get_currentScene().c_str());} + if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, gui_memoryOptimizer_getActiveSceneName().c_str());} - Serial.printf("scene: scene handling finished, new scene %s is active\r\n", get_currentScene().c_str()); + Serial.printf("scene: scene handling finished, new scene %s is active\r\n", gui_memoryOptimizer_getActiveSceneName().c_str()); - useSceneGUIlist = true; - // recreate the gui based on the current scene - guis_doAfterSliding(-1, -1, true); + guis_doTabCreationAfterGUIlistChanged(SCENE_GUI_LIST); } -void setLabelCurrentScene() { - if ((SceneLabel != NULL) && sceneExists(get_currentScene())) { - lv_label_set_text(SceneLabel, get_currentScene().c_str()); - } -} diff --git a/Platformio/src/applicationInternal/scenes/sceneHandler.h b/Platformio/src/applicationInternal/scenes/sceneHandler.h index 16c6c7b..ef2e217 100644 --- a/Platformio/src/applicationInternal/scenes/sceneHandler.h +++ b/Platformio/src/applicationInternal/scenes/sceneHandler.h @@ -3,5 +3,5 @@ #include #include "applicationInternal/commandHandler.h" +void setLabelActiveScene(); void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = ""); -void setLabelCurrentScene(); diff --git a/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp b/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp index c1be9d8..50162ec 100644 --- a/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp +++ b/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp @@ -1,16 +1,12 @@ #include #include -#include "applicationInternal/commandHandler.h" -#include "applicationInternal/scenes/sceneRegistry.h" +#include "applicationInternal/gui/guiMemoryOptimizer.h" #include "applicationInternal/hardware/hardwarePresenter.h" +#include "applicationInternal/scenes/sceneRegistry.h" +#include "applicationInternal/commandHandler.h" // scenes #include "scenes/scene__default.h" -// If useSceneGUIlist == true, then a scene is active and we are not in the main_gui_list (with the scene selector as first gui). -// In that case, we try to use the scene specific gui list, if the scene defined one. -// If useSceneGUIlist == false, then we are in the main_gui_list, either if a scene is active or not. -bool useSceneGUIlist = false; - // https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work struct scene_definition { scene_setKeys this_scene_setKeys; @@ -90,7 +86,7 @@ void scene_end_sequence_from_registry(std::string sceneName) { repeatModes get_key_repeatMode(std::string sceneName, char keyChar) { try { - // look if the map of the current scene has a definition for it + // look if the map of the active scene has a definition for it if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_repeatModes->count(keyChar) > 0)) { // Serial.printf("get_key_repeatMode: will use key from scene %s\r\n", sceneName.c_str()); return registered_scenes.at(sceneName).this_key_repeatModes->at(keyChar); @@ -114,7 +110,7 @@ repeatModes get_key_repeatMode(std::string sceneName, char keyChar) { uint16_t get_command_short(std::string sceneName, char keyChar) { try { - // look if the map of the current scene has a definition for it + // look if the map of the active scene has a definition for it if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_short->count(keyChar) > 0)) { // Serial.printf("get_command_short: will use key from scene %s\r\n", sceneName.c_str()); return registered_scenes.at(sceneName).this_key_commands_short->at(keyChar); @@ -139,7 +135,7 @@ uint16_t get_command_short(std::string sceneName, char keyChar) { uint16_t get_command_long(std::string sceneName, char keyChar) { try { - // look if the map of the current scene has a definition for it + // look if the map of the active scene has a definition for it if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_long->count(keyChar) > 0)) { // Serial.printf("get_command_long: will use key from scene %s\r\n", sceneName.c_str()); return registered_scenes.at(sceneName).this_key_commands_long->at(keyChar); @@ -162,40 +158,44 @@ uint16_t get_command_long(std::string sceneName, char keyChar) { } -gui_list get_gui_list(std::string sceneName) { +gui_list get_gui_list(GUIlists gui_list) { try { - // If useSceneGUIlist == true, then a scene is active and we are not in the main_gui_list (with the scene selector as first gui). + // If gui_list == MAIN_GUI_LIST, then we are in the main_gui_list, either if a scene is active or not. + // If gui_list == SCENE_GUI_LIST, then a scene is active and we are not in the main_gui_list (with the scene selector as first gui). // In that case, we try to use the scene specific gui list, if the scene defined one. - // If useSceneGUIlist == false, then we are in the main_gui_list, either if a scene is active or not. - #if (USE_SCENE_SPECIFIC_GUI_LIST != 0) - // look if the current scene has a definition for a gui list - if (useSceneGUIlist && - (registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_gui_list != NULL)) { - // Serial.printf("get_gui_list: will use gui_list from scene %s\r\n", sceneName.c_str()); - return registered_scenes.at(sceneName).this_gui_list; - - // if there is no scene specific gui list, simply return the main_gui_list - } else { - // Serial.printf("get_gui_list: will use main_gui_list\r\n"); + if (gui_list == MAIN_GUI_LIST) { return &main_gui_list; - - } - #else - // never use scene specific gui list - return &main_gui_list; - #endif + + } else { + #if (USE_SCENE_SPECIFIC_GUI_LIST != 0) + // look if the active scene has a definition for a gui list + if ((registered_scenes.count(gui_memoryOptimizer_getActiveSceneName()) > 0) && (registered_scenes.at(gui_memoryOptimizer_getActiveSceneName()).this_gui_list != NULL)) { + // Serial.printf("get_gui_list: will use gui_list from scene %s\r\n", sceneName.c_str()); + return registered_scenes.at(gui_memoryOptimizer_getActiveSceneName()).this_gui_list; + } else { + // no scene specific gui list was defined + return &main_gui_list; + } + #else + // never use scene specific gui list + return &main_gui_list; + #endif + } } catch (const std::out_of_range& oor) { Serial.printf("get_gui_list: internal error, sceneName not registered\r\n"); return NULL; } +} +gui_list get_gui_list_active() { + return get_gui_list(gui_memoryOptimizer_getActiveGUIlist()); } uint16_t get_activate_scene_command(std::string sceneName) { try { - // look if the current scene is known + // look if the active scene is known if ((registered_scenes.count(sceneName) > 0)) { // Serial.printf("get_activate_scene_command: will use activate_scene_command from scene %s\r\n", sceneName.c_str()); return registered_scenes.at(sceneName).this_activate_scene_command; diff --git a/Platformio/src/applicationInternal/scenes/sceneRegistry.h b/Platformio/src/applicationInternal/scenes/sceneRegistry.h index dbc8f56..beb045a 100644 --- a/Platformio/src/applicationInternal/scenes/sceneRegistry.h +++ b/Platformio/src/applicationInternal/scenes/sceneRegistry.h @@ -6,8 +6,6 @@ #include #include "applicationInternal/keys.h" -extern bool useSceneGUIlist; - typedef std::vector t_gui_list; typedef std::vector t_scene_list; @@ -37,7 +35,7 @@ void scene_end_sequence_from_registry(std::string sceneName); repeatModes get_key_repeatMode(std::string sceneName, char keyChar); uint16_t get_command_short(std::string sceneName, char keyChar); uint16_t get_command_long(std::string sceneName, char keyChar); -gui_list get_gui_list(std::string sceneName); +gui_list get_gui_list_active(); uint16_t get_activate_scene_command(std::string sceneName); scene_list get_scenes_on_sceneSelectionGUI(); void set_scenes_on_sceneSelectionGUI(t_scene_list a_scene_list); diff --git a/Platformio/src/guis/gui_numpad.cpp b/Platformio/src/guis/gui_numpad.cpp index 6bb2e96..a853ffa 100644 --- a/Platformio/src/guis/gui_numpad.cpp +++ b/Platformio/src/guis/gui_numpad.cpp @@ -18,12 +18,12 @@ static void virtualKeypad_event_cb(lv_event_t* e) { int user_data = (intptr_t)(target->user_data); // send corrensponding number - if (get_currentScene() == scene_name_TV) { + if (gui_memoryOptimizer_getActiveSceneName() == scene_name_TV) { uint16_t virtualKeyMapTVNumbers[10] = {SAMSUNG_NUM_1, SAMSUNG_NUM_2, SAMSUNG_NUM_3, SAMSUNG_NUM_4, SAMSUNG_NUM_5, SAMSUNG_NUM_6, SAMSUNG_NUM_7, SAMSUNG_NUM_8, SAMSUNG_NUM_9, SAMSUNG_NUM_0}; uint16_t command = virtualKeyMapTVNumbers[user_data]; executeCommand(command); - } else if (get_currentScene() == scene_name_fireTV) { + } else if (gui_memoryOptimizer_getActiveSceneName() == scene_name_fireTV) { int virtualKeyMapFireTVNumbers[10] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0}; int number = virtualKeyMapFireTVNumbers[user_data]; std::string numberStr = std::to_string(number); diff --git a/Platformio/src/main.cpp b/Platformio/src/main.cpp index 0515123..33ff548 100644 --- a/Platformio/src/main.cpp +++ b/Platformio/src/main.cpp @@ -125,7 +125,7 @@ int main(int argc, char *argv[]) { #endif // init GUI - will initialize tft, touch and lvgl init_gui(); - setLabelCurrentScene(); + setLabelActiveScene(); gui_loop(); // Run the LVGL UI once before the loop takes over // setup the Inertial Measurement Unit (IMU) for motion detection. Has to be after init_gui(), otherwise I2C will not work