support of "showSpecificGUI" in sceneHandler

This commit is contained in:
KlausMu 2024-04-23 14:37:16 +02:00 committed by Klaus Musch
parent 267e39bf93
commit 749f13417e
6 changed files with 70 additions and 76 deletions

View file

@ -104,7 +104,7 @@ static void tabview_animation_ready_cb(lv_anim_t* a) {
void tabview_tab_changed_event_cb(lv_event_t* e) {
if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {
int newTabID = lv_tabview_get_tab_active((lv_obj_t*)lv_event_get_target(e));
int newTabID = lv_tabview_get_tab_act((lv_obj_t*)lv_event_get_target(e));
// 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
@ -313,7 +313,7 @@ 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
// 3. after gui list has changed (called by handleScene()), when switching between main_gui_list and scene specific list. Will show first GUi in list
void guis_doTabCreationAfterGUIlistChanged(GUIlists newGUIlist) {
gui_memoryOptimizer_afterGUIlistChanged(&tabview, &panel, &img1, &img2, newGUIlist);
doLogMemoryUsage();

View file

@ -168,8 +168,8 @@ 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_active()->size() -1) {
return get_gui_list_active()->at(index);
} else if (index <= get_gui_list_active_withFallback()->size() -1) {
return get_gui_list_active_withFallback()->at(index);
} else {
return "";
}
@ -210,10 +210,10 @@ void setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(int gui_list_index, t_gu
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[1] = {NULL, "", get_gui_list_active_withFallback()->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) {
} else if (gui_list_index == get_gui_list_active_withFallback()->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};
@ -233,9 +233,9 @@ void setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(int gui_list_index, t_gu
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};
gui_state->gui_on_tab[0] = {NULL, "", get_gui_list_active_withFallback()->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[1] = {NULL, "", get_gui_list_active_withFallback()->size() >= 2 ? 1 : -1};
gui_state->gui_on_tab[2] = {NULL, "", -1};
gui_state->activeTabID = 0;
}
@ -268,7 +268,7 @@ void setGUIlistIndicesToBeShown_afterSlide(t_gui_state *gui_state) {
} else {
oldListIndex = gui_state->gui_on_tab[1].gui_list_index_previous;
}
if (oldListIndex == get_gui_list_active()->size() -2) {
if (oldListIndex == get_gui_list_active_withFallback()->size() -2) {
// next state is the "last state"
gui_state->gui_on_tab[0] = {NULL, "", oldListIndex};
gui_state->gui_on_tab[1] = {NULL, "", oldListIndex +1};
@ -292,8 +292,8 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, t_gui_state *gui_state) {
create_new_tab(tabview, &gui_state->gui_on_tab[i]);
}
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);
if (get_gui_list_active_withFallback()->size() > 0) {
std::string nameOfNewActiveTab = get_gui_list_active_withFallback()->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 active tab
@ -305,24 +305,10 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, t_gui_state *gui_state) {
LV_IMG_DECLARE(gradientLeft);
LV_IMG_DECLARE(gradientRight);
void getBreadcrumpPosition(uint8_t* breadcrumpPosition, std::string nameOfGUI) {
*breadcrumpPosition = 0;
gui_list gui_list_active = get_gui_list_active();
uint8_t counter = 0;
for (std::vector<std::string>::iterator it = gui_list_active->begin() ; it != gui_list_active->end(); ++it) {
counter++;
if (*it == nameOfGUI) {
*breadcrumpPosition = counter;
return;
}
}
}
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_active()->size() == 0) {
if (get_gui_list_active_withFallback()->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);
@ -362,9 +348,9 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
uint8_t breadcrumpDotSize = 8; // should be an even number
uint8_t breadcrumpDotDistance = 2; // should be an even number
uint8_t breadcrumpMainGuiListLength = get_gui_list(MAIN_GUI_LIST)->size();
uint8_t breadcrumpMainGuiListLength = get_gui_list_withFallback(MAIN_GUI_LIST)->size();
int8_t breadcrumpMainGuiListStartPositionX = (-1) * (breadcrumpMainGuiListLength -1) * (breadcrumpDotSize + breadcrumpDotDistance) / 2;
uint8_t breadcrumpSceneGuiListLength = get_gui_list(SCENE_GUI_LIST)->size();
uint8_t breadcrumpSceneGuiListLength = get_gui_list_withFallback(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());
@ -389,11 +375,11 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
for (int i=0; i<3; i++) {
if (gui_state->gui_on_tab[i].gui_list_index != -1) {
nameOfGUI = gui_state->gui_on_tab[i].GUIname;
getBreadcrumpPosition(&breadcrumpPosition, nameOfGUI);
breadcrumpPosition = gui_state->gui_on_tab[i].gui_list_index +1;
// Create actual buttons for every tab
lv_obj_t* btn = lv_btn_create(panel);
if (nameOfGUI == gui_memoryOptimizer_getActiveGUIname()) {
if (i == gui_state->activeTabID) {
// 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);
@ -484,8 +470,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 ((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)) {
// 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_withFallback()->size()-1) || (gui_state->gui_on_tab[1].gui_list_index == get_gui_list_active_withFallback()->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);
@ -555,8 +541,8 @@ void gui_memoryOptimizer_onStartup(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_
// 1. find last used gui
int gui_list_index = -1;
// find index of gui_memoryOptimizer_getActiveGUIname() in gui_list_active
for (int i=0; i<get_gui_list_active()->size(); i++) {
if (get_gui_list_active()->at(i) == gui_memoryOptimizer_getActiveGUIname()) {
for (int i=0; i<get_gui_list_active_withFallback()->size(); i++) {
if (get_gui_list_active_withFallback()->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;
@ -564,7 +550,7 @@ void gui_memoryOptimizer_onStartup(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_
}
// 2. set gui_list_indices and the tab to be activated
if ((gui_list_index >= 0) && (gui_list_index < get_gui_list_active()->size())) {
if ((gui_list_index >= 0) && (gui_list_index < get_gui_list_active_withFallback()->size())) {
// gui was found
setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(gui_list_index, &gui_state);
@ -619,7 +605,7 @@ void gui_memoryOptimizer_afterSliding(lv_obj_t** tabview, lv_obj_t** panel, lv_o
}
// 3. after gui list has changed (called by handleScene()), when switching between main_gui_list and scene specific list
// 3. after gui list has changed (called by handleScene()), when switching between main_gui_list and scene specific list. Will show first GUi in list
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");
@ -646,7 +632,7 @@ void gui_memoryOptimizer_navigateToGUI(lv_obj_t** tabview, lv_obj_t** panel, lv_
Serial.printf("--- Will navigate to specific GUI\r\n");
if ( !((gui_list_index >= 0) && (gui_list_index < get_gui_list(GUIlist)->size()))) {
if ( !((gui_list_index >= 0) && (gui_list_index < get_gui_list_withFallback(GUIlist)->size()))) {
Serial.printf(" cannot navigate to GUI because gui_list_index \"%d\" is out of range\r\n", gui_list_index);
return;
}

View file

@ -5,6 +5,7 @@
#include "applicationInternal/scenes/sceneRegistry.h"
#include "applicationInternal/hardware/hardwarePresenter.h"
#include "applicationInternal/commandHandler.h"
#include "guis/gui_sceneSelection.h"
#include "scenes/scene__default.h"
void setLabelActiveScene() {
@ -13,7 +14,7 @@ void setLabelActiveScene() {
}
}
void navigateBackToSceneGUIlist();
void showSpecificGUI(GUIlists GUIlist, std::string GUIname);
void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") {
@ -23,7 +24,7 @@ void handleScene(uint16_t command, commandData commandData, std::string addition
// --- 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);
showSpecificGUI(MAIN_GUI_LIST, tabName_sceneSelection);
return;
}
@ -127,30 +128,38 @@ 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 = "") {
void showSpecificGUI(GUIlists GUIlist, std::string GUIname) {
gui_list gui_list_for_search = get_gui_list_withFallback(GUIlist);
auto current = commandData.commandPayloads.begin();
std::string GUIname = *current;
// 1. check if the gui is known in the main_gui_list
// 1. search for gui in the 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);
for (int i=0; i < gui_list_for_search->size(); i++) {
if (gui_list_for_search->at(i) == GUIname) {
Serial.printf("showSpecificGUI: found GUI with name \"%s\" in %s at position %d\r\n", GUIname.c_str(), GUIlist == MAIN_GUI_LIST ? "\"main_gui_list\"" : "\"scene gui list\"", 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);
if ((gui_list_index >= 0) && (gui_list_index < gui_list_for_search->size())) {
guis_doTabCreationForSpecificGUI(GUIlist, 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());
Serial.printf("showSpecificGUI: GUI with name \"%s\" was not found in gui list %s. Cannot navigate to that GUI\r\n", GUIname.c_str(), GUIlist == MAIN_GUI_LIST ? "\"main_gui_list\"" : "\"scene gui list\"");
return;
}
}
void handleGUI(uint16_t command, commandData commandData, std::string additionalPayload = "") {
auto current = commandData.commandPayloads.begin();
GUIlists GUIlist = (GUIlists)std::stoi(*current);
current = std::next(current, 1);
std::string GUIname = *current;
showSpecificGUI(GUIlist, GUIname);
}

View file

@ -183,11 +183,10 @@ uint16_t get_command_long(std::string sceneName, char keyChar) {
}
gui_list get_gui_list(GUIlists gui_list) {
gui_list get_gui_list_withFallback(GUIlists gui_list) {
try {
// 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 gui_list == MAIN_GUI_LIST, then we want the main_gui_list, either if a scene is active or not.
// If gui_list == SCENE_GUI_LIST, then we want the scene gui list. If none is defined, return main_gui_list as fallback.
if (gui_list == MAIN_GUI_LIST) {
return &main_gui_list;
@ -214,8 +213,23 @@ gui_list get_gui_list(GUIlists gui_list) {
}
}
gui_list get_gui_list_active() {
return get_gui_list(gui_memoryOptimizer_getActiveGUIlist());
gui_list get_gui_list_active_withFallback() {
return get_gui_list_withFallback(gui_memoryOptimizer_getActiveGUIlist());
}
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;
}
}
uint16_t get_activate_scene_command(std::string sceneName) {
@ -239,21 +253,6 @@ 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;
}

View file

@ -31,10 +31,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);
gui_list get_gui_list_withFallback(GUIlists gui_list);
gui_list get_gui_list_active_withFallback();
bool get_scene_has_gui_list(std::string sceneName);
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);

View file

@ -184,5 +184,5 @@ void register_gui_smarthome(void){
& key_commands_long_smarthome
);
register_command(&GUI_SMARTHOME_ACTIVATE, makeCommandData(GUI, {std::string(tabName_smarthome)}));
register_command(&GUI_SMARTHOME_ACTIVATE, makeCommandData(GUI, {std::to_string(MAIN_GUI_LIST), std::string(tabName_smarthome)}));
}