From 7dfc3bd664fef27cb4e230b879f67edb4089c2dd Mon Sep 17 00:00:00 2001 From: KlausMu Date: Tue, 9 Apr 2024 12:34:29 +0200 Subject: [PATCH 1/2] navigate with pageIndicator and commands to prev and next gui --- .../src/applicationInternal/gui/guiBase.cpp | 22 ++++++++++--- .../src/applicationInternal/gui/guiBase.h | 3 +- .../gui/guiMemoryOptimizer.cpp | 32 +++++++++++++++++++ .../gui/guiMemoryOptimizer.h | 2 ++ .../scenes/sceneHandler.cpp | 23 +++++++++++++ Platformio/src/scenes/scene__default.cpp | 10 ++++-- Platformio/src/scenes/scene__default.h | 6 +++- 7 files changed, 90 insertions(+), 8 deletions(-) diff --git a/Platformio/src/applicationInternal/gui/guiBase.cpp b/Platformio/src/applicationInternal/gui/guiBase.cpp index 1ded520e..b96d2327 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.cpp +++ b/Platformio/src/applicationInternal/gui/guiBase.cpp @@ -33,6 +33,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"); @@ -100,9 +112,7 @@ void tabview_tab_changed_event_cb(lv_event_t* e) { // 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); - // https://docs.lvgl.io/8.3/overview/animation.html?highlight=lv_anim_get#_CPPv411lv_anim_getPv18lv_anim_exec_xcb_t - // (lv_anim_exec_xcb_t) lv_obj_set_x does not find an animation. NULL is good as well. - lv_anim_t* anim = lv_anim_get(tabContainer, NULL); // (lv_anim_exec_xcb_t) lv_obj_set_x); + lv_anim_t* anim = lv_anim_get(tabContainer, NULL); 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 @@ -305,7 +315,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_act(tabview, index, LV_ANIM_ON); @@ -318,6 +328,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 20c8f84c..eb7ceab3 100644 --- a/Platformio/src/applicationInternal/gui/guiBase.h +++ b/Platformio/src/applicationInternal/gui/guiBase.h @@ -31,7 +31,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 913a15a7..bf77aa57 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(u_int8_t 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; @@ -309,6 +326,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 ddf43728..fdd688e4 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(u_int8_t 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 b846e44c..8e35b943 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 6228df31..848aafed 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 2322716c..7078a2f5 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; From 8f0a4b343777829134720542cf0d4c9900829403 Mon Sep 17 00:00:00 2001 From: KlausMu Date: Tue, 9 Apr 2024 12:49:47 +0200 Subject: [PATCH 2/2] changed u_int8_t to int due to consistancy and for mingw --- Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp | 2 +- Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp index bf77aa57..8c03a70f 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.cpp @@ -13,7 +13,7 @@ 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(u_int8_t tabID) { +bool gui_memoryOptimizer_isTabIDInMemory(int tabID) { // range check if ((tabID < 0) || (tabID >= 3)) { return false; diff --git a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h index fdd688e4..83a87c49 100644 --- a/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h +++ b/Platformio/src/applicationInternal/gui/guiMemoryOptimizer.h @@ -2,5 +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(u_int8_t tabID); +bool gui_memoryOptimizer_isTabIDInMemory(int tabID); bool gui_memoryOptimizer_isGUInameInMemory(std::string guiName);