navigate with pageIndicator and commands to prev and next gui

This commit is contained in:
KlausMu 2024-04-09 12:34:29 +02:00 committed by Klaus Musch
parent 9669d15c3c
commit ef162cde24
7 changed files with 90 additions and 8 deletions

View file

@ -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) {

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -1,6 +1,7 @@
#include <string>
#include <lvgl.h>
#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());

View file

@ -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<char, repeatModes> key_repeatModes_default;
std::map<char, uint16_t> 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}));
}

View file

@ -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<char, repeatModes> key_repeatModes_default;
extern std::map<char, uint16_t> key_commands_short_default;