From d833827fabe18d79794b7f3f12430ab3e1c3d0cb Mon Sep 17 00:00:00 2001 From: KlausMu Date: Mon, 22 Apr 2024 17:12:47 +0200 Subject: [PATCH] navigate to specific GUI and back to last position in previous gui list --- .../ESP32/preferencesStorage_hal_esp32.cpp | 9 + .../ESP32/preferencesStorage_hal_esp32.h | 2 + .../preferencesStorage_hal_windows_linux.cpp | 10 +- .../preferencesStorage_hal_windows_linux.h | 2 + .../applicationInternal/commandHandler.cpp | 7 + .../src/applicationInternal/commandHandler.h | 1 + .../src/applicationInternal/gui/guiBase.cpp | 13 +- .../src/applicationInternal/gui/guiBase.h | 7 +- .../gui/guiMemoryOptimizer.cpp | 162 ++++++++++++++++-- .../gui/guiMemoryOptimizer.h | 2 + .../hardware/hardwarePresenter.cpp | 6 + .../hardware/hardwarePresenter.h | 2 + .../scenes/sceneHandler.cpp | 72 ++++++-- .../applicationInternal/scenes/sceneHandler.h | 1 + .../scenes/sceneRegistry.cpp | 17 +- .../scenes/sceneRegistry.h | 3 + .../misc/device_smarthome/gui_smarthome.cpp | 4 + .../misc/device_smarthome/gui_smarthome.h | 1 + Platformio/src/main.cpp | 21 +-- Platformio/src/scenes/scene_TV.cpp | 2 +- Platformio/src/scenes/scene__default.cpp | 16 +- Platformio/src/scenes/scene__default.h | 14 +- 22 files changed, 320 insertions(+), 54 deletions(-) diff --git a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp index 2577482..e60fe0d 100644 --- a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp +++ b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.cpp @@ -7,6 +7,7 @@ Preferences preferences; std::string activeScene; std::string activeGUIname; int activeGUIlist; +int lastActiveGUIlistIndex; void init_preferences_HAL(void) { // Restore settings from internal flash memory @@ -21,6 +22,7 @@ void init_preferences_HAL(void) { activeScene = std::string(preferences.getString("currentScene").c_str()); activeGUIname = std::string(preferences.getString("currentGUIname").c_str()); activeGUIlist =(preferences.getInt("currentGUIlist")); + lastActiveGUIlistIndex = (preferences.getInt("lastActiveIndex")); // Serial.printf("Preferences restored: brightness %d, GUI %s, scene %s\r\n", get_backlightBrightness_HAL(), get_activeGUIname().c_str(), get_activeScene().c_str()); } else { @@ -40,6 +42,7 @@ void save_preferences_HAL(void) { preferences.putString("currentScene", activeScene.c_str()); preferences.putString("currentGUIname", activeGUIname.c_str()); preferences.putInt("currentGUIlist", activeGUIlist); + preferences.putInt("lastActiveIndex", lastActiveGUIlistIndex); if (!preferences.getBool("alreadySetUp")) { preferences.putBool("alreadySetUp", true); } @@ -64,3 +67,9 @@ int get_activeGUIlist_HAL() { void set_activeGUIlist_HAL(int anActiveGUIlist) { activeGUIlist = anActiveGUIlist; } +int get_lastActiveGUIlistIndex_HAL() { + return lastActiveGUIlistIndex; +} +void set_lastActiveGUIlistIndex_HAL(int aGUIlistIndex) { + lastActiveGUIlistIndex = aGUIlistIndex; +} diff --git a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h index 9f4d98e..e223648 100644 --- a/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h +++ b/Platformio/hardware/ESP32/preferencesStorage_hal_esp32.h @@ -11,3 +11,5 @@ std::string get_activeGUIname_HAL(); void set_activeGUIname_HAL(std::string anActiveGUIname); int get_activeGUIlist_HAL(); void set_activeGUIlist_HAL(int anActiveGUIlist); +int get_lastActiveGUIlistIndex_HAL(); +void set_lastActiveGUIlistIndex_HAL(int aGUIlistIndex); diff --git a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp index 5d45c89..be907c2 100644 --- a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp +++ b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.cpp @@ -20,12 +20,14 @@ main_gui_list : "Scene selection", "Smart Home", "Settings", "IR Receiver"}; std::string activeScene; std::string activeGUIname; int activeGUIlist; +int lastActiveGUIlistIndex; 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; + activeGUIlist = MAIN_GUI_LIST; // MAIN_GUI_LIST, SCENE_GUI_LIST; + lastActiveGUIlistIndex = 0; } void save_preferences_HAL(void) { } @@ -48,3 +50,9 @@ int get_activeGUIlist_HAL() { void set_activeGUIlist_HAL(int anActiveGUIlist) { activeGUIlist = anActiveGUIlist; } +int get_lastActiveGUIlistIndex_HAL() { + return lastActiveGUIlistIndex; +} +void set_lastActiveGUIlistIndex_HAL(int aGUIlistIndex) { + lastActiveGUIlistIndex = aGUIlistIndex; +} diff --git a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h index 9f4d98e..e223648 100644 --- a/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h +++ b/Platformio/hardware/windows_linux/preferencesStorage_hal_windows_linux.h @@ -11,3 +11,5 @@ std::string get_activeGUIname_HAL(); void set_activeGUIname_HAL(std::string anActiveGUIname); int get_activeGUIlist_HAL(); void set_activeGUIlist_HAL(int anActiveGUIlist); +int get_lastActiveGUIlistIndex_HAL(); +void set_lastActiveGUIlistIndex_HAL(int aGUIlistIndex); diff --git a/Platformio/src/applicationInternal/commandHandler.cpp b/Platformio/src/applicationInternal/commandHandler.cpp index a9924b5..e158343 100644 --- a/Platformio/src/applicationInternal/commandHandler.cpp +++ b/Platformio/src/applicationInternal/commandHandler.cpp @@ -232,6 +232,13 @@ void executeCommandWithData(uint16_t command, commandData commandData, std::stri break; } + case GUI: { + // let the sceneHandler find and show the gui + Serial.printf("execute: will send gui command to the sceneHandler\r\n"); + handleGUI(command, commandData, additionalPayload); + break; + } + case SPECIAL: { if (command == MY_SPECIAL_COMMAND) { // do your special command here diff --git a/Platformio/src/applicationInternal/commandHandler.h b/Platformio/src/applicationInternal/commandHandler.h index 75b0a6b..29bd0d6 100644 --- a/Platformio/src/applicationInternal/commandHandler.h +++ b/Platformio/src/applicationInternal/commandHandler.h @@ -94,6 +94,7 @@ extern uint16_t KEYBOARD_VOLUME_DECREMENT; enum commandHandlers { SPECIAL, SCENE, + GUI, IR, #if (ENABLE_WIFI_AND_MQTT == 1) MQTT, diff --git a/Platformio/src/applicationInternal/gui/guiBase.cpp b/Platformio/src/applicationInternal/gui/guiBase.cpp index c8e9f86..dac2306 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.cpp +++ b/Platformio/src/applicationInternal/gui/guiBase.cpp @@ -265,6 +265,7 @@ void init_gui_status_bar() { lv_obj_align(SceneLabel, LV_ALIGN_TOP_MID, 0, labelsPositionTopStatusbar); lv_obj_set_style_text_font(SceneLabel, &lv_font_montserrat_12, LV_PART_MAIN); lv_obj_add_flag(SceneLabel, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_user_data(SceneLabel,(void *)(intptr_t)0); lv_obj_add_event_cb(SceneLabel, sceneLabel_or_pageIndicator_event_cb, LV_EVENT_CLICKED, NULL); // Battery ---------------------------------------------------------------------- @@ -304,7 +305,6 @@ void gui_loop(void) { // 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(); } @@ -318,6 +318,17 @@ void guis_doTabCreationAfterGUIlistChanged(GUIlists newGUIlist) { gui_memoryOptimizer_afterGUIlistChanged(&tabview, &panel, &img1, &img2, newGUIlist); doLogMemoryUsage(); } +// 4. navigate to a specific GUI in gui_list +void guis_doTabCreationForSpecificGUI(GUIlists GUIlist, int gui_list_index) { + gui_memoryOptimizer_navigateToGUI(&tabview, &panel, &img1, &img2, GUIlist, gui_list_index); + doLogMemoryUsage(); +} +// 5. navigate back to last active gui of previous gui_list +void guis_doTabCreationForNavigateToLastActiveGUIofPreviousGUIlist() { + gui_memoryOptimizer_navigateToLastActiveGUIofPreviousGUIlist(&tabview, &panel, &img1, &img2); + doLogMemoryUsage(); +} + // ------------------------------------------------------------------------------------------------------------ void setActiveTab(uint32_t index, lv_anim_enable_t anim_en, bool send_tab_changed_event) { diff --git a/Platformio/src/applicationInternal/gui/guiBase.h b/Platformio/src/applicationInternal/gui/guiBase.h index 2a8c2a0..ffaade2 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.h +++ b/Platformio/src/applicationInternal/gui/guiBase.h @@ -24,15 +24,20 @@ extern lv_color_t color_primary; extern lv_style_t style_red_border; #endif -// used by main.cpp and sceneHandler.cpp +// used by main.cpp void init_gui(void); +// used by main.cpp and sceneHandler.cpp void gui_loop(void); // used by guiMemoryOptimizer.cpp 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); +// used by sceneHandler.cpp void guis_doTabCreationAfterGUIlistChanged(GUIlists newGUIlist); +void guis_doTabCreationForSpecificGUI(GUIlists GUIlist, int gui_list_index); +void guis_doTabCreationForNavigateToLastActiveGUIofPreviousGUIlist(); +// used by guiMemoryOptimizer.cpp and sceneHandler.cpp 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); diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp index e3a1643..718377b 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp @@ -12,7 +12,7 @@ struct t_gui_on_tab { int gui_list_index_previous; }; struct t_gui_state { - // the next three are saved in the preferenceStorage every time they change + // the next three and the last are saved in the preferenceStorage every time they change std::string activeScene_internalDontUse; std::string activeGUIname_internalDontUse; GUIlists activeGUIlist_internalDontUse; @@ -20,6 +20,9 @@ struct t_gui_state { 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}}; + // the last active gui of scene. Will be stored to easily navigate back to it with guis_doTabCreationForNavigateToLastActiveGUIofPreviousGUIlist() + GUIlists last_active_gui_list = (GUIlists)-1; + int last_active_gui_list_index_internalDontUse = -1; }; t_gui_state gui_state; @@ -51,6 +54,14 @@ void gui_memoryOptimizer_setActiveGUIlist(GUIlists aGUIlist) { gui_state.activeGUIlist_internalDontUse = aGUIlist; set_activeGUIlist(aGUIlist); } +int gui_memoryOptimizer_getLastActiveGUIlistIndex() { + gui_state.last_active_gui_list_index_internalDontUse = get_lastActiveGUIlistIndex(); + return gui_state.last_active_gui_list_index_internalDontUse; +} +void gui_memoryOptimizer_setLastActiveGUIlistIndex(int aGUIlistIndex) { + gui_state.last_active_gui_list_index_internalDontUse = aGUIlistIndex; + set_lastActiveGUIlistIndex(aGUIlistIndex); +} int gui_memoryOptimizer_getActiveTabID() { return gui_state.activeTabID; @@ -349,10 +360,28 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN); } - uint8_t breadcrumpLength = get_gui_list_active()->size(); - uint8_t breadcrumpDotSize = 8; // should be an even number + 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; + uint8_t breadcrumpMainGuiListLength = get_gui_list(MAIN_GUI_LIST)->size(); + int8_t breadcrumpMainGuiListStartPositionX = (-1) * (breadcrumpMainGuiListLength -1) * (breadcrumpDotSize + breadcrumpDotDistance) / 2; + uint8_t breadcrumpSceneGuiListLength = get_gui_list(SCENE_GUI_LIST)->size(); + int8_t breadcrumpSceneGuiListStartPositionX = (-1) * (breadcrumpSceneGuiListLength -1) * (breadcrumpDotSize + breadcrumpDotDistance) / 2; + #if (USE_SCENE_SPECIFIC_GUI_LIST != 0) + bool show_scene_gui_list = get_scene_has_gui_list(gui_memoryOptimizer_getActiveSceneName()); + #else + bool show_scene_gui_list = false; + #endif + int8_t breadcrumpMainGuiList_yPos; + int8_t breadcrumpSceneGuiList_yPos; + int8_t nameOfGUI_yPos; + if (!show_scene_gui_list) { + breadcrumpMainGuiList_yPos = -6; + nameOfGUI_yPos = 6; + } else { + breadcrumpMainGuiList_yPos = -8; + breadcrumpSceneGuiList_yPos = -1; + nameOfGUI_yPos = 8; + } // create the panel content for the three guis (or less) which are currently in memory std::string nameOfGUI; @@ -364,9 +393,10 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv // 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 (nameOfGUI == gui_memoryOptimizer_getActiveGUIname()) { + // only if this is the button for the currently active tab, make it clickable to get to scene selection gui lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_user_data(btn,(void *)(intptr_t)2); lv_obj_add_event_cb(btn, sceneLabel_or_pageIndicator_event_cb, LV_EVENT_CLICKED, NULL); } else if ((i==0 || i==1) && (gui_state->gui_on_tab[i+1].gui_list_index != -1)) { @@ -389,28 +419,63 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv lv_obj_set_style_shadow_width(btn, 0, LV_PART_MAIN); lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN); - // create a breadcrump dot for each gui in the list - for (int j=0; j= 0) && (gui_list_index < get_gui_list(GUIlist)->size()))) { + Serial.printf(" cannot navigate to GUI because gui_list_index \"%d\" is out of range\r\n", gui_list_index); + return; + } + + if (gui_state.last_active_gui_list != GUIlist) { + // we are changing the gui_list, so save the last_active_gui_list_index + gui_memoryOptimizer_setLastActiveGUIlistIndex(gui_state.gui_on_tab[gui_state.activeTabID].gui_list_index); + } + + // 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(GUIlist); + setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(gui_list_index, &gui_state); + + // 3. create content + gui_memoryOptimizer_doContentCreation(tabview, panel, img1, img2, &gui_state); + +} + +// 5. navigate back to last gui in scene +void gui_memoryOptimizer_navigateToLastActiveGUIofPreviousGUIlist(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2) { + + #if (USE_SCENE_SPECIFIC_GUI_LIST == 0) + Serial.printf("--- Cannot navigate to last GUI from scene, because scene specific gui lists are not enabled\r\n"); + return; + #endif + + if (gui_memoryOptimizer_getLastActiveGUIlistIndex() == -1) { + Serial.printf("--- Cannot navigate to last GUI from scene, because it is not set\r\n"); + return; + } else { + Serial.printf("--- Will navigate to last GUI from scene\r\n"); + } + + // navigate to the other gui_list + if (gui_memoryOptimizer_getActiveGUIlist() == MAIN_GUI_LIST) { + gui_memoryOptimizer_navigateToGUI(tabview, panel, img1, img2, SCENE_GUI_LIST, gui_memoryOptimizer_getLastActiveGUIlistIndex()); + } else { + gui_memoryOptimizer_navigateToGUI(tabview, panel, img1, img2, MAIN_GUI_LIST, gui_memoryOptimizer_getLastActiveGUIlistIndex()); + } + +} + + 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(); @@ -586,6 +715,11 @@ void gui_memoryOptimizer_doContentCreation(lv_obj_t** tabview, lv_obj_t** panel, // Initialize scroll position of the page indicator lv_event_send(lv_tabview_get_content(*tabview), LV_EVENT_SCROLL, NULL); + // gui_memoryOptimizer_doContentCreation() is called as last step every time the 3 tabs are recreated. + // Save here the last_active_gui_list. If the used list changes in a future navigation, save the last_active_gui_list_index + // so that we can use SCENE_BACK_TO_PREVIOUS_GUI_LIST + gui_state->last_active_gui_list = gui_memoryOptimizer_getActiveGUIlist(); + Serial.printf("------------ End of tab deletion and creation\r\n"); } diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h index 47ec812..f163c54 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h @@ -12,6 +12,8 @@ enum GUIlists { 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); +void gui_memoryOptimizer_navigateToGUI(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, GUIlists GUIlist, int gui_list_index); +void gui_memoryOptimizer_navigateToLastActiveGUIofPreviousGUIlist(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2); int gui_memoryOptimizer_getActiveTabID(); bool gui_memoryOptimizer_isTabIDInMemory(int tabID); diff --git a/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp b/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp index 4a78631..fff5de7 100644 --- a/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp +++ b/Platformio/src/applicationInternal/hardware/hardwarePresenter.cpp @@ -44,6 +44,12 @@ int get_activeGUIlist() { void set_activeGUIlist(int anActiveGUIlist) { set_activeGUIlist_HAL(anActiveGUIlist); } +int get_lastActiveGUIlistIndex() { + return get_lastActiveGUIlistIndex_HAL(); +} +void set_lastActiveGUIlistIndex(int aGUIlistIndex) { + set_lastActiveGUIlistIndex_HAL(aGUIlistIndex); +} // --- user led --------------------------------------------------------------- void init_userled(void) { diff --git a/Platformio/src/applicationInternal/hardware/hardwarePresenter.h b/Platformio/src/applicationInternal/hardware/hardwarePresenter.h index f01111e..74c8e48 100644 --- a/Platformio/src/applicationInternal/hardware/hardwarePresenter.h +++ b/Platformio/src/applicationInternal/hardware/hardwarePresenter.h @@ -16,6 +16,8 @@ std::string get_activeGUIname(); void set_activeGUIname(std::string anActiveGUIname); int get_activeGUIlist(); void set_activeGUIlist(int anActiveGUIlist); +int get_lastActiveGUIlistIndex(); +void set_lastActiveGUIlistIndex(int aGUIlistIndex); // --- user led --------------------------------------------------------------- void init_userled(void); diff --git a/Platformio/src/applicationInternal/scenes/sceneHandler.cpp b/Platformio/src/applicationInternal/scenes/sceneHandler.cpp index fc0f4aa..8ea033c 100644 --- a/Platformio/src/applicationInternal/scenes/sceneHandler.cpp +++ b/Platformio/src/applicationInternal/scenes/sceneHandler.cpp @@ -13,29 +13,21 @@ void setLabelActiveScene() { } } -void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") { +void navigateBackToSceneGUIlist(); - // FORCE can be either as second payload in commandData - // e.g. register_command(&SCENE_TV_FORCE , makeCommandData(SCENE, {scene_name_TV, "FORCE"})); - // or as additionalPayload, used by gui_sceneSelection.cpp - // e.g. executeCommand(activate_scene_command, "FORCE"); +void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") { auto current = commandData.commandPayloads.begin(); std::string scene_name = *current; - // we can have a second payload - std::string isForcePayload = ""; - ++current; - if (current != commandData.commandPayloads.end()) { - isForcePayload = *current; - } - // do not really switch scene, but show sceneSelection gui. From that on, we are in the main_gui_list. + // --- do not switch scene, but show scene selection gui. From that on, we are in the main_gui_list. ---------------- if (scene_name == scene_name_selection) { + Serial.println("scene: will show scene selection gui"); 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 + // --- 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 (gui_memoryOptimizer_getActiveTabID() == 0) { @@ -57,6 +49,33 @@ void handleScene(uint16_t command, commandData commandData, std::string addition return; } + // --- do not switch scene. Switch to the other gui list ------------------------------------------------------------ + if (scene_name == scene_back_to_previous_gui_list) { + + if (get_scene_has_gui_list(gui_memoryOptimizer_getActiveSceneName())) { + Serial.println("scene: will navigate back to last active gui from previous gui list"); + guis_doTabCreationForNavigateToLastActiveGUIofPreviousGUIlist(); + } else { + Serial.println("scene: cannot navigate back to last active gui from previous gui list, because no scene specific gui list was defined"); + } + + return; + } + + // --- This is the normal case. We navigate to a new scene ---------------------------------------------------------- + + // FORCE can be either as second payload in commandData + // e.g. register_command(&SCENE_TV_FORCE , makeCommandData(SCENE, {scene_name_TV, "FORCE"})); + // or as additionalPayload, used by gui_sceneSelection.cpp + // e.g. executeCommand(activate_scene_command, "FORCE"); + + // we can have a second payload + std::string isForcePayload = ""; + ++current; + if (current != commandData.commandPayloads.end()) { + isForcePayload = *current; + } + // check if we know the new scene if (!sceneExists(scene_name)) { Serial.printf("scene: cannot start scene %s, because it is unknown\r\n", scene_name.c_str()); @@ -108,3 +127,30 @@ void handleScene(uint16_t command, commandData commandData, std::string addition guis_doTabCreationAfterGUIlistChanged(SCENE_GUI_LIST); } +void handleGUI(uint16_t command, commandData commandData, std::string additionalPayload = "") { + + auto current = commandData.commandPayloads.begin(); + std::string GUIname = *current; + + // 1. check if the gui is known in the main_gui_list + int gui_list_index = -1; + // find index of gui_memoryOptimizer_getActiveGUIname() in gui_list_active + for (int i=0; i < main_gui_list.size(); i++) { + if (main_gui_list.at(i) == GUIname) { + Serial.printf("handleGUI: found GUI with name \"%s\" in \"main_gui_list\" at position %d\r\n", GUIname.c_str(), i); + gui_list_index = i; + break; + } + } + + // 2. call guiBase.cpp + if ((gui_list_index >= 0) && (gui_list_index < main_gui_list.size())) { + guis_doTabCreationForSpecificGUI(MAIN_GUI_LIST, gui_list_index); + + } else { + // gui was not found + Serial.printf("handleGUI: GUI with name \"%s\" was not found. Cannot navigate to that GUI\r\n", GUIname.c_str()); + return; + } + +} diff --git a/Platformio/src/applicationInternal/scenes/sceneHandler.h b/Platformio/src/applicationInternal/scenes/sceneHandler.h index ef2e217..5aba73d 100644 --- a/Platformio/src/applicationInternal/scenes/sceneHandler.h +++ b/Platformio/src/applicationInternal/scenes/sceneHandler.h @@ -5,3 +5,4 @@ void setLabelActiveScene(); void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = ""); +void handleGUI (uint16_t command, commandData commandData, std::string additionalPayload = ""); diff --git a/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp b/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp index 50162ec..ceec140 100644 --- a/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp +++ b/Platformio/src/applicationInternal/scenes/sceneRegistry.cpp @@ -195,7 +195,7 @@ gui_list get_gui_list_active() { uint16_t get_activate_scene_command(std::string sceneName) { try { - // look if the active scene is known + // look if the 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; @@ -214,6 +214,21 @@ uint16_t get_activate_scene_command(std::string sceneName) { } +bool get_scene_has_gui_list(std::string sceneName) { + try { + // look if the scene is known + if ((registered_scenes.count(sceneName) > 0)) { + return (registered_scenes.at(sceneName).this_gui_list != NULL); + } else { + return false; + } + } + catch (const std::out_of_range& oor) { + Serial.printf("get_scene_has_gui_list: internal error, sceneName not registered\r\n"); + return false; + } +} + scene_list get_scenes_on_sceneSelectionGUI() { return &scenes_on_sceneSelectionGUI; } diff --git a/Platformio/src/applicationInternal/scenes/sceneRegistry.h b/Platformio/src/applicationInternal/scenes/sceneRegistry.h index beb045a..05ebfbf 100644 --- a/Platformio/src/applicationInternal/scenes/sceneRegistry.h +++ b/Platformio/src/applicationInternal/scenes/sceneRegistry.h @@ -5,6 +5,7 @@ #include #include #include "applicationInternal/keys.h" +#include "applicationInternal/gui/guiMemoryOptimizer.h" typedef std::vector t_gui_list; typedef std::vector t_scene_list; @@ -35,8 +36,10 @@ 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(GUIlists gui_list); gui_list get_gui_list_active(); uint16_t get_activate_scene_command(std::string sceneName); +bool get_scene_has_gui_list(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/devices/misc/device_smarthome/gui_smarthome.cpp b/Platformio/src/devices/misc/device_smarthome/gui_smarthome.cpp index 4ddc7cc..4cc1e13 100644 --- a/Platformio/src/devices/misc/device_smarthome/gui_smarthome.cpp +++ b/Platformio/src/devices/misc/device_smarthome/gui_smarthome.cpp @@ -20,6 +20,8 @@ static bool lightToggleBstate = false; static int32_t sliderAvalue = 0; static int32_t sliderBvalue = 0; +uint16_t GUI_SMARTHOME_ACTIVATE; + // Smart Home Toggle Event handler static void smartHomeToggle_event_cb(lv_event_t* e){ std::string payload; @@ -160,4 +162,6 @@ void notify_tab_before_delete_smarthome(void) { void register_gui_smarthome(void){ register_gui(std::string(tabName_smarthome), & create_tab_content_smarthome, & notify_tab_before_delete_smarthome); + + register_command(&GUI_SMARTHOME_ACTIVATE, makeCommandData(GUI, {std::string(tabName_smarthome)})); } diff --git a/Platformio/src/devices/misc/device_smarthome/gui_smarthome.h b/Platformio/src/devices/misc/device_smarthome/gui_smarthome.h index 26feb93..3c1a58c 100644 --- a/Platformio/src/devices/misc/device_smarthome/gui_smarthome.h +++ b/Platformio/src/devices/misc/device_smarthome/gui_smarthome.h @@ -3,4 +3,5 @@ #include const char * const tabName_smarthome = "Smart Home"; +extern uint16_t GUI_SMARTHOME_ACTIVATE; void register_gui_smarthome(void); diff --git a/Platformio/src/main.cpp b/Platformio/src/main.cpp index 33ff548..f6d9d41 100644 --- a/Platformio/src/main.cpp +++ b/Platformio/src/main.cpp @@ -102,16 +102,6 @@ int main(int argc, char *argv[]) { #endif register_keyboardCommands(); - // register the scenes and their key_commands_* - register_scene_defaultKeys(); - register_scene_TV(); - register_scene_fireTV(); - register_scene_chromecast(); - register_scene_appleTV(); - register_scene_allOff(); - // Only show these scenes on the sceneSelection gui. If you don't set this explicitely, by default all registered scenes are shown. - set_scenes_on_sceneSelectionGUI({scene_name_TV, scene_name_fireTV, scene_name_chromecast, scene_name_appleTV}); - // register the GUIs. They will be displayed in the order they have been registered. register_gui_sceneSelection(); register_gui_irReceiver(); @@ -123,6 +113,17 @@ int main(int argc, char *argv[]) { #if (USE_SCENE_SPECIFIC_GUI_LIST != 0) main_gui_list = {tabName_sceneSelection, tabName_smarthome, tabName_settings, tabName_irReceiver}; #endif + + // register the scenes and their key_commands_* + register_scene_defaultKeys(); + register_scene_TV(); + register_scene_fireTV(); + register_scene_chromecast(); + register_scene_appleTV(); + register_scene_allOff(); + // Only show these scenes on the sceneSelection gui. If you don't set this explicitely, by default all registered scenes are shown. + set_scenes_on_sceneSelectionGUI({scene_name_TV, scene_name_fireTV, scene_name_chromecast, scene_name_appleTV}); + // init GUI - will initialize tft, touch and lvgl init_gui(); setLabelActiveScene(); diff --git a/Platformio/src/scenes/scene_TV.cpp b/Platformio/src/scenes/scene_TV.cpp index 7f74bb1..fecdcde 100644 --- a/Platformio/src/scenes/scene_TV.cpp +++ b/Platformio/src/scenes/scene_TV.cpp @@ -33,7 +33,7 @@ void scene_setKeys_TV() { key_commands_short_TV = { - {KEY_STOP, SAMSUNG_REWIND }, {KEY_REWI, SAMSUNG_PAUSE }, {KEY_PLAY, SAMSUNG_PLAY }, {KEY_FORW, SAMSUNG_FASTFORWARD}, + {KEY_STOP, SAMSUNG_PAUSE }, {KEY_REWI, SAMSUNG_REWIND }, {KEY_PLAY, SAMSUNG_PLAY }, {KEY_FORW, SAMSUNG_FASTFORWARD}, {KEY_CONF, SAMSUNG_GUIDE }, {KEY_INFO, SAMSUNG_MENU }, {KEY_UP, SAMSUNG_UP }, {KEY_LEFT, SAMSUNG_LEFT }, {KEY_OK, SAMSUNG_SELECT }, {KEY_RIGHT, SAMSUNG_RIGHT }, diff --git a/Platformio/src/scenes/scene__default.cpp b/Platformio/src/scenes/scene__default.cpp index 848aafe..c4b69dc 100644 --- a/Platformio/src/scenes/scene__default.cpp +++ b/Platformio/src/scenes/scene__default.cpp @@ -4,6 +4,7 @@ #include "applicationInternal/commandHandler.h" // devices #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" +#include "devices/misc/device_smarthome/gui_smarthome.h" // scenes #include "scene__default.h" #include "scenes/scene_allOff.h" @@ -14,9 +15,11 @@ uint16_t SCENE_SELECTION; std::string scene_name_selection = "sceneSelection"; +uint16_t SCENE_BACK_TO_PREVIOUS_GUI_LIST; +std::string scene_back_to_previous_gui_list = "backToPreviousList"; uint16_t GUI_PREV; -uint16_t GUI_NEXT; std::string scene_gui_prev = "GUI_prev"; +uint16_t GUI_NEXT; std::string scene_gui_next = "GUI_next"; std::map key_repeatModes_default; @@ -45,14 +48,14 @@ void register_scene_defaultKeys(void) { key_commands_short_default = { {KEY_OFF, SCENE_ALLOFF_FORCE}, - /*{KEY_STOP, COMMAND_UNKNOWN }, {KEY_REWI, COMMAND_UNKNOWN }, {KEY_PLAY, COMMAND_UNKNOWN }, {KEY_FORW, COMMAND_UNKNOWN },*/ + {KEY_STOP, GUI_SMARTHOME_ACTIVATE},/*{KEY_REWI, COMMAND_UNKNOWN }, {KEY_PLAY, COMMAND_UNKNOWN }, {KEY_FORW, COMMAND_UNKNOWN },*/ /*{KEY_CONF, COMMAND_UNKNOWN }, {KEY_INFO, COMMAND_UNKNOWN },*/ /* {KEY_UP, COMMAND_UNKNOWN },*/ {KEY_LEFT, GUI_PREV }, /* {KEY_OK, COMMAND_UNKNOWN },*/ {KEY_RIGHT, GUI_NEXT }, /* {KEY_DOWN, COMMAND_UNKNOWN },*/ {KEY_BACK, SCENE_SELECTION }, /*{KEY_SRC, COMMAND_UNKNOWN },*/ {KEY_VOLUP, YAMAHA_VOL_PLUS }, {KEY_MUTE, YAMAHA_MUTE_TOGGLE}, /*{KEY_CHUP, COMMAND_UNKNOWN },*/ - {KEY_VOLDO, YAMAHA_VOL_MINUS }, /* {KEY_REC, COMMAND_UNKNOWN },*/ /*{KEY_CHDOW, COMMAND_UNKNOWN },*/ + {KEY_VOLDO, YAMAHA_VOL_MINUS }, {KEY_REC, SCENE_BACK_TO_PREVIOUS_GUI_LIST }, /*{KEY_CHDOW, COMMAND_UNKNOWN },*/ {KEY_RED, SCENE_TV_FORCE }, {KEY_GREEN, SCENE_FIRETV_FORCE}, {KEY_YELLO, SCENE_CHROMECAST_FORCE},{KEY_BLUE, SCENE_APPLETV_FORCE}, }; @@ -61,8 +64,9 @@ void register_scene_defaultKeys(void) { }; - register_command(&SCENE_SELECTION, makeCommandData(SCENE, {scene_name_selection})); - register_command(&GUI_PREV , makeCommandData(SCENE, {scene_gui_prev})); - register_command(&GUI_NEXT , makeCommandData(SCENE, {scene_gui_next})); + register_command(&SCENE_SELECTION , makeCommandData(SCENE, {scene_name_selection})); + register_command(&SCENE_BACK_TO_PREVIOUS_GUI_LIST, makeCommandData(SCENE, {scene_back_to_previous_gui_list})); + register_command(&GUI_PREV , makeCommandData(SCENE, {scene_gui_prev})); + register_command(&GUI_NEXT , makeCommandData(SCENE, {scene_gui_next})); } diff --git a/Platformio/src/scenes/scene__default.h b/Platformio/src/scenes/scene__default.h index 7078a2f..00c1194 100644 --- a/Platformio/src/scenes/scene__default.h +++ b/Platformio/src/scenes/scene__default.h @@ -6,12 +6,14 @@ #include "applicationInternal/keys.h" #include "applicationInternal/scenes/sceneRegistry.h" -extern uint16_t SCENE_SELECTION; // command -extern std::string scene_name_selection; // payload: name of this fake default scene -extern uint16_t GUI_PREV; // command -extern uint16_t GUI_NEXT; // command -extern std::string scene_gui_prev; // payload: name of this fake scene -extern std::string scene_gui_next; // payload: name of this fake scene +extern uint16_t SCENE_SELECTION; // command +extern std::string scene_name_selection; // payload: name of this fake default scene +extern uint16_t SCENE_BACK_TO_PREVIOUS_GUI_LIST; // command +extern std::string scene_back_to_previous_gui_list; // payload: name of this fake scene +extern uint16_t GUI_PREV; // command +extern std::string scene_gui_prev; // payload: name of this fake scene +extern uint16_t GUI_NEXT; // command +extern std::string scene_gui_next; // payload: name of this fake scene extern std::map key_repeatModes_default; extern std::map key_commands_short_default;