diff --git a/Platformio/src/applicationInternal/gui/guiBase.cpp b/Platformio/src/applicationInternal/gui/guiBase.cpp index 5f04faf..ef0c1ca 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.cpp +++ b/Platformio/src/applicationInternal/gui/guiBase.cpp @@ -35,6 +35,18 @@ void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList); // Helper Functions ----------------------------------------------------------------------------------------------------------------------- +// callback when pageIndicator prev or next was clicked +void pageIndicator_navigate_event_cb(lv_event_t* e) { + lv_obj_t* target = lv_event_get_target(e); + + int user_data = (intptr_t)(target->user_data); + if (user_data == 0) { + executeCommand(GUI_PREV); + } else if (user_data == 1) { + executeCommand(GUI_NEXT); + } +} + // callback when sceneLabel or pageIndicator was clicked void sceneLabel_or_pageIndicator_event_cb(lv_event_t* e) { Serial.println("- Scene selection: sceneLabel or pageIndicator clicked received for navigating to scene selection page"); @@ -309,7 +321,7 @@ void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList) { doLogMemoryUsage(); } -void setActiveTab(uint32_t index, lv_anim_enable_t anim_en) { +void setActiveTab(uint32_t index, lv_anim_enable_t anim_en, bool send_tab_changed_event) { // unsigned long startTime = millis(); if (anim_en == LV_ANIM_ON) { lv_tabview_set_active(tabview, index, LV_ANIM_ON); @@ -322,6 +334,10 @@ void setActiveTab(uint32_t index, lv_anim_enable_t anim_en) { // lv_timer_handler(); // log_memory(); } + + if (send_tab_changed_event) { + lv_event_send(tabview, LV_EVENT_VALUE_CHANGED, NULL); + } } void showWiFiConnected(bool connected) { diff --git a/Platformio/src/applicationInternal/gui/guiBase.h b/Platformio/src/applicationInternal/gui/guiBase.h index 3ef5e6e..d78cffa 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.h +++ b/Platformio/src/applicationInternal/gui/guiBase.h @@ -33,7 +33,8 @@ void gui_loop(void); 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 setActiveTab(uint32_t index, lv_anim_enable_t anim_en); +void pageIndicator_navigate_event_cb(lv_event_t* e); +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 diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp index 053c129..a401ecf 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp @@ -13,6 +13,23 @@ 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}; +bool gui_memoryOptimizer_isTabIDInMemory(int tabID) { + // range check + if ((tabID < 0) || (tabID >= 3)) { + return false; + } + return (tabs_in_memory[tabID].listIndex != -1); +} + +bool gui_memoryOptimizer_isGUInameInMemory(std::string guiName) { + for (uint8_t index=0; index <= 2; index++) { + if (tabs_in_memory[index].guiName == guiName) { + return true; + } + } + return false; +} + void notify_active_tabs_before_delete() { Serial.printf(" Will notify tabs about deletion\r\n"); std::string nameOfTab; @@ -311,6 +328,21 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv if (nameOfTab == get_currentGUIname()) { 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)) { + // 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); + lv_obj_set_user_data(btn,(void *)(intptr_t)0); + lv_obj_add_event_cb(btn, pageIndicator_navigate_event_cb, LV_EVENT_CLICKED, NULL); + + } else if (i==1 || i==2) { + // this is the button on the next tab, which can be seen on the active tab + // activate click to next tab + lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_user_data(btn,(void *)(intptr_t)1); + lv_obj_add_event_cb(btn, pageIndicator_navigate_event_cb, LV_EVENT_CLICKED, NULL); + } lv_obj_set_size(btn, 150, lv_pct(100)); lv_obj_remove_style(btn, NULL, LV_STATE_PRESSED); diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h index ddf4372..83a87c4 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h @@ -2,3 +2,5 @@ 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); +bool gui_memoryOptimizer_isTabIDInMemory(int tabID); +bool gui_memoryOptimizer_isGUInameInMemory(std::string guiName); diff --git a/Platformio/src/applicationInternal/scenes/sceneHandler.cpp b/Platformio/src/applicationInternal/scenes/sceneHandler.cpp index b846e44..8e35b94 100644 --- a/Platformio/src/applicationInternal/scenes/sceneHandler.cpp +++ b/Platformio/src/applicationInternal/scenes/sceneHandler.cpp @@ -1,6 +1,7 @@ #include #include #include "applicationInternal/gui/guiBase.h" +#include "applicationInternal/gui/guiMemoryOptimizer.h" #include "applicationInternal/scenes/sceneRegistry.h" #include "applicationInternal/hardware/hardwarePresenter.h" #include "applicationInternal/commandHandler.h" @@ -29,6 +30,28 @@ void handleScene(uint16_t command, commandData commandData, std::string addition 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) { + 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); + } + + } else if (scene_name == scene_gui_next) { + if (!gui_memoryOptimizer_isTabIDInMemory(currentTabID +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); + } + + } + return; + } + // 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()); diff --git a/Platformio/src/scenes/scene__default.cpp b/Platformio/src/scenes/scene__default.cpp index 6228df3..848aafe 100644 --- a/Platformio/src/scenes/scene__default.cpp +++ b/Platformio/src/scenes/scene__default.cpp @@ -14,6 +14,10 @@ uint16_t SCENE_SELECTION; std::string scene_name_selection = "sceneSelection"; +uint16_t GUI_PREV; +uint16_t GUI_NEXT; +std::string scene_gui_prev = "GUI_prev"; +std::string scene_gui_next = "GUI_next"; std::map key_repeatModes_default; std::map key_commands_short_default; @@ -44,7 +48,7 @@ void register_scene_defaultKeys(void) { /*{KEY_STOP, COMMAND_UNKNOWN }, {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, COMMAND_UNKNOWN }, {KEY_OK, COMMAND_UNKNOWN }, {KEY_RIGHT, 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 },*/ @@ -57,6 +61,8 @@ void register_scene_defaultKeys(void) { }; - register_command(&SCENE_SELECTION , makeCommandData(SCENE, {scene_name_selection})); + 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})); } diff --git a/Platformio/src/scenes/scene__default.h b/Platformio/src/scenes/scene__default.h index 2322716..7078a2f 100644 --- a/Platformio/src/scenes/scene__default.h +++ b/Platformio/src/scenes/scene__default.h @@ -7,7 +7,11 @@ #include "applicationInternal/scenes/sceneRegistry.h" extern uint16_t SCENE_SELECTION; // command -extern std::string scene_name_selection; // name of this fake default scene +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 std::map key_repeatModes_default; extern std::map key_commands_short_default;