navigate to specific GUI and back to last position in previous gui list

This commit is contained in:
KlausMu 2024-04-22 17:12:47 +02:00 committed by Klaus Musch
parent 5a420c381a
commit d833827fab
22 changed files with 320 additions and 54 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -94,6 +94,7 @@ extern uint16_t KEYBOARD_VOLUME_DECREMENT;
enum commandHandlers {
SPECIAL,
SCENE,
GUI,
IR,
#if (ENABLE_WIFI_AND_MQTT == 1)
MQTT,

View file

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

View file

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

View file

@ -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<breadcrumpLength; j++) {
// create a breadcrump dot for each gui in the main_gui_list
for (int j=0; j<breadcrumpMainGuiListLength; j++) {
lv_obj_t* dot = lv_obj_create(btn);
lv_obj_set_size(dot, breadcrumpDotSize, breadcrumpDotSize);
lv_obj_set_style_radius(dot, LV_RADIUS_CIRCLE, LV_PART_MAIN);
// hightlight dot if it is the one for the currently active tab
if (j == (breadcrumpPosition-1)) {
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 200), LV_PART_MAIN);
#if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
if ( ((gui_memoryOptimizer_getActiveGUIlist() == MAIN_GUI_LIST) || !get_scene_has_gui_list(gui_memoryOptimizer_getActiveSceneName()))
#else
if ( true
#endif
&& (j == (breadcrumpPosition-1))) {
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 255), LV_PART_MAIN);
} else if ((gui_memoryOptimizer_getActiveGUIlist() == SCENE_GUI_LIST) && get_scene_has_gui_list(gui_memoryOptimizer_getActiveSceneName()) && (j == gui_memoryOptimizer_getLastActiveGUIlistIndex())) {
// hightlight dot a little bit if it is at least the one which was last active in the other gui list
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 140), LV_PART_MAIN);
} else {
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 100), LV_PART_MAIN);
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 30), LV_PART_MAIN);
}
lv_obj_align(dot, LV_ALIGN_TOP_MID, breadcrumpStartPositionX +j*(breadcrumpDotSize + breadcrumpDotDistance), -6);
lv_obj_align(dot, LV_ALIGN_TOP_MID, breadcrumpMainGuiListStartPositionX +j*(breadcrumpDotSize + breadcrumpDotDistance), breadcrumpMainGuiList_yPos);
// this dot needs to get clickable again
lv_obj_set_user_data(dot,(void *)(intptr_t)1);
lv_obj_add_flag(dot, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_flag(dot, LV_OBJ_FLAG_EVENT_BUBBLE);
}
// create a breadcrump dot for each gui in the scene gui list, if there is one
if (show_scene_gui_list) {
for (int j=0; j<breadcrumpSceneGuiListLength; j++) {
lv_obj_t* dot = lv_obj_create(btn);
lv_obj_set_size(dot, breadcrumpDotSize, breadcrumpDotSize);
lv_obj_set_style_radius(dot, LV_RADIUS_CIRCLE, LV_PART_MAIN);
if ((gui_memoryOptimizer_getActiveGUIlist() == SCENE_GUI_LIST) && (j == (breadcrumpPosition-1))) {
// hightlight dot if it is the one for the currently active tab
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 255), LV_PART_MAIN);
} else if ((gui_memoryOptimizer_getActiveGUIlist() == MAIN_GUI_LIST) && (j == gui_memoryOptimizer_getLastActiveGUIlistIndex())) {
// hightlight dot a little bit if it is at least the one which was last active in the other gui list
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 140), LV_PART_MAIN);
} else {
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 30), LV_PART_MAIN);
}
lv_obj_align(dot, LV_ALIGN_TOP_MID, breadcrumpSceneGuiListStartPositionX +j*(breadcrumpDotSize + breadcrumpDotDistance), breadcrumpSceneGuiList_yPos);
// this dot needs to get clickable again
lv_obj_set_user_data(dot,(void *)(intptr_t)1);
lv_obj_add_flag(dot, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_flag(dot, LV_OBJ_FLAG_EVENT_BUBBLE);
}
}
// create a label for nameOfGUI
lv_obj_t* label = lv_label_create(btn);
lv_obj_set_style_text_font(label, &lv_font_montserrat_10, LV_PART_MAIN);
lv_label_set_text_fmt(label, "%s", nameOfGUI.c_str());
lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, 6);
lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, nameOfGUI_yPos);
}
}
@ -474,15 +539,19 @@ void gui_memoryOptimizer_notifyAndClear(lv_obj_t** tabview, lv_obj_t** panel, lv
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);
// 1. tab creation on startup (called by init_gui())
// find the position of the current GUI in the gui list which was active last (both were automatically saved in the preferences)
void gui_memoryOptimizer_onStartup(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2) {
Serial.printf("Startup: try to resume at scene \"%s\" with GUI \"%s\"\r\n", gui_memoryOptimizer_getActiveSceneName().c_str(), gui_memoryOptimizer_getActiveGUIname().c_str());
// Get last state from preferences and save it in gui_state
// So it is ok to call them without using the return values.
gui_memoryOptimizer_getActiveSceneName();
gui_memoryOptimizer_getActiveGUIname();
gui_memoryOptimizer_getActiveGUIlist();
gui_memoryOptimizer_getLastActiveGUIlistIndex();
// 1. find last used gui
int gui_list_index = -1;
// find index of gui_memoryOptimizer_getActiveGUIname() in gui_list_active
@ -512,6 +581,7 @@ void gui_memoryOptimizer_onStartup(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_
}
// 2. tab creation after sliding (called by tabview_tab_changed_event_cb())
void gui_memoryOptimizer_afterSliding(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, int newTabID) {
// Here the magic for dynamic creation and deletion of lvgl objects happens to keep memory usage low.
@ -546,12 +616,19 @@ void gui_memoryOptimizer_afterSliding(lv_obj_t** tabview, lv_obj_t** panel, lv_o
// 3. create content
gui_memoryOptimizer_doContentCreation(tabview, panel, img1, img2, &gui_state);
}
// 3. after gui list has changed (called by handleScene()), when switching between main_gui_list and scene specific 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");
if (gui_state.last_active_gui_list != newGUIlist) {
// 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);
@ -564,6 +641,58 @@ void gui_memoryOptimizer_afterGUIlistChanged(lv_obj_t** tabview, lv_obj_t** pane
}
// 4. navigate to a specific GUI in gui_list
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) {
Serial.printf("--- Will navigate to specific GUI\r\n");
if ( !((gui_list_index >= 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");
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,6 +5,7 @@
#include <map>
#include <vector>
#include "applicationInternal/keys.h"
#include "applicationInternal/gui/guiMemoryOptimizer.h"
typedef std::vector<std::string> t_gui_list;
typedef std::vector<std::string> 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);

View file

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

View file

@ -3,4 +3,5 @@
#include <lvgl.h>
const char * const tabName_smarthome = "Smart Home";
extern uint16_t GUI_SMARTHOME_ACTIVATE;
void register_gui_smarthome(void);

View file

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

View file

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

View file

@ -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<char, repeatModes> 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}));
}

View file

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