Merge branch 'main' into lvgl_9.1
This commit is contained in:
commit
d69913c323
29 changed files with 977 additions and 450 deletions
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
Preferences preferences;
|
Preferences preferences;
|
||||||
|
|
||||||
std::string currentScene;
|
std::string activeScene;
|
||||||
std::string currentGUIname;
|
std::string activeGUIname;
|
||||||
|
int activeGUIlist;
|
||||||
|
int lastActiveGUIlistIndex;
|
||||||
|
|
||||||
void init_preferences_HAL(void) {
|
void init_preferences_HAL(void) {
|
||||||
// Restore settings from internal flash memory
|
// Restore settings from internal flash memory
|
||||||
|
@ -17,10 +19,12 @@ void init_preferences_HAL(void) {
|
||||||
// from tft.h
|
// from tft.h
|
||||||
set_backlightBrightness_HAL(preferences.getUChar("blBrightness"));
|
set_backlightBrightness_HAL(preferences.getUChar("blBrightness"));
|
||||||
// from here
|
// from here
|
||||||
currentScene = std::string(preferences.getString("currentScene").c_str());
|
activeScene = std::string(preferences.getString("currentScene").c_str());
|
||||||
currentGUIname = std::string(preferences.getString("currentGUIname").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_currentGUIname().c_str(), get_currentScene().c_str());
|
// Serial.printf("Preferences restored: brightness %d, GUI %s, scene %s\r\n", get_backlightBrightness_HAL(), get_activeGUIname().c_str(), get_activeScene().c_str());
|
||||||
} else {
|
} else {
|
||||||
// Serial.printf("No preferences to restore\r\n");
|
// Serial.printf("No preferences to restore\r\n");
|
||||||
}
|
}
|
||||||
|
@ -35,23 +39,37 @@ void save_preferences_HAL(void) {
|
||||||
preferences.putUInt("slpTimeout", get_sleepTimeout_HAL());
|
preferences.putUInt("slpTimeout", get_sleepTimeout_HAL());
|
||||||
preferences.putUChar("blBrightness", get_backlightBrightness_HAL());
|
preferences.putUChar("blBrightness", get_backlightBrightness_HAL());
|
||||||
// from here
|
// from here
|
||||||
preferences.putString("currentScene", currentScene.c_str());
|
preferences.putString("currentScene", activeScene.c_str());
|
||||||
preferences.putString("currentGUIname", currentGUIname.c_str());
|
preferences.putString("currentGUIname", activeGUIname.c_str());
|
||||||
|
preferences.putInt("currentGUIlist", activeGUIlist);
|
||||||
|
preferences.putInt("lastActiveIndex", lastActiveGUIlistIndex);
|
||||||
if (!preferences.getBool("alreadySetUp")) {
|
if (!preferences.getBool("alreadySetUp")) {
|
||||||
preferences.putBool("alreadySetUp", true);
|
preferences.putBool("alreadySetUp", true);
|
||||||
}
|
}
|
||||||
preferences.end();
|
preferences.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_currentScene_HAL() {
|
std::string get_activeScene_HAL() {
|
||||||
return currentScene;
|
return activeScene;
|
||||||
}
|
}
|
||||||
void set_currentScene_HAL(std::string aCurrentScene) {
|
void set_activeScene_HAL(std::string anActiveScene) {
|
||||||
currentScene = aCurrentScene;
|
activeScene = anActiveScene;
|
||||||
}
|
}
|
||||||
std::string get_currentGUIname_HAL(){
|
std::string get_activeGUIname_HAL(){
|
||||||
return currentGUIname;
|
return activeGUIname;
|
||||||
}
|
}
|
||||||
void set_currentGUIname_HAL(std::string aCurrentGUIname) {
|
void set_activeGUIname_HAL(std::string anActiveGUIname) {
|
||||||
currentGUIname = aCurrentGUIname;
|
activeGUIname = anActiveGUIname;
|
||||||
|
}
|
||||||
|
int get_activeGUIlist_HAL() {
|
||||||
|
return activeGUIlist;
|
||||||
|
}
|
||||||
|
void set_activeGUIlist_HAL(int anActiveGUIlist) {
|
||||||
|
activeGUIlist = anActiveGUIlist;
|
||||||
|
}
|
||||||
|
int get_lastActiveGUIlistIndex_HAL() {
|
||||||
|
return lastActiveGUIlistIndex;
|
||||||
|
}
|
||||||
|
void set_lastActiveGUIlistIndex_HAL(int aGUIlistIndex) {
|
||||||
|
lastActiveGUIlistIndex = aGUIlistIndex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
void init_preferences_HAL(void);
|
void init_preferences_HAL(void);
|
||||||
void save_preferences_HAL(void);
|
void save_preferences_HAL(void);
|
||||||
|
|
||||||
std::string get_currentScene_HAL();
|
std::string get_activeScene_HAL();
|
||||||
void set_currentScene_HAL(std::string aCurrentScene);
|
void set_activeScene_HAL(std::string anActiveScene);
|
||||||
std::string get_currentGUIname_HAL();
|
std::string get_activeGUIname_HAL();
|
||||||
void set_currentGUIname_HAL(std::string aCurrentGUIname);
|
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);
|
||||||
|
|
|
@ -1,31 +1,58 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
std::string currentScene;
|
enum GUIlists {
|
||||||
std::string currentGUIname;
|
// MAIN_GUI_LIST: we are in the main_gui_list (with the scene selector as first gui), either if a scene is active or not
|
||||||
|
// SCENE_GUI_LIST: a scene is active and we are not in the main_gui_list. In that case, we try to use the scene specific gui list, if the scene defined one.
|
||||||
|
MAIN_GUI_LIST,
|
||||||
|
SCENE_GUI_LIST
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Possible example:
|
||||||
|
main_gui_list : "Scene selection", "Smart Home", "Settings", "IR Receiver"};
|
||||||
|
|
||||||
|
"Off" :
|
||||||
|
"TV" : "Numpad"
|
||||||
|
"Fire TV" : "Numpad", "Settings"
|
||||||
|
"Chromecast" :
|
||||||
|
"Apple TV" : "Apple TV", "Settings", "IR Receiver"
|
||||||
|
*/
|
||||||
|
std::string activeScene;
|
||||||
|
std::string activeGUIname;
|
||||||
|
int activeGUIlist;
|
||||||
|
int lastActiveGUIlistIndex;
|
||||||
|
|
||||||
void init_preferences_HAL(void) {
|
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;
|
||||||
|
lastActiveGUIlistIndex = 0;
|
||||||
}
|
}
|
||||||
void save_preferences_HAL(void) {
|
void save_preferences_HAL(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_currentScene_HAL() {
|
std::string get_activeScene_HAL() {
|
||||||
// if (currentScene == "") {
|
return activeScene;
|
||||||
// // set here something if you need it for a test at startup
|
|
||||||
// return "Apple TV";
|
|
||||||
// } else
|
|
||||||
{return currentScene;}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void set_currentScene_HAL(std::string aCurrentScene) {
|
void set_activeScene_HAL(std::string anActiveScene) {
|
||||||
currentScene = aCurrentScene;
|
activeScene = anActiveScene;
|
||||||
}
|
}
|
||||||
std::string get_currentGUIname_HAL(){
|
std::string get_activeGUIname_HAL(){
|
||||||
// if (currentGUIname == "") {
|
return activeGUIname;
|
||||||
// // set here something if you need it for a test at startup
|
|
||||||
// return "IR Receiver"; // "Numpad"; // "Apple TV";
|
|
||||||
// } else
|
|
||||||
{return currentGUIname;}
|
|
||||||
}
|
}
|
||||||
void set_currentGUIname_HAL(std::string aCurrentGUIname) {
|
void set_activeGUIname_HAL(std::string anActiveGUIname) {
|
||||||
currentGUIname = aCurrentGUIname;
|
activeGUIname = anActiveGUIname;
|
||||||
|
}
|
||||||
|
int get_activeGUIlist_HAL() {
|
||||||
|
return activeGUIlist;
|
||||||
|
}
|
||||||
|
void set_activeGUIlist_HAL(int anActiveGUIlist) {
|
||||||
|
activeGUIlist = anActiveGUIlist;
|
||||||
|
}
|
||||||
|
int get_lastActiveGUIlistIndex_HAL() {
|
||||||
|
return lastActiveGUIlistIndex;
|
||||||
|
}
|
||||||
|
void set_lastActiveGUIlistIndex_HAL(int aGUIlistIndex) {
|
||||||
|
lastActiveGUIlistIndex = aGUIlistIndex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
void init_preferences_HAL(void);
|
void init_preferences_HAL(void);
|
||||||
void save_preferences_HAL(void);
|
void save_preferences_HAL(void);
|
||||||
|
|
||||||
std::string get_currentScene_HAL();
|
std::string get_activeScene_HAL();
|
||||||
void set_currentScene_HAL(std::string aCurrentScene);
|
void set_activeScene_HAL(std::string anActiveScene);
|
||||||
std::string get_currentGUIname_HAL();
|
std::string get_activeGUIname_HAL();
|
||||||
void set_currentGUIname_HAL(std::string aCurrentGUIname);
|
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);
|
||||||
|
|
|
@ -232,6 +232,13 @@ void executeCommandWithData(uint16_t command, commandData commandData, std::stri
|
||||||
break;
|
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: {
|
case SPECIAL: {
|
||||||
if (command == MY_SPECIAL_COMMAND) {
|
if (command == MY_SPECIAL_COMMAND) {
|
||||||
// do your special command here
|
// do your special command here
|
||||||
|
|
|
@ -94,6 +94,7 @@ extern uint16_t KEYBOARD_VOLUME_DECREMENT;
|
||||||
enum commandHandlers {
|
enum commandHandlers {
|
||||||
SPECIAL,
|
SPECIAL,
|
||||||
SCENE,
|
SCENE,
|
||||||
|
GUI,
|
||||||
IR,
|
IR,
|
||||||
#if (ENABLE_WIFI_AND_MQTT == 1)
|
#if (ENABLE_WIFI_AND_MQTT == 1)
|
||||||
MQTT,
|
MQTT,
|
||||||
|
|
|
@ -15,8 +15,6 @@ lv_obj_t* BluetoothLabel = NULL;
|
||||||
lv_obj_t* BattPercentageLabel = NULL;
|
lv_obj_t* BattPercentageLabel = NULL;
|
||||||
lv_obj_t* BattIconLabel = NULL;
|
lv_obj_t* BattIconLabel = NULL;
|
||||||
lv_obj_t* SceneLabel = NULL;
|
lv_obj_t* SceneLabel = NULL;
|
||||||
uint32_t currentTabID = -1; // id of the current tab
|
|
||||||
uint32_t oldTabID = -1;
|
|
||||||
|
|
||||||
lv_obj_t* tabview = NULL;
|
lv_obj_t* tabview = NULL;
|
||||||
// page indicator
|
// page indicator
|
||||||
|
@ -30,8 +28,8 @@ lv_style_t panel_style;
|
||||||
lv_style_t style_red_border;
|
lv_style_t style_red_border;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void guis_doTabCreationAtStartup();
|
void guis_doTabCreationOnStartup();
|
||||||
void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList);
|
void guis_doTabCreationAfterSliding(int newTabID);
|
||||||
|
|
||||||
// Helper Functions -----------------------------------------------------------------------------------------------------------------------
|
// Helper Functions -----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -89,28 +87,28 @@ void tabview_content_is_scrolling_event_cb(lv_event_t* e){
|
||||||
// -----------------------
|
// -----------------------
|
||||||
static bool waitBeforeActionAfterSlidingAnimationEnded = false;
|
static bool waitBeforeActionAfterSlidingAnimationEnded = false;
|
||||||
static unsigned long waitBeforeActionAfterSlidingAnimationEnded_timerStart;
|
static unsigned long waitBeforeActionAfterSlidingAnimationEnded_timerStart;
|
||||||
|
static int newTabID_forLateTabCreation;
|
||||||
// This is the callback when the animation of the tab sliding ended
|
// This is the callback when the animation of the tab sliding ended
|
||||||
static void tabview_animation_ready_cb(lv_anim_t* a) {
|
static void tabview_animation_ready_cb(lv_anim_t* a) {
|
||||||
// Unfortunately, the animation has not completely ended here. We cannot do the recreation of the tabs here.
|
// Unfortunately, the animation has not completely ended here. We cannot do the recreation of the tabs here.
|
||||||
// We have to wait some more milliseconds or at least one cycle of lv_timer_handler();
|
// We have to wait some more milliseconds or at least one cycle of lv_timer_handler();
|
||||||
// calling lv_timer_handler(); here does not help
|
// calling lv_timer_handler(); here does not help
|
||||||
// lv_timer_handler();
|
// lv_timer_handler();
|
||||||
// guis_doAfterSliding(oldTabID, currentTabID, false);
|
// guis_doTabCreationAfterSliding(newTabID_forLateTabCreation);
|
||||||
|
|
||||||
waitBeforeActionAfterSlidingAnimationEnded = true;
|
waitBeforeActionAfterSlidingAnimationEnded = true;
|
||||||
waitBeforeActionAfterSlidingAnimationEnded_timerStart = millis();
|
waitBeforeActionAfterSlidingAnimationEnded_timerStart = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update currentTabID when a new tab is selected
|
// Update gui when a new tab is selected
|
||||||
// this is a callback if the tabview is changed (LV_EVENT_VALUE_CHANGED)
|
// this is a callback if the tabview is changed (LV_EVENT_VALUE_CHANGED)
|
||||||
// Sent when a new tab is selected by sliding or clicking the tab button. lv_tabview_get_tab_act(tabview) returns the zero based index of the current tab.
|
// Sent when a new tab is selected by sliding or clicking the tab button. lv_tabview_get_tab_act(tabview) returns the zero based index of the current tab.
|
||||||
void tabview_tab_changed_event_cb(lv_event_t* e) {
|
void tabview_tab_changed_event_cb(lv_event_t* e) {
|
||||||
if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {
|
if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {
|
||||||
|
|
||||||
oldTabID = currentTabID;
|
int newTabID = lv_tabview_get_tab_active((lv_obj_t*)lv_event_get_target(e));
|
||||||
currentTabID = lv_tabview_get_tab_active((lv_obj_t*)lv_event_get_target(e));
|
|
||||||
|
|
||||||
// Wait until the animation ended, then call "guis_doAfterSliding(oldTabID, currentTabID, false);"
|
// 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
|
// https://forum.lvgl.io/t/delete-a-tab-after-the-tabview-scroll-animation-is-complete/3155/4
|
||||||
lv_obj_t* myTabview = (lv_obj_t*)lv_event_get_target(e);
|
lv_obj_t* myTabview = (lv_obj_t*)lv_event_get_target(e);
|
||||||
lv_obj_t* tabContainer = lv_tabview_get_content(myTabview);
|
lv_obj_t* tabContainer = lv_tabview_get_content(myTabview);
|
||||||
|
@ -118,11 +116,12 @@ void tabview_tab_changed_event_cb(lv_event_t* e) {
|
||||||
if(anim) {
|
if(anim) {
|
||||||
// Swipe is not yet complete. User released the touch screen, an animation will bring it to the end.
|
// 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
|
// That's the normal (and only?) case for the tft touchscreen
|
||||||
|
newTabID_forLateTabCreation = newTabID;
|
||||||
lv_anim_set_completed_cb(anim, tabview_animation_ready_cb);
|
lv_anim_set_completed_cb(anim, tabview_animation_ready_cb);
|
||||||
} else {
|
} else {
|
||||||
// Swipe is complete, no additional animation is needed. Most likely only possible in simulator
|
// Swipe is complete, no additional animation is needed. Most likely only possible in simulator
|
||||||
Serial.println("Change of tab detected, without animation at the end. Will directly do my job after sliding.");
|
Serial.println("Change of tab detected, without animation at the end. Will directly do my job after sliding.");
|
||||||
guis_doAfterSliding(oldTabID, currentTabID, false);
|
guis_doTabCreationAfterSliding(newTabID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,8 +155,8 @@ void init_gui(void) {
|
||||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_black(), LV_PART_MAIN);
|
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_black(), LV_PART_MAIN);
|
||||||
// set default height and position of main widgets
|
// set default height and position of main widgets
|
||||||
setMainWidgetsHeightAndPosition();
|
setMainWidgetsHeightAndPosition();
|
||||||
// At startup, set current GUI according to get_currentGUIname(), and create the content of that tab (and the previous and the next) for the first time
|
// On startup, set current GUIname and GUIlist according to last state before going to sleep
|
||||||
guis_doTabCreationAtStartup();
|
guis_doTabCreationOnStartup();
|
||||||
// memoryUsage bar
|
// memoryUsage bar
|
||||||
init_gui_memoryUsage_bar();
|
init_gui_memoryUsage_bar();
|
||||||
// status bar
|
// status bar
|
||||||
|
@ -272,6 +271,7 @@ void init_gui_status_bar() {
|
||||||
lv_obj_align(SceneLabel, LV_ALIGN_TOP_MID, 0, labelsPositionTopStatusbar);
|
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_set_style_text_font(SceneLabel, &lv_font_montserrat_12, LV_PART_MAIN);
|
||||||
lv_obj_add_flag(SceneLabel, LV_OBJ_FLAG_CLICKABLE);
|
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);
|
lv_obj_add_event_cb(SceneLabel, sceneLabel_or_pageIndicator_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
// Battery ----------------------------------------------------------------------
|
// Battery ----------------------------------------------------------------------
|
||||||
|
@ -294,12 +294,12 @@ void gui_loop(void) {
|
||||||
waitBeforeActionAfterSlidingAnimationEnded = false;
|
waitBeforeActionAfterSlidingAnimationEnded = false;
|
||||||
} else if (waitOneLoop) {
|
} else if (waitOneLoop) {
|
||||||
waitOneLoop = false;
|
waitOneLoop = false;
|
||||||
guis_doAfterSliding(oldTabID, currentTabID, false);
|
guis_doTabCreationAfterSliding(newTabID_forLateTabCreation);
|
||||||
};
|
};
|
||||||
// // as alternative, we could wait some milliseconds. But one cycle of gui_loop() works well.
|
// // as alternative, we could wait some milliseconds. But one cycle of gui_loop() works well.
|
||||||
// if (waitBeforeActionAfterSlidingAnimationEnded) {
|
// if (waitBeforeActionAfterSlidingAnimationEnded) {
|
||||||
// if (millis() - waitBeforeActionAfterSlidingAnimationEnded_timerStart >= 5) {
|
// if (millis() - waitBeforeActionAfterSlidingAnimationEnded_timerStart >= 5) {
|
||||||
// guis_doAfterSliding(oldTabID, currentTabID, false);
|
// guis_doTabCreationAfterSliding(newTabID_forLateTabCreation);
|
||||||
// waitBeforeActionAfterSlidingAnimationEnded = false;
|
// waitBeforeActionAfterSlidingAnimationEnded = false;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
@ -307,19 +307,35 @@ void gui_loop(void) {
|
||||||
lv_timer_handler();
|
lv_timer_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void guis_doTabCreationAtStartup() {
|
// ------------------------------------------------------------------------------------------------------------
|
||||||
gui_memoryOptimizer_prepare_startup();
|
// 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())
|
||||||
guis_doAfterSliding(-1, -1, false);
|
void guis_doTabCreationOnStartup() {
|
||||||
}
|
gui_memoryOptimizer_onStartup(&tabview, &panel, &img1, &img2);
|
||||||
|
|
||||||
void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList) {
|
|
||||||
// With parameter newGuiList it is signaled that we are changing from a scene specific list to the main list or vice versa
|
|
||||||
// In that case, we have to do special treatment because we are not simply sliding to the left or to the right, but we start newly with a different gui list.
|
|
||||||
gui_memoryOptimizer_doAfterSliding_deletionAndCreation(&tabview, oldTabID, newTabID, newGuiList, &panel, &img1, &img2);
|
|
||||||
|
|
||||||
doLogMemoryUsage();
|
doLogMemoryUsage();
|
||||||
}
|
}
|
||||||
|
// 2. tab creation after sliding (called by tabview_tab_changed_event_cb())
|
||||||
|
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. Will show first GUi in list
|
||||||
|
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) {
|
void setActiveTab(uint32_t index, lv_anim_enable_t anim_en, bool send_tab_changed_event) {
|
||||||
// unsigned long startTime = millis();
|
// unsigned long startTime = millis();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
#include "applicationInternal/gui/guiMemoryOptimizer.h"
|
||||||
|
|
||||||
// used by memoryUsage.cpp
|
// used by memoryUsage.cpp
|
||||||
extern lv_span_t* MemoryUsageSpanHeap;
|
extern lv_span_t* MemoryUsageSpanHeap;
|
||||||
|
@ -17,7 +18,6 @@ extern lv_style_t panel_style;
|
||||||
extern int tabviewTop;
|
extern int tabviewTop;
|
||||||
extern int tabviewHeight;
|
extern int tabviewHeight;
|
||||||
extern int panelHeight;
|
extern int panelHeight;
|
||||||
extern uint32_t currentTabID;
|
|
||||||
// used by almost all gui_*.cpp
|
// used by almost all gui_*.cpp
|
||||||
extern lv_color_t color_primary;
|
extern lv_color_t color_primary;
|
||||||
|
|
||||||
|
@ -26,18 +26,22 @@ extern lv_color_t color_primary;
|
||||||
extern lv_style_t style_red_border;
|
extern lv_style_t style_red_border;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// used by main.cpp and sceneHandler.cpp
|
// used by main.cpp
|
||||||
void init_gui(void);
|
void init_gui(void);
|
||||||
|
// used by main.cpp and sceneHandler.cpp
|
||||||
void gui_loop(void);
|
void gui_loop(void);
|
||||||
// used by guiMemoryOptimizer.cpp
|
// used by guiMemoryOptimizer.cpp
|
||||||
void tabview_content_is_scrolling_event_cb(lv_event_t* e);
|
void tabview_content_is_scrolling_event_cb(lv_event_t* e);
|
||||||
void tabview_tab_changed_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 sceneLabel_or_pageIndicator_event_cb(lv_event_t* e);
|
||||||
void pageIndicator_navigate_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);
|
void setActiveTab(uint32_t index, lv_anim_enable_t anim_en, bool send_tab_changed_event = false);
|
||||||
// used by memoryUsage.cpp
|
// used by memoryUsage.cpp
|
||||||
void showMemoryUsageBar(bool showBar);
|
void showMemoryUsageBar(bool showBar);
|
||||||
// used by commandHandler to show WiFi status
|
// used by commandHandler to show WiFi status
|
||||||
void showWiFiConnected(bool connected);
|
void showWiFiConnected(bool connected);
|
||||||
|
|
||||||
void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList);
|
|
||||||
|
|
|
@ -1,47 +1,101 @@
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include "applicationInternal/gui/guiBase.h"
|
#include "applicationInternal/gui/guiBase.h"
|
||||||
|
#include "applicationInternal/gui/guiMemoryOptimizer.h"
|
||||||
#include "applicationInternal/gui/guiRegistry.h"
|
#include "applicationInternal/gui/guiRegistry.h"
|
||||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
|
||||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||||
|
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||||
|
|
||||||
struct tab_in_memory {
|
struct t_gui_on_tab {
|
||||||
lv_obj_t* tab;
|
lv_obj_t* tab;
|
||||||
int listIndex;
|
std::string GUIname;
|
||||||
std::string guiName;
|
int gui_list_index;
|
||||||
|
int gui_list_index_previous;
|
||||||
};
|
};
|
||||||
tab_in_memory tabs_in_memory[3] = {{NULL, -1, ""}, {NULL, -1, ""}, {NULL, -1, ""}};
|
struct t_gui_state {
|
||||||
// holds the ids of the tabs we had in memory before, so that we can determine the next or previous id
|
// the next three and the last are saved in the preferenceStorage every time they change
|
||||||
int tabs_in_memory_previous_listIndex[3]= {-1 , -1, -1};
|
std::string activeScene_internalDontUse;
|
||||||
|
std::string activeGUIname_internalDontUse;
|
||||||
|
GUIlists activeGUIlist_internalDontUse;
|
||||||
|
// ---
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Both the gui_state and the preferenceStorage should know at any time the current state (scene, GUIname, and GUIlist)
|
||||||
|
// preferenceStorage should know it because when going to sleep, it should persist the state in NVM.
|
||||||
|
// So whenever values change, it should be done through these functions.
|
||||||
|
// On startup, the gui_state is set by gui_memoryOptimizer_onStartup()
|
||||||
|
std::string gui_memoryOptimizer_getActiveSceneName() {
|
||||||
|
gui_state.activeScene_internalDontUse = get_activeScene();
|
||||||
|
return gui_state.activeScene_internalDontUse;
|
||||||
|
}
|
||||||
|
void gui_memoryOptimizer_setActiveSceneName(std::string aSceneName) {
|
||||||
|
gui_state.activeScene_internalDontUse = aSceneName;
|
||||||
|
set_activeScene(aSceneName);
|
||||||
|
}
|
||||||
|
std::string gui_memoryOptimizer_getActiveGUIname() {
|
||||||
|
gui_state.activeGUIname_internalDontUse = get_activeGUIname();
|
||||||
|
return gui_state.activeGUIname_internalDontUse;
|
||||||
|
}
|
||||||
|
void gui_memoryOptimizer_setActiveGUIname(std::string aGUIname) {
|
||||||
|
gui_state.activeGUIname_internalDontUse = aGUIname;
|
||||||
|
set_activeGUIname(aGUIname);
|
||||||
|
}
|
||||||
|
GUIlists gui_memoryOptimizer_getActiveGUIlist() {
|
||||||
|
gui_state.activeGUIlist_internalDontUse = (GUIlists)get_activeGUIlist();
|
||||||
|
return gui_state.activeGUIlist_internalDontUse;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
bool gui_memoryOptimizer_isTabIDInMemory(int tabID) {
|
bool gui_memoryOptimizer_isTabIDInMemory(int tabID) {
|
||||||
// range check
|
// range check
|
||||||
if ((tabID < 0) || (tabID >= 3)) {
|
if ((tabID < 0) || (tabID >= 3)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (tabs_in_memory[tabID].listIndex != -1);
|
return (gui_state.gui_on_tab[tabID].gui_list_index != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gui_memoryOptimizer_isGUInameInMemory(std::string guiName) {
|
bool gui_memoryOptimizer_isGUInameInMemory(std::string GUIname) {
|
||||||
for (uint8_t index=0; index <= 2; index++) {
|
for (uint8_t index=0; index <= 2; index++) {
|
||||||
if (tabs_in_memory[index].guiName == guiName) {
|
if (gui_state.gui_on_tab[index].GUIname == GUIname) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify_active_tabs_before_delete() {
|
void notify_active_tabs_before_delete(t_gui_state *gui_state) {
|
||||||
Serial.printf(" Will notify tabs about deletion\r\n");
|
Serial.printf(" Will notify tabs about deletion\r\n");
|
||||||
std::string nameOfTab;
|
std::string nameOfTab;
|
||||||
for (int index=0; index <= 2; index++) {
|
for (int index=0; index <= 2; index++) {
|
||||||
if (tabs_in_memory[index].listIndex == -1) {
|
if (gui_state->gui_on_tab[index].gui_list_index == -1) {
|
||||||
Serial.printf(" Will not notify tab %d about deletion because it does not exist\r\n", index);
|
Serial.printf(" Will not notify tab %d about deletion because it does not exist\r\n", index);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For deletion, do not use the listIndex, but the name of the gui.
|
// For deletion, do not use the gui_list_index, but the name of the gui.
|
||||||
// The gui_list might have changed (when switching from a scene specific list to the main list or vice versa), so index could have changed as well.
|
// The gui_list might have changed (when switching from a scene specific list to the main list or vice versa), so index could have changed as well.
|
||||||
nameOfTab = tabs_in_memory[index].guiName;
|
nameOfTab = gui_state->gui_on_tab[index].GUIname;
|
||||||
if (nameOfTab == "") {
|
if (nameOfTab == "") {
|
||||||
Serial.printf(" Will not notify tab %d about deletion because it is not set\r\n", index);
|
Serial.printf(" Will not notify tab %d about deletion because it is not set\r\n", index);
|
||||||
} else if (registered_guis_byName_map.count(nameOfTab) == 0) {
|
} else if (registered_guis_byName_map.count(nameOfTab) == 0) {
|
||||||
|
@ -53,7 +107,7 @@ void notify_active_tabs_before_delete() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_tabview(lv_obj_t* tabview) {
|
void clear_tabview(lv_obj_t* tabview, t_gui_state *gui_state) {
|
||||||
if (tabview != NULL) {
|
if (tabview != NULL) {
|
||||||
// first remove events for the tabview
|
// first remove events for the tabview
|
||||||
lv_obj_remove_event_cb(tabview, tabview_tab_changed_event_cb);
|
lv_obj_remove_event_cb(tabview, tabview_tab_changed_event_cb);
|
||||||
|
@ -63,10 +117,10 @@ void clear_tabview(lv_obj_t* tabview) {
|
||||||
tabview = NULL;
|
tabview = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set struct tabs_in_memory to NULL
|
// the gui_list_index_previous is needed for setGUIlistIndicesToBeShown_afterSlide();
|
||||||
tabs_in_memory[0] = {NULL, -1, ""};
|
gui_state->gui_on_tab[0] = {NULL, "", -1, gui_state->gui_on_tab[0].gui_list_index};
|
||||||
tabs_in_memory[1] = {NULL, -1, ""};
|
gui_state->gui_on_tab[1] = {NULL, "", -1, gui_state->gui_on_tab[1].gui_list_index};
|
||||||
tabs_in_memory[2] = {NULL, -1, ""};
|
gui_state->gui_on_tab[2] = {NULL, "", -1, gui_state->gui_on_tab[2].gui_list_index};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,32 +170,31 @@ lv_obj_t* create_panel() {
|
||||||
std::string get_name_of_gui_to_be_shown(int index) {
|
std::string get_name_of_gui_to_be_shown(int index) {
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return "";
|
return "";
|
||||||
} else if (index <= get_gui_list(get_currentScene())->size() -1) {
|
} else if (index <= get_gui_list_active_withFallback()->size() -1) {
|
||||||
return get_gui_list(get_currentScene())->at(index);
|
return get_gui_list_active_withFallback()->at(index);
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_new_tab(lv_obj_t* tabview, uint32_t tabs_in_memory_index) {
|
void create_new_tab(lv_obj_t* tabview, t_gui_on_tab *gui_on_tab) {
|
||||||
std::string nameOfTab = get_name_of_gui_to_be_shown(tabs_in_memory[tabs_in_memory_index].listIndex);
|
std::string nameOfTab = get_name_of_gui_to_be_shown(gui_on_tab->gui_list_index);
|
||||||
|
|
||||||
if (nameOfTab == "") {
|
if (nameOfTab == "") {
|
||||||
Serial.printf(" Will not create new tab at index %d because no name was provided\r\n", tabs_in_memory_index);
|
Serial.printf(" Will not create new tab because no name was provided\r\n");
|
||||||
} else if (registered_guis_byName_map.count(nameOfTab) == 0) {
|
} else if (registered_guis_byName_map.count(nameOfTab) == 0) {
|
||||||
Serial.printf(" Will not create new tab at index %d because name %s was not found in registry\r\n", tabs_in_memory_index, nameOfTab.c_str());
|
Serial.printf(" Will not create new tab because name %s was not found in registry\r\n", nameOfTab.c_str());
|
||||||
} else {
|
} else {
|
||||||
Serial.printf(" Will create tab with name \"%s\" at index %d\r\n", nameOfTab.c_str(), tabs_in_memory_index);
|
Serial.printf(" Will create tab with name \"%s\" \r\n", nameOfTab.c_str());
|
||||||
// save name of tab for deletion later
|
// save name of tab for deletion later
|
||||||
tabs_in_memory[tabs_in_memory_index].guiName = nameOfTab;
|
gui_on_tab->GUIname = nameOfTab;
|
||||||
// create tab and save pointer to tab in tabs_in_memory
|
// create tab and save pointer to tab in gui_on_tab
|
||||||
tabs_in_memory[tabs_in_memory_index].tab = lv_tabview_add_tab(tabview, nameOfTab.c_str());
|
gui_on_tab->tab = lv_tabview_add_tab(tabview, nameOfTab.c_str());
|
||||||
// let the gui create it's content
|
// let the gui create it's content
|
||||||
registered_guis_byName_map.at(nameOfTab).this_create_tab_content(tabs_in_memory[tabs_in_memory_index].tab);
|
registered_guis_byName_map.at(nameOfTab).this_create_tab_content(gui_on_tab->tab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t newTabID) {
|
|
||||||
// create up to three tabs and the content of the tabs
|
// create up to three tabs and the content of the tabs
|
||||||
/*
|
/*
|
||||||
example: gui_list: 0 1 2 3 4
|
example: gui_list: 0 1 2 3 4
|
||||||
|
@ -152,126 +205,112 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n
|
||||||
2 3 4 1
|
2 3 4 1
|
||||||
3 4 -1 1 <- last state, special case
|
3 4 -1 1 <- last state, special case
|
||||||
*/
|
*/
|
||||||
|
void setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(int gui_list_index, t_gui_state *gui_state) {
|
||||||
int tabToBeActivated = -1;
|
// Set the gui_list_indeces to be shown for a specific gui_list_index
|
||||||
int oldListIndex = -1;
|
if (gui_list_index == 0) {
|
||||||
|
|
||||||
if ((oldTabID == -1) && (newTabID == -1)) {
|
|
||||||
// This is the initialization after the ESP32 has booted.
|
|
||||||
|
|
||||||
if ((tabs_in_memory_previous_listIndex[0] < get_gui_list(get_currentScene())->size()) && (tabs_in_memory_previous_listIndex[0] != -1)) {
|
|
||||||
// In gui_memoryOptimizer_prepare_startup, the index of get_currentGUIname() in gui_list was saved, if found.
|
|
||||||
// We can resume at this old state.
|
|
||||||
oldListIndex = tabs_in_memory_previous_listIndex[0] ;
|
|
||||||
if (oldListIndex == 0) {
|
|
||||||
// first state
|
// first state
|
||||||
Serial.printf(" Startup: will resume where we went to sleep with \"first state\"\r\n");
|
Serial.printf(" GUIlistIndices: will resume at specific index with \"first state\"\r\n");
|
||||||
tabs_in_memory[0] = {NULL, 0};
|
gui_state->gui_on_tab[0] = {NULL, "", 0};
|
||||||
// take care if there is only one gui in list
|
// take care if there is only one gui in list
|
||||||
tabs_in_memory[1] = {NULL, get_gui_list(get_currentScene())->size() >= 2 ? 1 : -1};
|
gui_state->gui_on_tab[1] = {NULL, "", get_gui_list_active_withFallback()->size() >= 2 ? 1 : -1};
|
||||||
tabs_in_memory[2] = {NULL, -1};
|
gui_state->gui_on_tab[2] = {NULL, "", -1};
|
||||||
tabToBeActivated = 0;
|
gui_state->activeTabID = 0;
|
||||||
} else if (oldListIndex == get_gui_list(get_currentScene())->size() -1) {
|
} else if (gui_list_index == get_gui_list_active_withFallback()->size() -1) {
|
||||||
// last state
|
// last state
|
||||||
Serial.printf(" Startup: will resume where we went to sleep with \"last state\"\r\n");
|
Serial.printf(" GUIlistIndices: will resume at specific index with \"last state\"\r\n");
|
||||||
tabs_in_memory[0] = {NULL, oldListIndex -1};
|
gui_state->gui_on_tab[0] = {NULL, "", gui_list_index -1};
|
||||||
tabs_in_memory[1] = {NULL, oldListIndex};
|
gui_state->gui_on_tab[1] = {NULL, "", gui_list_index};
|
||||||
tabs_in_memory[2] = {NULL, -1};
|
gui_state->gui_on_tab[2] = {NULL, "", -1};
|
||||||
tabToBeActivated = 1;
|
gui_state->activeTabID = 1;
|
||||||
} else {
|
} else {
|
||||||
// any other state
|
// any other state
|
||||||
Serial.printf(" Startup: will resume where we went to sleep with \"state between\"\r\n");
|
Serial.printf(" GUIlistIndices: will resume at specific index with \"state between\"\r\n");
|
||||||
tabs_in_memory[0] = {NULL, oldListIndex -1};
|
gui_state->gui_on_tab[0] = {NULL, "", gui_list_index -1};
|
||||||
tabs_in_memory[1] = {NULL, oldListIndex};
|
gui_state->gui_on_tab[1] = {NULL, "", gui_list_index};
|
||||||
tabs_in_memory[2] = {NULL, oldListIndex +1};
|
gui_state->gui_on_tab[2] = {NULL, "", gui_list_index +1};
|
||||||
tabToBeActivated = 1;
|
gui_state->activeTabID = 1;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
Serial.printf(" Startup: cannot resume old state, so we will show the first tabs from \"gui_list\" as initial state\r\n");
|
|
||||||
|
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
|
// take care if there is no gui in list
|
||||||
tabs_in_memory[0] = {NULL, get_gui_list(get_currentScene())->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
|
// take care if there is only one gui in list
|
||||||
tabs_in_memory[1] = {NULL, get_gui_list(get_currentScene())->size() >= 2 ? 1 : -1};
|
gui_state->gui_on_tab[1] = {NULL, "", get_gui_list_active_withFallback()->size() >= 2 ? 1 : -1};
|
||||||
tabs_in_memory[2] = {NULL, -1};
|
gui_state->gui_on_tab[2] = {NULL, "", -1};
|
||||||
tabToBeActivated = 0;
|
gui_state->activeTabID = 0;
|
||||||
}
|
}
|
||||||
} else if (oldTabID > newTabID) {
|
|
||||||
|
void setGUIlistIndicesToBeShown_afterSlide(t_gui_state *gui_state) {
|
||||||
|
int oldListIndex = -1;
|
||||||
|
|
||||||
|
if (gui_state->oldTabID > gui_state->activeTabID) {
|
||||||
// swipe to previous item in list
|
// swipe to previous item in list
|
||||||
Serial.printf(" Will swipe to previous item in list\r\n");
|
Serial.printf(" Will swipe to previous item in list\r\n");
|
||||||
oldListIndex = tabs_in_memory_previous_listIndex[1];
|
oldListIndex = gui_state->gui_on_tab[1].gui_list_index_previous;
|
||||||
if ((oldListIndex == 1)) {
|
if ((oldListIndex == 1)) {
|
||||||
// next state is the "first state"
|
// next state is the "first state"
|
||||||
tabs_in_memory[0] = {NULL, 0};
|
gui_state->gui_on_tab[0] = {NULL, "", 0};
|
||||||
tabs_in_memory[1] = {NULL, 1};
|
gui_state->gui_on_tab[1] = {NULL, "", 1};
|
||||||
tabs_in_memory[2] = {NULL, -1};
|
gui_state->gui_on_tab[2] = {NULL, "", -1};
|
||||||
tabToBeActivated = 0;
|
gui_state->activeTabID = 0;
|
||||||
} else {
|
} else {
|
||||||
tabs_in_memory[0] = {NULL, oldListIndex -2};
|
gui_state->gui_on_tab[0] = {NULL, "", oldListIndex -2};
|
||||||
tabs_in_memory[1] = {NULL, oldListIndex -1};
|
gui_state->gui_on_tab[1] = {NULL, "", oldListIndex -1};
|
||||||
tabs_in_memory[2] = {NULL, oldListIndex};
|
gui_state->gui_on_tab[2] = {NULL, "", oldListIndex};
|
||||||
tabToBeActivated = 1;
|
gui_state->activeTabID = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// swipe to next item in list
|
// swipe to next item in list
|
||||||
Serial.printf(" Will swipe to next item in list\r\n");
|
Serial.printf(" Will swipe to next item in list\r\n");
|
||||||
if (tabs_in_memory_previous_listIndex[2] == -1) {
|
if (gui_state->gui_on_tab[2].gui_list_index_previous == -1) {
|
||||||
// last state was the first state
|
// last state was the first state
|
||||||
oldListIndex = tabs_in_memory_previous_listIndex[0]; // is always 0
|
oldListIndex = gui_state->gui_on_tab[0].gui_list_index_previous; // is always 0
|
||||||
} else {
|
} else {
|
||||||
oldListIndex = tabs_in_memory_previous_listIndex[1];
|
oldListIndex = gui_state->gui_on_tab[1].gui_list_index_previous;
|
||||||
}
|
}
|
||||||
if (oldListIndex == get_gui_list(get_currentScene())->size() -2) {
|
if (oldListIndex == get_gui_list_active_withFallback()->size() -2) {
|
||||||
// next state is the "last state"
|
// next state is the "last state"
|
||||||
tabs_in_memory[0] = {NULL, oldListIndex};
|
gui_state->gui_on_tab[0] = {NULL, "", oldListIndex};
|
||||||
tabs_in_memory[1] = {NULL, oldListIndex +1};
|
gui_state->gui_on_tab[1] = {NULL, "", oldListIndex +1};
|
||||||
tabs_in_memory[2] = {NULL, -1};
|
gui_state->gui_on_tab[2] = {NULL, "", -1};
|
||||||
tabToBeActivated = 1;
|
gui_state->activeTabID = 1;
|
||||||
} else {
|
} else {
|
||||||
tabs_in_memory[0] = {NULL, oldListIndex};
|
gui_state->gui_on_tab[0] = {NULL, "", oldListIndex};
|
||||||
tabs_in_memory[1] = {NULL, oldListIndex +1};
|
gui_state->gui_on_tab[1] = {NULL, "", oldListIndex +1};
|
||||||
tabs_in_memory[2] = {NULL, oldListIndex +2};
|
gui_state->gui_on_tab[2] = {NULL, "", oldListIndex +2};
|
||||||
tabToBeActivated = 1;
|
gui_state->activeTabID = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void doTabCreation_strategyMax3(lv_obj_t* tabview, t_gui_state *gui_state) {
|
||||||
|
|
||||||
// create the tabs
|
// create the tabs
|
||||||
Serial.printf(" Will create tabs. List indices of the three tabs are %d, %d, %d, tab nr %d will be activated\r\n", tabs_in_memory[0].listIndex, tabs_in_memory[1].listIndex, tabs_in_memory[2].listIndex, tabToBeActivated);
|
Serial.printf(" Will create tabs. List indices of the three tabs are %d, %d, %d, tab nr %d will be activated\r\n", gui_state->gui_on_tab[0].gui_list_index, gui_state->gui_on_tab[1].gui_list_index, gui_state->gui_on_tab[2].gui_list_index, gui_state->activeTabID);
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
create_new_tab(tabview, i);
|
create_new_tab(tabview, &gui_state->gui_on_tab[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_gui_list(get_currentScene())->size() > 0) {
|
if (get_gui_list_active_withFallback()->size() > 0) {
|
||||||
std::string nameOfNewActiveTab = get_gui_list(get_currentScene())->at(tabs_in_memory[tabToBeActivated].listIndex);
|
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());
|
Serial.printf(" New visible tab is \"%s\"\r\n", nameOfNewActiveTab.c_str());
|
||||||
|
|
||||||
// set the tab we swiped to as active
|
// set active tab
|
||||||
setActiveTab(tabToBeActivated, LV_ANIM_OFF);
|
setActiveTab(gui_state->activeTabID, LV_ANIM_OFF);
|
||||||
set_currentGUIname(nameOfNewActiveTab);
|
gui_memoryOptimizer_setActiveGUIname(nameOfNewActiveTab);
|
||||||
currentTabID = tabToBeActivated;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LV_IMAGE_DECLARE(gradientLeft);
|
LV_IMAGE_DECLARE(gradientLeft);
|
||||||
LV_IMAGE_DECLARE(gradientRight);
|
LV_IMAGE_DECLARE(gradientRight);
|
||||||
|
|
||||||
void getBreadcrumpPosition(uint8_t* breadcrumpPosition, std::string nameOfTab) {
|
void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv_obj_t* img2, t_gui_state *gui_state) {
|
||||||
*breadcrumpPosition = 0;
|
|
||||||
|
|
||||||
gui_list currentGUIlist = get_gui_list(get_currentScene());
|
|
||||||
uint8_t counter = 0;
|
|
||||||
for (std::vector<std::string>::iterator it = currentGUIlist->begin() ; it != currentGUIlist->end(); ++it) {
|
|
||||||
counter++;
|
|
||||||
if (*it == nameOfTab) {
|
|
||||||
*breadcrumpPosition = counter;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv_obj_t* img2) {
|
|
||||||
Serial.printf(" Will fill panel with page indicators\r\n");
|
Serial.printf(" Will fill panel with page indicators\r\n");
|
||||||
|
|
||||||
if (get_gui_list(get_currentScene())->size() == 0) {
|
if (get_gui_list_active_withFallback()->size() == 0) {
|
||||||
Serial.printf(" no tab available, so no page indicators\r\n");
|
Serial.printf(" no tab available, so no page indicators\r\n");
|
||||||
// at least add the style
|
// at least add the style
|
||||||
lv_obj_add_style(panel, &panel_style, 0);
|
lv_obj_add_style(panel, &panel_style, 0);
|
||||||
|
@ -303,33 +342,52 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
|
||||||
btn = lv_button_create(panel);
|
btn = lv_button_create(panel);
|
||||||
lv_obj_remove_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
lv_obj_remove_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
||||||
lv_obj_set_size(btn, 150, lv_pct(100));
|
lv_obj_set_size(btn, 150, lv_pct(100));
|
||||||
if (tabs_in_memory[0].listIndex == 0) {
|
if (gui_state->gui_on_tab[0].gui_list_index == 0) {
|
||||||
lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN);
|
lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN);
|
||||||
} else {
|
} else {
|
||||||
lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN);
|
lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t breadcrumpLength = get_gui_list(get_currentScene())->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
|
uint8_t breadcrumpDotDistance = 2; // should be an even number
|
||||||
int8_t breadcrumpStartPositionX = (-1) * (breadcrumpLength -1) * (breadcrumpDotSize + breadcrumpDotDistance) / 2;
|
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_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());
|
||||||
|
#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
|
// create the panel content for the three guis (or less) which are currently in memory
|
||||||
std::string nameOfTab;
|
std::string nameOfGUI;
|
||||||
uint8_t breadcrumpPosition;
|
uint8_t breadcrumpPosition;
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
if (tabs_in_memory[i].listIndex != -1) {
|
if (gui_state->gui_on_tab[i].gui_list_index != -1) {
|
||||||
nameOfTab = tabs_in_memory[i].guiName;
|
nameOfGUI = gui_state->gui_on_tab[i].GUIname;
|
||||||
getBreadcrumpPosition(&breadcrumpPosition, nameOfTab);
|
breadcrumpPosition = gui_state->gui_on_tab[i].gui_list_index +1;
|
||||||
|
|
||||||
// Create actual buttons for every tab
|
// Create actual buttons for every tab
|
||||||
lv_obj_t* btn = lv_button_create(panel);
|
lv_obj_t* btn = lv_button_create(panel);
|
||||||
|
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
|
// only if this is the button for the currently active tab, make it clickable to get to scene selection gui
|
||||||
if (nameOfTab == get_currentGUIname()) {
|
|
||||||
lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
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);
|
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)) {
|
} else if ((i==0 || i==1) && (gui_state->gui_on_tab[i+1].gui_list_index != -1)) {
|
||||||
// this is the button on the previous tab, which can be seen on the active tab
|
// this is the button on the previous tab, which can be seen on the active tab
|
||||||
// activate click to prev tab
|
// activate click to prev tab
|
||||||
lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
@ -349,28 +407,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_shadow_width(btn, 0, LV_PART_MAIN);
|
||||||
lv_obj_set_style_bg_color(btn, color_primary, 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
|
// create a breadcrump dot for each gui in the main_gui_list
|
||||||
for (int j=0; j<breadcrumpLength; j++) {
|
for (int j=0; j<breadcrumpMainGuiListLength; j++) {
|
||||||
lv_obj_t* dot = lv_obj_create(btn);
|
lv_obj_t* dot = lv_obj_create(btn);
|
||||||
lv_obj_set_size(dot, breadcrumpDotSize, breadcrumpDotSize);
|
lv_obj_set_size(dot, breadcrumpDotSize, breadcrumpDotSize);
|
||||||
lv_obj_set_style_radius(dot, LV_RADIUS_CIRCLE, LV_PART_MAIN);
|
lv_obj_set_style_radius(dot, LV_RADIUS_CIRCLE, LV_PART_MAIN);
|
||||||
// hightlight dot if it is the one for the currently active tab
|
// hightlight dot if it is the one for the currently active tab
|
||||||
if (j == (breadcrumpPosition-1)) {
|
#if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
|
||||||
lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 200), LV_PART_MAIN);
|
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 {
|
} 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
|
// 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_CLICKABLE);
|
||||||
lv_obj_add_flag(dot, LV_OBJ_FLAG_EVENT_BUBBLE);
|
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_t* label = lv_label_create(btn);
|
||||||
lv_obj_set_style_text_font(label, &lv_font_montserrat_10, LV_PART_MAIN);
|
lv_obj_set_style_text_font(label, &lv_font_montserrat_10, LV_PART_MAIN);
|
||||||
lv_label_set_text_fmt(label, "%s", nameOfTab.c_str());
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,7 +473,7 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
|
||||||
lv_obj_remove_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
lv_obj_remove_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
||||||
lv_obj_set_size(btn, 150, lv_pct(100));
|
lv_obj_set_size(btn, 150, lv_pct(100));
|
||||||
// 4 at last position 4 at middle position only one tab available overall
|
// 4 at last position 4 at middle position only one tab available overall
|
||||||
if ((tabs_in_memory[2].listIndex == get_gui_list(get_currentScene())->size()-1) || (tabs_in_memory[1].listIndex == get_gui_list(get_currentScene())->size()-1) || (tabs_in_memory[1].listIndex == -1)) {
|
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);
|
lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN);
|
||||||
} else {
|
} else {
|
||||||
lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN);
|
lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN);
|
||||||
|
@ -423,71 +516,81 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_memoryOptimizer_prepare_startup() {
|
void gui_memoryOptimizer_notifyAndClear(lv_obj_t** tabview, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2, t_gui_state *gui_state) {
|
||||||
// find index of get_currentGUIname() in gui_list
|
|
||||||
for (int i=0; i<get_gui_list(get_currentScene())->size(); i++) {
|
|
||||||
if (get_gui_list(get_currentScene())->at(i) == get_currentGUIname()) {
|
|
||||||
Serial.printf("Startup: found GUI with name \"%s\" in \"gui_list\" at position %d\r\n", get_currentGUIname().c_str(), i);
|
|
||||||
// save position so that "guis_doAfterSliding" can use it
|
|
||||||
tabs_in_memory[0].listIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the gui was not found in main_gui_list, try to find it in scene specific list
|
// 1. notify old guis that they will be deleted so that they can persist their state if needed
|
||||||
if (tabs_in_memory[0].listIndex == -1) {
|
notify_active_tabs_before_delete(gui_state);
|
||||||
useSceneGUIlist = true;
|
// 2. clear current tabview and save gui_list_index_previous (needed for swipe)
|
||||||
for (int i=0; i<get_gui_list(get_currentScene())->size(); i++) {
|
clear_tabview(*tabview, gui_state);
|
||||||
if (get_gui_list(get_currentScene())->at(i) == get_currentGUIname()) {
|
// 3. clear current panel for page indicator
|
||||||
Serial.printf("Startup: found GUI with name \"%s\" in scene specific \"gui_list\" at position %d\r\n", get_currentGUIname().c_str(), i);
|
clear_panel(*panel, *img1, *img2);
|
||||||
// save position so that "guis_doAfterSliding" can use it
|
|
||||||
tabs_in_memory[0].listIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the gui was still not found, reset useSceneGUIlist
|
|
||||||
if (tabs_in_memory[0].listIndex == -1) {
|
|
||||||
useSceneGUIlist = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. set gui_list_indices and the tab to be activated
|
||||||
|
if ((gui_list_index >= 0) && (gui_list_index < get_gui_list_active_withFallback()->size())) {
|
||||||
|
// gui was found
|
||||||
|
setGUIlistIndicesToBeShown_forSpecificGUIlistIndex(gui_list_index, &gui_state);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// gui was not found
|
||||||
|
Serial.printf("Startup: GUI with name \"%s\" was not found. Will start with first GUI of main_gui_list\r\n", gui_memoryOptimizer_getActiveGUIname().c_str());
|
||||||
|
gui_memoryOptimizer_setActiveGUIlist(MAIN_GUI_LIST);
|
||||||
|
setGUIlistIndicesToBeShown_forFirstGUIinGUIlist(&gui_state);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. create content
|
||||||
|
gui_memoryOptimizer_doContentCreation(tabview, panel, img1, img2, &gui_state);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
// Here the magic for dynamic creation and deletion of lvgl objects happens to keep memory usage low.
|
||||||
// The next and previous tab must always be available in the tabview, because they can already been seen during the animation.
|
// The next and previous tab must always be available in the tabview, because they can already been seen during the animation.
|
||||||
// And you always need 3 tabs, otherwise you even could not slide to the next or previous tab.
|
// And you always need 3 tabs, otherwise you even could not slide to the next or previous tab.
|
||||||
// So we always have 3 tabs.
|
// So we always have 3 tabs.
|
||||||
// After the animation, the tabview and hence all tabs are deleted and recreated.
|
// After the animation, the tabview and hence all tabs are deleted and recreated.
|
||||||
|
|
||||||
// With parameter newGuiList it is signaled that we are changing from a scene specific list to the main list or vice versa
|
|
||||||
// In that case, we have to do special treatment because we are not simply sliding to the left or to the right, but we start newly with a different gui list.
|
|
||||||
// only called by guis_doTabCreationAtStartup():
|
|
||||||
// oldTabID = -1, newTabID = -1, newGuiList = false
|
|
||||||
// called by handleScene()
|
|
||||||
// oldTabID = -1, newTabID = -1, newGuiList = true
|
|
||||||
|
|
||||||
Serial.printf("--- Start of tab deletion and creation\r\n");
|
Serial.printf("--- Start of tab deletion and creation\r\n");
|
||||||
|
|
||||||
bool isInitialization = ((oldTabID == -1) && (newTabID == -1));
|
gui_state.oldTabID = gui_state.activeTabID;
|
||||||
if (isInitialization) {
|
gui_state.activeTabID = newTabID;
|
||||||
Serial.printf("Startup: will initially create the tabs to be shown\r\n");
|
|
||||||
} else {
|
|
||||||
Serial.printf("Changing from oldTabID %d \"%s\" to newTabID %d \"%s\"\r\n",
|
Serial.printf("Changing from oldTabID %d \"%s\" to newTabID %d \"%s\"\r\n",
|
||||||
oldTabID, get_gui_list(get_currentScene())->at(tabs_in_memory[oldTabID].listIndex).c_str(),
|
gui_state.oldTabID, gui_state.gui_on_tab[gui_state.oldTabID].GUIname.c_str(),
|
||||||
newTabID, get_gui_list(get_currentScene())->at(tabs_in_memory[newTabID].listIndex).c_str());
|
gui_state.activeTabID, gui_state.gui_on_tab[gui_state.activeTabID].GUIname.c_str());
|
||||||
}
|
|
||||||
|
|
||||||
// Save the ids of the tabs we had in memory before. This is only used by doTabCreation_strategyMax3() to know where we come from and where we have to go to.
|
// 1. notify old guis and clear tabview and panel
|
||||||
for (int i=0; i<3; i++) {
|
gui_memoryOptimizer_notifyAndClear(tabview, panel, img1, img2, &gui_state);
|
||||||
tabs_in_memory_previous_listIndex[i] = tabs_in_memory[i].listIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the old tabs need to be notified that they will be deleted so that they can persist their state if needed
|
|
||||||
notify_active_tabs_before_delete();
|
|
||||||
// clear current tabview
|
|
||||||
clear_tabview(*tabview);
|
|
||||||
// clear current panel for page indicator
|
|
||||||
clear_panel(*panel, *img1, *img2);
|
|
||||||
|
|
||||||
// only optional: delete and create the whole screen. Not necessary.
|
// only optional: delete and create the whole screen. Not necessary.
|
||||||
// Only used for a test. init_gui_status_bar() would need to be called again at a suitable place, because the status bar would also be deleted.
|
// Only used for a test. init_gui_status_bar() would need to be called again at a suitable place, because the status bar would also be deleted.
|
||||||
|
@ -498,25 +601,103 @@ void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview,
|
||||||
// lv_screen_load(newscr);
|
// lv_screen_load(newscr);
|
||||||
// lv_obj_delete(oldscr);
|
// lv_obj_delete(oldscr);
|
||||||
|
|
||||||
if (newGuiList) {
|
// 2. set gui_list_indices and the tab to be activated
|
||||||
// If we are switching to a new gui list, then we need to set tabs_in_memory_previous_listIndex[0] = -1;
|
setGUIlistIndicesToBeShown_afterSlide(&gui_state);
|
||||||
// Doing so, doTabCreation_strategyMax3() knows that we cannot resume an old state.
|
|
||||||
tabs_in_memory_previous_listIndex[0] = -1;
|
// 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. 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");
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 2. set gui_list_indices and the tab to be activated
|
||||||
|
gui_memoryOptimizer_setActiveGUIlist(newGUIlist);
|
||||||
|
setGUIlistIndicesToBeShown_forFirstGUIinGUIlist(&gui_state);
|
||||||
|
|
||||||
|
// 3. create content
|
||||||
|
gui_memoryOptimizer_doContentCreation(tabview, panel, img1, img2, &gui_state);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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_withFallback(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
|
// recreate the tabview
|
||||||
lv_obj_t* newTabview = create_tabview();
|
lv_obj_t* newTabview = create_tabview();
|
||||||
*tabview = newTabview;
|
*tabview = newTabview;
|
||||||
|
|
||||||
// Create the tabs. Use strategy "3 tabs at maximum" to keep memory usage low.
|
// Create the tabs. Use strategy "3 tabs at maximum" to keep memory usage low.
|
||||||
// Set the tab we swiped to as active
|
// Set the tab we swiped to as active
|
||||||
doTabCreation_strategyMax3(*tabview, oldTabID, newTabID);
|
doTabCreation_strategyMax3(*tabview, gui_state);
|
||||||
|
|
||||||
// Create the panel for the page indicator. Panel itself takes about 2136 bytes for three tabs.
|
// Create the panel for the page indicator. Panel itself takes about 2136 bytes for three tabs.
|
||||||
lv_obj_t* newPanel = create_panel();
|
lv_obj_t* newPanel = create_panel();
|
||||||
*panel = newPanel;
|
*panel = newPanel;
|
||||||
*img1 = lv_image_create(lv_screen_active());
|
*img1 = lv_image_create(lv_screen_active());
|
||||||
*img2 = lv_image_create(lv_screen_active());
|
*img2 = lv_image_create(lv_screen_active());
|
||||||
fillPanelWithPageIndicator_strategyMax3(*panel, *img1, *img2);
|
fillPanelWithPageIndicator_strategyMax3(*panel, *img1, *img2, gui_state);
|
||||||
|
|
||||||
// now, as the correct tab is active, register again the events for the tabview
|
// now, as the correct tab is active, register again the events for the tabview
|
||||||
lv_obj_add_event_cb(*tabview, tabview_tab_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
lv_obj_add_event_cb(*tabview, tabview_tab_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
|
@ -524,6 +705,11 @@ void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview,
|
||||||
// Initialize scroll position of the page indicator
|
// Initialize scroll position of the page indicator
|
||||||
lv_obj_send_event(lv_tabview_get_content(*tabview), LV_EVENT_SCROLL, NULL);
|
lv_obj_send_event(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");
|
Serial.printf("------------ End of tab deletion and creation\r\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,28 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
void gui_memoryOptimizer_prepare_startup();
|
enum GUIlists {
|
||||||
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);
|
// MAIN_GUI_LIST: we are in the main_gui_list (with the scene selector as first gui), either if a scene is active or not
|
||||||
|
// SCENE_GUI_LIST: a scene is active and we are not in the main_gui_list. In that case, we try to use the scene specific gui list, if the scene defined one.
|
||||||
|
MAIN_GUI_LIST,
|
||||||
|
SCENE_GUI_LIST
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
bool gui_memoryOptimizer_isTabIDInMemory(int tabID);
|
||||||
bool gui_memoryOptimizer_isGUInameInMemory(std::string guiName);
|
bool gui_memoryOptimizer_isGUInameInMemory(std::string GUIname);
|
||||||
|
|
||||||
|
std::string gui_memoryOptimizer_getActiveSceneName();
|
||||||
|
void gui_memoryOptimizer_setActiveSceneName(std::string aSceneName);
|
||||||
|
std::string gui_memoryOptimizer_getActiveGUIname();
|
||||||
|
void gui_memoryOptimizer_setActiveGUIname(std::string aGUIname);
|
||||||
|
GUIlists gui_memoryOptimizer_getActiveGUIlist();
|
||||||
|
void gui_memoryOptimizer_setActiveGUIlist(GUIlists aGUIlist);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "guiRegistry.h"
|
#include "guiRegistry.h"
|
||||||
#include "applicationInternal/gui/guiBase.h"
|
#include "applicationInternal/gui/guiBase.h"
|
||||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||||
|
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||||
#include "scenes/scene__default.h"
|
#include "scenes/scene__default.h"
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
|
@ -15,14 +16,30 @@ std::map<std::string, gui_definition> registered_guis_byName_map;
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void register_gui(std::string a_name, create_tab_content a_create_tab_content, notify_tab_before_delete a_notify_tab_before_delete) {
|
void register_gui(
|
||||||
|
std::string a_name,
|
||||||
|
create_tab_content a_create_tab_content,
|
||||||
|
notify_tab_before_delete a_notify_tab_before_delete,
|
||||||
|
gui_setKeys a_gui_setKeys,
|
||||||
|
key_repeatModes a_key_repeatModes,
|
||||||
|
key_commands_short a_key_commands_short,
|
||||||
|
key_commands_long a_key_commands_long
|
||||||
|
) {
|
||||||
|
|
||||||
if (registered_guis_byName_map.count(a_name) > 0) {
|
if (registered_guis_byName_map.count(a_name) > 0) {
|
||||||
Serial.printf("ERROR!!!: you cannot register two guis having the same name '%s'\r\n", a_name.c_str());
|
Serial.printf("ERROR!!!: you cannot register two guis having the same name '%s'\r\n", a_name.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_definition new_gui_definition = gui_definition{a_name, a_create_tab_content, a_notify_tab_before_delete};
|
gui_definition new_gui_definition = gui_definition{
|
||||||
|
a_name,
|
||||||
|
a_create_tab_content,
|
||||||
|
a_notify_tab_before_delete,
|
||||||
|
a_gui_setKeys,
|
||||||
|
a_key_repeatModes,
|
||||||
|
a_key_commands_short,
|
||||||
|
a_key_commands_long
|
||||||
|
};
|
||||||
|
|
||||||
// put the gui_definition in a map that can be accessed by name
|
// put the gui_definition in a map that can be accessed by name
|
||||||
registered_guis_byName_map[a_name] = new_gui_definition;
|
registered_guis_byName_map[a_name] = new_gui_definition;
|
||||||
|
@ -31,4 +48,25 @@ void register_gui(std::string a_name, create_tab_content a_create_tab_content, n
|
||||||
// Can be overwritten by scenes to have their own gui_list.
|
// Can be overwritten by scenes to have their own gui_list.
|
||||||
main_gui_list.insert(main_gui_list.end(), {std::string(a_name)});
|
main_gui_list.insert(main_gui_list.end(), {std::string(a_name)});
|
||||||
|
|
||||||
|
setKeysForAllRegisteredGUIsAndScenes();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setKeysForAllRegisteredGUIsAndScenes() {
|
||||||
|
// Whenever a new gui or scene is registered, a new gui or scene command could have been defined in the gui or scene.
|
||||||
|
// But this new command could have already been used before in the key definition of another gui or scene. The command at this time was 0, which is undefined.
|
||||||
|
// So we have to set the keys again for all guis and scenes that have been registered before.
|
||||||
|
// 1. set again the defaultKeys
|
||||||
|
register_scene_defaultKeys();
|
||||||
|
// 2. loop over all registered scenes and call setKeys()
|
||||||
|
for (std::map<std::string, scene_definition>::iterator it = registered_scenes.begin(); it != registered_scenes.end(); ++it) {
|
||||||
|
it->second.this_scene_setKeys();
|
||||||
|
}
|
||||||
|
// 3. loop over all registered guis and call setKeys()
|
||||||
|
for (std::map<std::string, gui_definition>::iterator it = registered_guis_byName_map.begin(); it != registered_guis_byName_map.end(); ++it) {
|
||||||
|
if (it->second.this_gui_setKeys != NULL) {
|
||||||
|
it->second.this_gui_setKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,19 +22,33 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
#include "applicationInternal/keys.h"
|
||||||
|
|
||||||
typedef void (*create_tab_content)(lv_obj_t* tab);
|
typedef void (*create_tab_content)(lv_obj_t* tab);
|
||||||
typedef void (*notify_tab_before_delete)(void);
|
typedef void (*notify_tab_before_delete)(void);
|
||||||
|
typedef void (*gui_setKeys)(void);
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work
|
// https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work
|
||||||
struct gui_definition {
|
struct gui_definition {
|
||||||
std::string this_name;
|
std::string this_name;
|
||||||
create_tab_content this_create_tab_content;
|
create_tab_content this_create_tab_content;
|
||||||
notify_tab_before_delete this_notify_tab_before_delete;
|
notify_tab_before_delete this_notify_tab_before_delete;
|
||||||
uint32_t this_tabID;
|
gui_setKeys this_gui_setKeys;
|
||||||
lv_obj_t* this_tab;
|
key_repeatModes this_key_repeatModes;
|
||||||
|
key_commands_short this_key_commands_short;
|
||||||
|
key_commands_long this_key_commands_long;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::map<std::string, gui_definition> registered_guis_byName_map;
|
extern std::map<std::string, gui_definition> registered_guis_byName_map;
|
||||||
|
|
||||||
void register_gui(std::string a_name, create_tab_content a_create_tab_content, notify_tab_before_delete a_notify_tab_before_delete);
|
void register_gui(
|
||||||
|
std::string a_name,
|
||||||
|
create_tab_content a_create_tab_content,
|
||||||
|
notify_tab_before_delete a_notify_tab_before_delete,
|
||||||
|
gui_setKeys a_gui_setKeys = NULL,
|
||||||
|
key_repeatModes a_key_repeatModes = NULL,
|
||||||
|
key_commands_short a_key_commands_short = NULL,
|
||||||
|
key_commands_long a_key_commands_long = NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
void setKeysForAllRegisteredGUIsAndScenes();
|
|
@ -26,17 +26,29 @@ void init_preferences(void) {
|
||||||
void save_preferences(void) {
|
void save_preferences(void) {
|
||||||
save_preferences_HAL();
|
save_preferences_HAL();
|
||||||
};
|
};
|
||||||
std::string get_currentScene() {
|
std::string get_activeScene() {
|
||||||
return get_currentScene_HAL();
|
return get_activeScene_HAL();
|
||||||
}
|
}
|
||||||
void set_currentScene(std::string aCurrentScene) {
|
void set_activeScene(std::string anActiveScene) {
|
||||||
set_currentScene_HAL(aCurrentScene);
|
set_activeScene_HAL(anActiveScene);
|
||||||
}
|
}
|
||||||
std::string get_currentGUIname() {
|
std::string get_activeGUIname() {
|
||||||
return get_currentGUIname_HAL();
|
return get_activeGUIname_HAL();
|
||||||
}
|
}
|
||||||
void set_currentGUIname(std::string aCurrentGUIname) {
|
void set_activeGUIname(std::string anActiveGUIname) {
|
||||||
set_currentGUIname_HAL(aCurrentGUIname);
|
set_activeGUIname_HAL(anActiveGUIname);
|
||||||
|
}
|
||||||
|
int get_activeGUIlist() {
|
||||||
|
return get_activeGUIlist_HAL();
|
||||||
|
}
|
||||||
|
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 ---------------------------------------------------------------
|
// --- user led ---------------------------------------------------------------
|
||||||
|
|
|
@ -10,10 +10,14 @@ void init_hardware_general(void);
|
||||||
// --- preferences ------------------------------------------------------------
|
// --- preferences ------------------------------------------------------------
|
||||||
void init_preferences(void);
|
void init_preferences(void);
|
||||||
void save_preferences(void);
|
void save_preferences(void);
|
||||||
std::string get_currentScene();
|
std::string get_activeScene();
|
||||||
void set_currentScene(std::string aCurrentScene);
|
void set_activeScene(std::string anActiveScene);
|
||||||
std::string get_currentGUIname();
|
std::string get_activeGUIname();
|
||||||
void set_currentGUIname(std::string aCurrentGUIname);
|
void set_activeGUIname(std::string anActiveGUIname);
|
||||||
|
int get_activeGUIlist();
|
||||||
|
void set_activeGUIlist(int anActiveGUIlist);
|
||||||
|
int get_lastActiveGUIlistIndex();
|
||||||
|
void set_lastActiveGUIlistIndex(int aGUIlistIndex);
|
||||||
|
|
||||||
// --- user led ---------------------------------------------------------------
|
// --- user led ---------------------------------------------------------------
|
||||||
void init_userled(void);
|
void init_userled(void);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "applicationInternal/gui/guiMemoryOptimizer.h"
|
||||||
|
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||||
#include "applicationInternal/commandHandler.h"
|
#include "applicationInternal/commandHandler.h"
|
||||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
|
||||||
|
|
||||||
const uint8_t ROWS = 5; //five rows
|
const uint8_t ROWS = 5; //five rows
|
||||||
const uint8_t COLS = 5; //five columns
|
const uint8_t COLS = 5; //five columns
|
||||||
|
@ -33,7 +34,7 @@ void doShortPress(char keyChar, int keyCode){
|
||||||
if ((currentMillis - lastTimeSent[keyCode/ROWS][keyCode%ROWS]) > repeatRate) {
|
if ((currentMillis - lastTimeSent[keyCode/ROWS][keyCode%ROWS]) > repeatRate) {
|
||||||
lastTimeSent[keyCode/ROWS][keyCode%ROWS] = currentMillis;
|
lastTimeSent[keyCode/ROWS][keyCode%ROWS] = currentMillis;
|
||||||
|
|
||||||
uint16_t command = get_command_short(get_currentScene(), keyChar);
|
uint16_t command = get_command_short(gui_memoryOptimizer_getActiveSceneName(), keyChar);
|
||||||
if (command != COMMAND_UNKNOWN) {
|
if (command != COMMAND_UNKNOWN) {
|
||||||
Serial.printf("key: key '%c', will use command '%u'\r\n", keyChar, command);
|
Serial.printf("key: key '%c', will use command '%u'\r\n", keyChar, command);
|
||||||
executeCommand(command);
|
executeCommand(command);
|
||||||
|
@ -44,7 +45,7 @@ void doShortPress(char keyChar, int keyCode){
|
||||||
}
|
}
|
||||||
|
|
||||||
void doLongPress(char keyChar, int keyCode){
|
void doLongPress(char keyChar, int keyCode){
|
||||||
uint16_t command = get_command_long(get_currentScene(), keyChar);
|
uint16_t command = get_command_long(gui_memoryOptimizer_getActiveSceneName(), keyChar);
|
||||||
if (command != COMMAND_UNKNOWN) {
|
if (command != COMMAND_UNKNOWN) {
|
||||||
Serial.printf("key: key '%c' (long press), will use command '%u'\r\n", keyChar, command);
|
Serial.printf("key: key '%c' (long press), will use command '%u'\r\n", keyChar, command);
|
||||||
executeCommand(command);
|
executeCommand(command);
|
||||||
|
@ -70,11 +71,11 @@ void keypad_loop(void) {
|
||||||
if (keypad_keys[i].kstate == PRESSED) {
|
if (keypad_keys[i].kstate == PRESSED) {
|
||||||
// Serial.println("pressed");
|
// Serial.println("pressed");
|
||||||
|
|
||||||
if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORT) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) {
|
if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORT) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) {
|
||||||
// Serial.printf("key: PRESSED of SHORT key %c (%d)\r\n", keyChar, keyCode);
|
// Serial.printf("key: PRESSED of SHORT key %c (%d)\r\n", keyChar, keyCode);
|
||||||
doShortPress(keyChar, keyCode);
|
doShortPress(keyChar, keyCode);
|
||||||
|
|
||||||
} else if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORT_REPEATED) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) { // here do not repeat it too early, do the repeat only in HOLD
|
} else if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORT_REPEATED) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != PRESSED)) { // here do not repeat it too early, do the repeat only in HOLD
|
||||||
// Serial.printf("key: PRESSED of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode);
|
// Serial.printf("key: PRESSED of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode);
|
||||||
doShortPress(keyChar, keyCode);
|
doShortPress(keyChar, keyCode);
|
||||||
|
|
||||||
|
@ -84,13 +85,13 @@ void keypad_loop(void) {
|
||||||
} else if (keypad_keys[i].kstate == HOLD) {
|
} else if (keypad_keys[i].kstate == HOLD) {
|
||||||
// Serial.println("hold");
|
// Serial.println("hold");
|
||||||
|
|
||||||
if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORTorLONG) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != HOLD)) {
|
if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORTorLONG) && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != HOLD)) {
|
||||||
// Serial.printf("key: HOLD of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode);
|
// Serial.printf("key: HOLD of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode);
|
||||||
// Serial.printf("will set keyIsHold to TRUE for keycode %d\r\n", keyCode);
|
// Serial.printf("will set keyIsHold to TRUE for keycode %d\r\n", keyCode);
|
||||||
keyIsHold[keyCode/ROWS][keyCode%ROWS] = true;
|
keyIsHold[keyCode/ROWS][keyCode%ROWS] = true;
|
||||||
doLongPress(keyChar, keyCode);
|
doLongPress(keyChar, keyCode);
|
||||||
|
|
||||||
} else if (get_key_repeatMode(get_currentScene(), keyChar) == SHORT_REPEATED) { // this is the only case where we do not check the lastKeyState, because here it is intended to repeat the action
|
} else if (get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORT_REPEATED) { // this is the only case where we do not check the lastKeyState, because here it is intended to repeat the action
|
||||||
// Serial.printf("key: HOLD of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode);
|
// Serial.printf("key: HOLD of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode);
|
||||||
doShortPress(keyChar, keyCode);
|
doShortPress(keyChar, keyCode);
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ void keypad_loop(void) {
|
||||||
|
|
||||||
} else if (keypad_keys[i].kstate == RELEASED) {
|
} else if (keypad_keys[i].kstate == RELEASED) {
|
||||||
// Serial.println("released");
|
// Serial.println("released");
|
||||||
if ((get_key_repeatMode(get_currentScene(), keyChar) == SHORTorLONG) && !keyIsHold[keyCode/ROWS][keyCode%ROWS] && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != RELEASED)) {
|
if ((get_key_repeatMode(gui_memoryOptimizer_getActiveSceneName(), keyChar) == SHORTorLONG) && !keyIsHold[keyCode/ROWS][keyCode%ROWS] && (lastKeyState[keyCode/ROWS][keyCode%ROWS] != RELEASED)) {
|
||||||
// Serial.printf("value of keyIsHold for keycode %d is %d\r\n", keyCode, keyIsHold[keyCode/ROWS][keyCode%ROWS]);
|
// Serial.printf("value of keyIsHold for keycode %d is %d\r\n", keyCode, keyIsHold[keyCode/ROWS][keyCode%ROWS]);
|
||||||
// Serial.printf("key: RELEASED of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode);
|
// Serial.printf("key: RELEASED of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode);
|
||||||
doShortPress(keyChar, keyCode);
|
doShortPress(keyChar, keyCode);
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
enum repeatModes {
|
enum repeatModes {
|
||||||
// only as fallback
|
// only as fallback
|
||||||
REPEAT_MODE_UNKNOWN,
|
REPEAT_MODE_UNKNOWN,
|
||||||
|
@ -15,4 +18,8 @@ enum repeatModes {
|
||||||
SHORTorLONG,
|
SHORTorLONG,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::map<char, repeatModes> *key_repeatModes;
|
||||||
|
typedef std::map<char, uint16_t> *key_commands_short;
|
||||||
|
typedef std::map<char, uint16_t> *key_commands_long;
|
||||||
|
|
||||||
void keypad_loop(void);
|
void keypad_loop(void);
|
||||||
|
|
|
@ -5,17 +5,71 @@
|
||||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||||
#include "applicationInternal/commandHandler.h"
|
#include "applicationInternal/commandHandler.h"
|
||||||
|
#include "guis/gui_sceneSelection.h"
|
||||||
#include "scenes/scene__default.h"
|
#include "scenes/scene__default.h"
|
||||||
|
|
||||||
|
void setLabelActiveScene() {
|
||||||
|
if ((SceneLabel != NULL) && sceneExists(gui_memoryOptimizer_getActiveSceneName())) {
|
||||||
|
lv_label_set_text(SceneLabel, gui_memoryOptimizer_getActiveSceneName().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showSpecificGUI(GUIlists GUIlist, std::string GUIname);
|
||||||
|
|
||||||
void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") {
|
void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") {
|
||||||
|
|
||||||
|
auto current = commandData.commandPayloads.begin();
|
||||||
|
std::string scene_name = *current;
|
||||||
|
|
||||||
|
// --- 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");
|
||||||
|
showSpecificGUI(MAIN_GUI_LIST, tabName_sceneSelection);
|
||||||
|
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 (gui_memoryOptimizer_getActiveTabID() == 0) {
|
||||||
|
Serial.println("scene: cannot navigate to prev gui, because there is none");
|
||||||
|
} else {
|
||||||
|
Serial.println("scene: will navigate to prev gui");
|
||||||
|
setActiveTab(gui_memoryOptimizer_getActiveTabID() -1, LV_ANIM_ON, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (scene_name == scene_gui_next) {
|
||||||
|
if (!gui_memoryOptimizer_isTabIDInMemory(gui_memoryOptimizer_getActiveTabID() +1)) {
|
||||||
|
Serial.println("scene: cannot navigate to next gui, because there is none");
|
||||||
|
} else {
|
||||||
|
Serial.println("scene: will navigate to next gui");
|
||||||
|
setActiveTab(gui_memoryOptimizer_getActiveTabID() +1, LV_ANIM_ON, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
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
|
// FORCE can be either as second payload in commandData
|
||||||
// e.g. register_command(&SCENE_TV_FORCE , makeCommandData(SCENE, {scene_name_TV, "FORCE"}));
|
// e.g. register_command(&SCENE_TV_FORCE , makeCommandData(SCENE, {scene_name_TV, "FORCE"}));
|
||||||
// or as additionalPayload, used by gui_sceneSelection.cpp
|
// or as additionalPayload, used by gui_sceneSelection.cpp
|
||||||
// e.g. executeCommand(activate_scene_command, "FORCE");
|
// e.g. executeCommand(activate_scene_command, "FORCE");
|
||||||
|
|
||||||
auto current = commandData.commandPayloads.begin();
|
|
||||||
std::string scene_name = *current;
|
|
||||||
// we can have a second payload
|
// we can have a second payload
|
||||||
std::string isForcePayload = "";
|
std::string isForcePayload = "";
|
||||||
++current;
|
++current;
|
||||||
|
@ -23,49 +77,20 @@ void handleScene(uint16_t command, commandData commandData, std::string addition
|
||||||
isForcePayload = *current;
|
isForcePayload = *current;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not really switch scene, but show sceneSelection gui. From that on, we are in the main_gui_list.
|
|
||||||
if (scene_name == scene_name_selection) {
|
|
||||||
useSceneGUIlist = false;
|
|
||||||
guis_doAfterSliding(-1, -1, true);
|
|
||||||
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
|
// check if we know the new scene
|
||||||
if (!sceneExists(scene_name)) {
|
if (!sceneExists(scene_name)) {
|
||||||
Serial.printf("scene: cannot start scene %s, because it is unknown\r\n", scene_name.c_str());
|
Serial.printf("scene: cannot start scene %s, because it is unknown\r\n", scene_name.c_str());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Serial.printf("scene: will switch from old scene %s to new scene %s\r\n", get_currentScene().c_str(), scene_name.c_str());
|
Serial.printf("scene: will switch from old scene %s to new scene %s\r\n", gui_memoryOptimizer_getActiveSceneName().c_str(), scene_name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not activate the same scene again, only when forced to do so (e.g. by long press on the gui or when selected by hardware key)
|
// do not activate the same scene again, only when forced to do so (e.g. by long press on the gui or when selected by hardware key)
|
||||||
bool callEndAndStartSequences;
|
bool callEndAndStartSequences;
|
||||||
if ((scene_name == get_currentScene()) && ((isForcePayload != "FORCE") && (additionalPayload != "FORCE"))) {
|
if ((scene_name == gui_memoryOptimizer_getActiveSceneName()) && ((isForcePayload != "FORCE") && (additionalPayload != "FORCE"))) {
|
||||||
Serial.printf("scene: will not start scene again, because it is already active\r\n");
|
Serial.printf("scene: will not start scene again, because it is already active\r\n");
|
||||||
callEndAndStartSequences = false;
|
callEndAndStartSequences = false;
|
||||||
} else if ((scene_name == get_currentScene()) && ((isForcePayload == "FORCE") || (additionalPayload == "FORCE"))) {
|
} else if ((scene_name == gui_memoryOptimizer_getActiveSceneName()) && ((isForcePayload == "FORCE") || (additionalPayload == "FORCE"))) {
|
||||||
Serial.printf("scene: scene is already active, but FORCE was set, so start scene again\r\n");
|
Serial.printf("scene: scene is already active, but FORCE was set, so start scene again\r\n");
|
||||||
callEndAndStartSequences = true;
|
callEndAndStartSequences = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,13 +103,13 @@ void handleScene(uint16_t command, commandData commandData, std::string addition
|
||||||
|
|
||||||
if (callEndAndStartSequences) {
|
if (callEndAndStartSequences) {
|
||||||
// end old scene
|
// end old scene
|
||||||
if (!sceneExists(get_currentScene()) && (get_currentScene() != "")) {
|
if (!sceneExists(gui_memoryOptimizer_getActiveSceneName()) && (gui_memoryOptimizer_getActiveSceneName() != "")) {
|
||||||
Serial.printf("scene: WARNING: cannot end scene %s, because it is unknown\r\n", get_currentScene().c_str());
|
Serial.printf("scene: WARNING: cannot end scene %s, because it is unknown\r\n", gui_memoryOptimizer_getActiveSceneName().c_str());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (get_currentScene() != "") {
|
if (gui_memoryOptimizer_getActiveSceneName() != "") {
|
||||||
Serial.printf("scene: will call end sequence for scene %s\r\n", get_currentScene().c_str());
|
Serial.printf("scene: will call end sequence for scene %s\r\n", gui_memoryOptimizer_getActiveSceneName().c_str());
|
||||||
scene_end_sequence_from_registry(get_currentScene());
|
scene_end_sequence_from_registry(gui_memoryOptimizer_getActiveSceneName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -94,19 +119,47 @@ void handleScene(uint16_t command, commandData commandData, std::string addition
|
||||||
scene_start_sequence_from_registry(scene_name);
|
scene_start_sequence_from_registry(scene_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_currentScene(scene_name);
|
gui_memoryOptimizer_setActiveSceneName(scene_name);
|
||||||
|
|
||||||
if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, get_currentScene().c_str());}
|
if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, gui_memoryOptimizer_getActiveSceneName().c_str());}
|
||||||
|
|
||||||
Serial.printf("scene: scene handling finished, new scene %s is active\r\n", get_currentScene().c_str());
|
Serial.printf("scene: scene handling finished, new scene %s is active\r\n", gui_memoryOptimizer_getActiveSceneName().c_str());
|
||||||
|
|
||||||
useSceneGUIlist = true;
|
guis_doTabCreationAfterGUIlistChanged(SCENE_GUI_LIST);
|
||||||
// recreate the gui based on the current scene
|
|
||||||
guis_doAfterSliding(-1, -1, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLabelCurrentScene() {
|
void showSpecificGUI(GUIlists GUIlist, std::string GUIname) {
|
||||||
if ((SceneLabel != NULL) && sceneExists(get_currentScene())) {
|
gui_list gui_list_for_search = get_gui_list_withFallback(GUIlist);
|
||||||
lv_label_set_text(SceneLabel, get_currentScene().c_str());
|
|
||||||
|
// 1. search for gui in the gui list
|
||||||
|
int gui_list_index = -1;
|
||||||
|
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 < gui_list_for_search->size())) {
|
||||||
|
guis_doTabCreationForSpecificGUI(GUIlist, gui_list_index);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// gui was not found
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -3,5 +3,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "applicationInternal/commandHandler.h"
|
#include "applicationInternal/commandHandler.h"
|
||||||
|
|
||||||
|
void setLabelActiveScene();
|
||||||
void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "");
|
void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "");
|
||||||
void setLabelCurrentScene();
|
void handleGUI (uint16_t command, commandData commandData, std::string additionalPayload = "");
|
||||||
|
|
|
@ -1,28 +1,13 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "applicationInternal/commandHandler.h"
|
#include "applicationInternal/gui/guiMemoryOptimizer.h"
|
||||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
#include "applicationInternal/gui/guiRegistry.h"
|
||||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||||
|
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||||
|
#include "applicationInternal/commandHandler.h"
|
||||||
// scenes
|
// scenes
|
||||||
#include "scenes/scene__default.h"
|
#include "scenes/scene__default.h"
|
||||||
|
|
||||||
// If useSceneGUIlist == true, 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 useSceneGUIlist == false, then we are in the main_gui_list, either if a scene is active or not.
|
|
||||||
bool useSceneGUIlist = false;
|
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work
|
|
||||||
struct scene_definition {
|
|
||||||
scene_setKeys this_scene_setKeys;
|
|
||||||
scene_start_sequence this_scene_start_sequence;
|
|
||||||
scene_end_sequence this_scene_end_sequence;
|
|
||||||
key_repeatModes this_key_repeatModes;
|
|
||||||
key_commands_short this_key_commands_short;
|
|
||||||
key_commands_long this_key_commands_long;
|
|
||||||
gui_list this_gui_list;
|
|
||||||
uint16_t this_activate_scene_command;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<std::string, scene_definition> registered_scenes;
|
std::map<std::string, scene_definition> registered_scenes;
|
||||||
t_scene_list scenes_on_sceneSelectionGUI;
|
t_scene_list scenes_on_sceneSelectionGUI;
|
||||||
|
|
||||||
|
@ -54,15 +39,7 @@ void register_scene(
|
||||||
// Can be overwritten in main.cpp
|
// Can be overwritten in main.cpp
|
||||||
scenes_on_sceneSelectionGUI.insert(scenes_on_sceneSelectionGUI.end(), {std::string(a_scene_name)});
|
scenes_on_sceneSelectionGUI.insert(scenes_on_sceneSelectionGUI.end(), {std::string(a_scene_name)});
|
||||||
|
|
||||||
// Whenever a new scene is registered, normally a new scene command has been defined immediately before (e.g. see register_scene_TV()).
|
setKeysForAllRegisteredGUIsAndScenes();
|
||||||
// But this new scene command could have been already been used before in the key definition of another scene. The command at this time was 0, which is undefined.
|
|
||||||
// So we have to set the keys again for all scenes that have been registered before.
|
|
||||||
// 1. set again the defaultKeys
|
|
||||||
register_scene_defaultKeys();
|
|
||||||
// 2. loop over all registered scenes and call setKeys()
|
|
||||||
for (std::map<std::string, scene_definition>::iterator it = registered_scenes.begin(); it != registered_scenes.end(); ++it) {
|
|
||||||
it->second.this_scene_setKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,8 +67,14 @@ void scene_end_sequence_from_registry(std::string sceneName) {
|
||||||
|
|
||||||
repeatModes get_key_repeatMode(std::string sceneName, char keyChar) {
|
repeatModes get_key_repeatMode(std::string sceneName, char keyChar) {
|
||||||
try {
|
try {
|
||||||
// look if the map of the current scene has a definition for it
|
// look if the map of the active gui has a definition for it
|
||||||
if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_repeatModes->count(keyChar) > 0)) {
|
std::string GUIname = gui_memoryOptimizer_getActiveGUIname();
|
||||||
|
if ((registered_guis_byName_map.count(GUIname) > 0) && (registered_guis_byName_map.at(GUIname).this_key_repeatModes != NULL) && (registered_guis_byName_map.at(GUIname).this_key_repeatModes->count(keyChar) > 0)) {
|
||||||
|
// Serial.printf("get_key_repeatMode: will use key from gui %s\r\n", GUIname.c_str());
|
||||||
|
return registered_guis_byName_map.at(GUIname).this_key_repeatModes->at(keyChar);
|
||||||
|
|
||||||
|
// look if the map of the active scene has a definition for it
|
||||||
|
} else if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_repeatModes->count(keyChar) > 0)) {
|
||||||
// Serial.printf("get_key_repeatMode: will use key from scene %s\r\n", sceneName.c_str());
|
// Serial.printf("get_key_repeatMode: will use key from scene %s\r\n", sceneName.c_str());
|
||||||
return registered_scenes.at(sceneName).this_key_repeatModes->at(keyChar);
|
return registered_scenes.at(sceneName).this_key_repeatModes->at(keyChar);
|
||||||
|
|
||||||
|
@ -114,8 +97,14 @@ repeatModes get_key_repeatMode(std::string sceneName, char keyChar) {
|
||||||
|
|
||||||
uint16_t get_command_short(std::string sceneName, char keyChar) {
|
uint16_t get_command_short(std::string sceneName, char keyChar) {
|
||||||
try {
|
try {
|
||||||
// look if the map of the current scene has a definition for it
|
// look if the map of the active gui has a definition for it
|
||||||
if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_short->count(keyChar) > 0)) {
|
std::string GUIname = gui_memoryOptimizer_getActiveGUIname();
|
||||||
|
if ((registered_guis_byName_map.count(GUIname) > 0) && (registered_guis_byName_map.at(GUIname).this_key_commands_short != NULL) && (registered_guis_byName_map.at(GUIname).this_key_commands_short->count(keyChar) > 0)) {
|
||||||
|
// Serial.printf("get_command_short: will use key from gui %s\r\n", GUIname.c_str());
|
||||||
|
return registered_guis_byName_map.at(GUIname).this_key_commands_short->at(keyChar);
|
||||||
|
|
||||||
|
// look if the map of the active scene has a definition for it
|
||||||
|
} else if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_short->count(keyChar) > 0)) {
|
||||||
// Serial.printf("get_command_short: will use key from scene %s\r\n", sceneName.c_str());
|
// Serial.printf("get_command_short: will use key from scene %s\r\n", sceneName.c_str());
|
||||||
return registered_scenes.at(sceneName).this_key_commands_short->at(keyChar);
|
return registered_scenes.at(sceneName).this_key_commands_short->at(keyChar);
|
||||||
|
|
||||||
|
@ -139,8 +128,14 @@ uint16_t get_command_short(std::string sceneName, char keyChar) {
|
||||||
|
|
||||||
uint16_t get_command_long(std::string sceneName, char keyChar) {
|
uint16_t get_command_long(std::string sceneName, char keyChar) {
|
||||||
try {
|
try {
|
||||||
// look if the map of the current scene has a definition for it
|
// look if the map of the active gui has a definition for it
|
||||||
if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_long->count(keyChar) > 0)) {
|
std::string GUIname = gui_memoryOptimizer_getActiveGUIname();
|
||||||
|
if ((registered_guis_byName_map.count(GUIname) > 0) && (registered_guis_byName_map.at(GUIname).this_key_commands_long != NULL) && (registered_guis_byName_map.at(GUIname).this_key_commands_long->count(keyChar) > 0)) {
|
||||||
|
// Serial.printf("get_command_long: will use key from gui %s\r\n", GUIname.c_str());
|
||||||
|
return registered_guis_byName_map.at(GUIname).this_key_commands_long->at(keyChar);
|
||||||
|
|
||||||
|
// look if the map of the active scene has a definition for it
|
||||||
|
} else if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_long->count(keyChar) > 0)) {
|
||||||
// Serial.printf("get_command_long: will use key from scene %s\r\n", sceneName.c_str());
|
// Serial.printf("get_command_long: will use key from scene %s\r\n", sceneName.c_str());
|
||||||
return registered_scenes.at(sceneName).this_key_commands_long->at(keyChar);
|
return registered_scenes.at(sceneName).this_key_commands_long->at(keyChar);
|
||||||
|
|
||||||
|
@ -162,40 +157,58 @@ uint16_t get_command_long(std::string sceneName, char keyChar) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_list get_gui_list(std::string sceneName) {
|
gui_list get_gui_list_withFallback(GUIlists gui_list) {
|
||||||
try {
|
try {
|
||||||
// If useSceneGUIlist == true, then a scene is active and we are not in the main_gui_list (with the scene selector as first gui).
|
// If gui_list == MAIN_GUI_LIST, then we want the main_gui_list, either if a scene is active or not.
|
||||||
// In that case, we try to use the scene specific gui list, if the scene defined one.
|
// If gui_list == SCENE_GUI_LIST, then we want the scene gui list. If none is defined, return main_gui_list as fallback.
|
||||||
// If useSceneGUIlist == false, then we are in the main_gui_list, either if a scene is active or not.
|
|
||||||
|
|
||||||
#if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
|
if (gui_list == MAIN_GUI_LIST) {
|
||||||
// look if the current scene has a definition for a gui list
|
|
||||||
if (useSceneGUIlist &&
|
|
||||||
(registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_gui_list != NULL)) {
|
|
||||||
// Serial.printf("get_gui_list: will use gui_list from scene %s\r\n", sceneName.c_str());
|
|
||||||
return registered_scenes.at(sceneName).this_gui_list;
|
|
||||||
|
|
||||||
// if there is no scene specific gui list, simply return the main_gui_list
|
|
||||||
} else {
|
|
||||||
// Serial.printf("get_gui_list: will use main_gui_list\r\n");
|
|
||||||
return &main_gui_list;
|
return &main_gui_list;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
|
||||||
|
// look if the active scene has a definition for a gui list
|
||||||
|
if ((registered_scenes.count(gui_memoryOptimizer_getActiveSceneName()) > 0) && (registered_scenes.at(gui_memoryOptimizer_getActiveSceneName()).this_gui_list != NULL)) {
|
||||||
|
// Serial.printf("get_gui_list: will use gui_list from scene %s\r\n", sceneName.c_str());
|
||||||
|
return registered_scenes.at(gui_memoryOptimizer_getActiveSceneName()).this_gui_list;
|
||||||
|
} else {
|
||||||
|
// no scene specific gui list was defined
|
||||||
|
return &main_gui_list;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// never use scene specific gui list
|
// never use scene specific gui list
|
||||||
return &main_gui_list;
|
return &main_gui_list;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (const std::out_of_range& oor) {
|
catch (const std::out_of_range& oor) {
|
||||||
Serial.printf("get_gui_list: internal error, sceneName not registered\r\n");
|
Serial.printf("get_gui_list: internal error, sceneName not registered\r\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
uint16_t get_activate_scene_command(std::string sceneName) {
|
||||||
try {
|
try {
|
||||||
// look if the current scene is known
|
// look if the scene is known
|
||||||
if ((registered_scenes.count(sceneName) > 0)) {
|
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());
|
// 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;
|
return registered_scenes.at(sceneName).this_activate_scene_command;
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdint.h>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "applicationInternal/keys.h"
|
#include "applicationInternal/keys.h"
|
||||||
|
#include "applicationInternal/gui/guiMemoryOptimizer.h"
|
||||||
extern bool useSceneGUIlist;
|
|
||||||
|
|
||||||
typedef std::vector<std::string> t_gui_list;
|
typedef std::vector<std::string> t_gui_list;
|
||||||
typedef std::vector<std::string> t_scene_list;
|
typedef std::vector<std::string> t_scene_list;
|
||||||
|
@ -14,12 +11,23 @@ typedef std::vector<std::string> t_scene_list;
|
||||||
typedef void (*scene_setKeys)(void);
|
typedef void (*scene_setKeys)(void);
|
||||||
typedef void (*scene_start_sequence)(void);
|
typedef void (*scene_start_sequence)(void);
|
||||||
typedef void (*scene_end_sequence)(void);
|
typedef void (*scene_end_sequence)(void);
|
||||||
typedef std::map<char, repeatModes> *key_repeatModes;
|
|
||||||
typedef std::map<char, uint16_t> *key_commands_short;
|
|
||||||
typedef std::map<char, uint16_t> *key_commands_long;
|
|
||||||
typedef t_gui_list *gui_list;
|
typedef t_gui_list *gui_list;
|
||||||
typedef t_scene_list *scene_list;
|
typedef t_scene_list *scene_list;
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work
|
||||||
|
struct scene_definition {
|
||||||
|
scene_setKeys this_scene_setKeys;
|
||||||
|
scene_start_sequence this_scene_start_sequence;
|
||||||
|
scene_end_sequence this_scene_end_sequence;
|
||||||
|
key_repeatModes this_key_repeatModes;
|
||||||
|
key_commands_short this_key_commands_short;
|
||||||
|
key_commands_long this_key_commands_long;
|
||||||
|
gui_list this_gui_list;
|
||||||
|
uint16_t this_activate_scene_command;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::map<std::string, scene_definition> registered_scenes;
|
||||||
|
|
||||||
void register_scene(
|
void register_scene(
|
||||||
std::string a_scene_name,
|
std::string a_scene_name,
|
||||||
scene_setKeys a_scene_setKeys,
|
scene_setKeys a_scene_setKeys,
|
||||||
|
@ -37,7 +45,9 @@ void scene_end_sequence_from_registry(std::string sceneName);
|
||||||
repeatModes get_key_repeatMode(std::string sceneName, char keyChar);
|
repeatModes get_key_repeatMode(std::string sceneName, char keyChar);
|
||||||
uint16_t get_command_short(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);
|
uint16_t get_command_long(std::string sceneName, char keyChar);
|
||||||
gui_list get_gui_list(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);
|
uint16_t get_activate_scene_command(std::string sceneName);
|
||||||
scene_list get_scenes_on_sceneSelectionGUI();
|
scene_list get_scenes_on_sceneSelectionGUI();
|
||||||
void set_scenes_on_sceneSelectionGUI(t_scene_list a_scene_list);
|
void set_scenes_on_sceneSelectionGUI(t_scene_list a_scene_list);
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include <lvgl.h>
|
||||||
|
#include "applicationInternal/gui/guiBase.h"
|
||||||
|
#include "applicationInternal/gui/guiRegistry.h"
|
||||||
|
#include "applicationInternal/commandHandler.h"
|
||||||
|
#include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h"
|
||||||
|
#include "devices/AVreceiver/device_yamahaAmp/gui_yamahaAmp.h"
|
||||||
|
|
||||||
|
static void button_clicked_event_cb(lv_event_t* e) {
|
||||||
|
int user_data = (intptr_t)(e->user_data);
|
||||||
|
|
||||||
|
if (user_data == 0) {
|
||||||
|
executeCommand(YAMAHA_STANDARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_tab_content_yamahaAmp(lv_obj_t* tab) {
|
||||||
|
|
||||||
|
// Add content to the sceneSelection tab
|
||||||
|
|
||||||
|
lv_obj_set_layout(tab, LV_LAYOUT_FLEX);
|
||||||
|
lv_obj_set_flex_flow(tab, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_set_scrollbar_mode(tab, LV_SCROLLBAR_MODE_ACTIVE);
|
||||||
|
|
||||||
|
// -- create a button for "standard" ----------------------------------------
|
||||||
|
lv_obj_t* button = lv_btn_create(tab);
|
||||||
|
lv_obj_set_size(button, 80, 40);
|
||||||
|
lv_obj_set_style_radius(button, 10, LV_PART_MAIN);
|
||||||
|
lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN);
|
||||||
|
lv_obj_add_event_cb(button, button_clicked_event_cb, LV_EVENT_CLICKED, (void *)(intptr_t) 0);
|
||||||
|
|
||||||
|
lv_obj_t* label = lv_label_create(button);
|
||||||
|
lv_label_set_text(label, "Standard");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void notify_tab_before_delete_yamahaAmp(void) {
|
||||||
|
// remember to set all pointers to lvgl objects to NULL if they might be accessed from outside.
|
||||||
|
// They must check if object is NULL and must not use it if so
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_gui_yamahaAmp(void){
|
||||||
|
register_gui(std::string(tabName_yamahaAmp), & create_tab_content_yamahaAmp, & notify_tab_before_delete_yamahaAmp);
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
const char * const tabName_yamahaAmp = "Yamaha Amp";
|
||||||
|
void register_gui_yamahaAmp(void);
|
|
@ -1,11 +1,13 @@
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
|
||||||
#include "applicationInternal/gui/guiBase.h"
|
#include "applicationInternal/gui/guiBase.h"
|
||||||
#include "applicationInternal/gui/guiRegistry.h"
|
#include "applicationInternal/gui/guiRegistry.h"
|
||||||
#include "devices/misc/device_smarthome/gui_smarthome.h"
|
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||||
|
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||||
#include "applicationInternal/commandHandler.h"
|
#include "applicationInternal/commandHandler.h"
|
||||||
|
#include "applicationInternal/keys.h"
|
||||||
|
#include "devices/misc/device_smarthome/gui_smarthome.h"
|
||||||
#include "devices/misc/device_smarthome/device_smarthome.h"
|
#include "devices/misc/device_smarthome/device_smarthome.h"
|
||||||
|
#include "scenes/scene__default.h"
|
||||||
|
|
||||||
// LVGL declarations
|
// LVGL declarations
|
||||||
LV_IMAGE_DECLARE(lightbulb);
|
LV_IMAGE_DECLARE(lightbulb);
|
||||||
|
@ -20,6 +22,12 @@ static bool lightToggleBstate = false;
|
||||||
static int32_t sliderAvalue = 0;
|
static int32_t sliderAvalue = 0;
|
||||||
static int32_t sliderBvalue = 0;
|
static int32_t sliderBvalue = 0;
|
||||||
|
|
||||||
|
uint16_t GUI_SMARTHOME_ACTIVATE;
|
||||||
|
|
||||||
|
std::map<char, repeatModes> key_repeatModes_smarthome = {};
|
||||||
|
std::map<char, uint16_t> key_commands_short_smarthome = {};
|
||||||
|
std::map<char, uint16_t> key_commands_long_smarthome = {};
|
||||||
|
|
||||||
// Smart Home Toggle Event handler
|
// Smart Home Toggle Event handler
|
||||||
static void smartHomeToggle_event_cb(lv_event_t* e){
|
static void smartHomeToggle_event_cb(lv_event_t* e){
|
||||||
std::string payload;
|
std::string payload;
|
||||||
|
@ -158,6 +166,23 @@ void notify_tab_before_delete_smarthome(void) {
|
||||||
sliderBvalue = lv_slider_get_value(sliderB);
|
sliderBvalue = lv_slider_get_value(sliderB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_gui_smarthome(void){
|
void gui_setKeys_smarthome() {
|
||||||
register_gui(std::string(tabName_smarthome), & create_tab_content_smarthome, & notify_tab_before_delete_smarthome);
|
key_commands_short_smarthome = {
|
||||||
|
{KEY_STOP, SCENE_SELECTION},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_gui_smarthome(void){
|
||||||
|
|
||||||
|
register_gui(
|
||||||
|
std::string(tabName_smarthome),
|
||||||
|
& create_tab_content_smarthome,
|
||||||
|
& notify_tab_before_delete_smarthome,
|
||||||
|
& gui_setKeys_smarthome,
|
||||||
|
& key_repeatModes_smarthome,
|
||||||
|
& key_commands_short_smarthome,
|
||||||
|
& key_commands_long_smarthome
|
||||||
|
);
|
||||||
|
|
||||||
|
register_command(&GUI_SMARTHOME_ACTIVATE, makeCommandData(GUI, {std::to_string(MAIN_GUI_LIST), std::string(tabName_smarthome)}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,4 +3,5 @@
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
const char * const tabName_smarthome = "Smart Home";
|
const char * const tabName_smarthome = "Smart Home";
|
||||||
|
extern uint16_t GUI_SMARTHOME_ACTIVATE;
|
||||||
void register_gui_smarthome(void);
|
void register_gui_smarthome(void);
|
||||||
|
|
|
@ -18,12 +18,12 @@ static void virtualKeypad_event_cb(lv_event_t* e) {
|
||||||
|
|
||||||
int user_data = (intptr_t)(target->user_data);
|
int user_data = (intptr_t)(target->user_data);
|
||||||
// send corrensponding number
|
// send corrensponding number
|
||||||
if (get_currentScene() == scene_name_TV) {
|
if (gui_memoryOptimizer_getActiveSceneName() == scene_name_TV) {
|
||||||
uint16_t virtualKeyMapTVNumbers[10] = {SAMSUNG_NUM_1, SAMSUNG_NUM_2, SAMSUNG_NUM_3, SAMSUNG_NUM_4, SAMSUNG_NUM_5, SAMSUNG_NUM_6, SAMSUNG_NUM_7, SAMSUNG_NUM_8, SAMSUNG_NUM_9, SAMSUNG_NUM_0};
|
uint16_t virtualKeyMapTVNumbers[10] = {SAMSUNG_NUM_1, SAMSUNG_NUM_2, SAMSUNG_NUM_3, SAMSUNG_NUM_4, SAMSUNG_NUM_5, SAMSUNG_NUM_6, SAMSUNG_NUM_7, SAMSUNG_NUM_8, SAMSUNG_NUM_9, SAMSUNG_NUM_0};
|
||||||
uint16_t command = virtualKeyMapTVNumbers[user_data];
|
uint16_t command = virtualKeyMapTVNumbers[user_data];
|
||||||
executeCommand(command);
|
executeCommand(command);
|
||||||
|
|
||||||
} else if (get_currentScene() == scene_name_fireTV) {
|
} else if (gui_memoryOptimizer_getActiveSceneName() == scene_name_fireTV) {
|
||||||
int virtualKeyMapFireTVNumbers[10] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0};
|
int virtualKeyMapFireTVNumbers[10] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0};
|
||||||
int number = virtualKeyMapFireTVNumbers[user_data];
|
int number = virtualKeyMapFireTVNumbers[user_data];
|
||||||
std::string numberStr = std::to_string(number);
|
std::string numberStr = std::to_string(number);
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "guis/gui_irReceiver.h"
|
#include "guis/gui_irReceiver.h"
|
||||||
#include "guis/gui_settings.h"
|
#include "guis/gui_settings.h"
|
||||||
#include "guis/gui_numpad.h"
|
#include "guis/gui_numpad.h"
|
||||||
|
#include "devices/AVreceiver/device_yamahaAmp/gui_yamahaAmp.h"
|
||||||
#include "devices/mediaPlayer/device_appleTV/gui_appleTV.h"
|
#include "devices/mediaPlayer/device_appleTV/gui_appleTV.h"
|
||||||
#include "devices/misc/device_smarthome/gui_smarthome.h"
|
#include "devices/misc/device_smarthome/gui_smarthome.h"
|
||||||
#include "applicationInternal/keys.h"
|
#include "applicationInternal/keys.h"
|
||||||
|
@ -102,6 +103,19 @@ int main(int argc, char *argv[]) {
|
||||||
#endif
|
#endif
|
||||||
register_keyboardCommands();
|
register_keyboardCommands();
|
||||||
|
|
||||||
|
// Register the GUIs. They will be displayed in the order they have been registered.
|
||||||
|
register_gui_sceneSelection();
|
||||||
|
register_gui_irReceiver();
|
||||||
|
register_gui_settings();
|
||||||
|
register_gui_appleTV();
|
||||||
|
register_gui_numpad();
|
||||||
|
register_gui_smarthome();
|
||||||
|
register_gui_yamahaAmp();
|
||||||
|
// Only show these GUIs in the main gui list. If you don't set this explicitely, by default all registered guis are shown.
|
||||||
|
#if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
|
||||||
|
main_gui_list = {tabName_yamahaAmp, tabName_sceneSelection, tabName_smarthome, tabName_settings, tabName_irReceiver};
|
||||||
|
#endif
|
||||||
|
|
||||||
// register the scenes and their key_commands_*
|
// register the scenes and their key_commands_*
|
||||||
register_scene_defaultKeys();
|
register_scene_defaultKeys();
|
||||||
register_scene_TV();
|
register_scene_TV();
|
||||||
|
@ -112,20 +126,9 @@ int main(int argc, char *argv[]) {
|
||||||
// Only show these scenes on the sceneSelection gui. If you don't set this explicitely, by default all registered scenes are shown.
|
// 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});
|
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();
|
|
||||||
register_gui_settings();
|
|
||||||
register_gui_appleTV();
|
|
||||||
register_gui_numpad();
|
|
||||||
register_gui_smarthome();
|
|
||||||
// Only show these GUIs in the main gui list. If you don't set this explicitely, by default all registered guis are shown.
|
|
||||||
#if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
|
|
||||||
main_gui_list = {tabName_sceneSelection, tabName_smarthome, tabName_settings, tabName_irReceiver};
|
|
||||||
#endif
|
|
||||||
// init GUI - will initialize tft, touch and lvgl
|
// init GUI - will initialize tft, touch and lvgl
|
||||||
init_gui();
|
init_gui();
|
||||||
setLabelCurrentScene();
|
setLabelActiveScene();
|
||||||
gui_loop(); // Run the LVGL UI once before the loop takes over
|
gui_loop(); // Run the LVGL UI once before the loop takes over
|
||||||
|
|
||||||
// setup the Inertial Measurement Unit (IMU) for motion detection. Has to be after init_gui(), otherwise I2C will not work
|
// setup the Inertial Measurement Unit (IMU) for motion detection. Has to be after init_gui(), otherwise I2C will not work
|
||||||
|
|
|
@ -33,7 +33,7 @@ void scene_setKeys_TV() {
|
||||||
|
|
||||||
key_commands_short_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_CONF, SAMSUNG_GUIDE }, {KEY_INFO, SAMSUNG_MENU },
|
||||||
{KEY_UP, SAMSUNG_UP },
|
{KEY_UP, SAMSUNG_UP },
|
||||||
{KEY_LEFT, SAMSUNG_LEFT }, {KEY_OK, SAMSUNG_SELECT }, {KEY_RIGHT, SAMSUNG_RIGHT },
|
{KEY_LEFT, SAMSUNG_LEFT }, {KEY_OK, SAMSUNG_SELECT }, {KEY_RIGHT, SAMSUNG_RIGHT },
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "applicationInternal/commandHandler.h"
|
#include "applicationInternal/commandHandler.h"
|
||||||
// devices
|
// devices
|
||||||
#include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h"
|
#include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h"
|
||||||
|
#include "devices/misc/device_smarthome/gui_smarthome.h"
|
||||||
// scenes
|
// scenes
|
||||||
#include "scene__default.h"
|
#include "scene__default.h"
|
||||||
#include "scenes/scene_allOff.h"
|
#include "scenes/scene_allOff.h"
|
||||||
|
@ -14,9 +15,11 @@
|
||||||
|
|
||||||
uint16_t SCENE_SELECTION;
|
uint16_t SCENE_SELECTION;
|
||||||
std::string scene_name_selection = "sceneSelection";
|
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_PREV;
|
||||||
uint16_t GUI_NEXT;
|
|
||||||
std::string scene_gui_prev = "GUI_prev";
|
std::string scene_gui_prev = "GUI_prev";
|
||||||
|
uint16_t GUI_NEXT;
|
||||||
std::string scene_gui_next = "GUI_next";
|
std::string scene_gui_next = "GUI_next";
|
||||||
|
|
||||||
std::map<char, repeatModes> key_repeatModes_default;
|
std::map<char, repeatModes> key_repeatModes_default;
|
||||||
|
@ -45,14 +48,14 @@ void register_scene_defaultKeys(void) {
|
||||||
|
|
||||||
key_commands_short_default = {
|
key_commands_short_default = {
|
||||||
{KEY_OFF, SCENE_ALLOFF_FORCE},
|
{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_CONF, COMMAND_UNKNOWN }, {KEY_INFO, COMMAND_UNKNOWN },*/
|
||||||
/* {KEY_UP, COMMAND_UNKNOWN },*/
|
/* {KEY_UP, COMMAND_UNKNOWN },*/
|
||||||
{KEY_LEFT, GUI_PREV }, /* {KEY_OK, COMMAND_UNKNOWN },*/ {KEY_RIGHT, GUI_NEXT },
|
{KEY_LEFT, GUI_PREV }, /* {KEY_OK, COMMAND_UNKNOWN },*/ {KEY_RIGHT, GUI_NEXT },
|
||||||
/* {KEY_DOWN, COMMAND_UNKNOWN },*/
|
/* {KEY_DOWN, COMMAND_UNKNOWN },*/
|
||||||
{KEY_BACK, SCENE_SELECTION }, /*{KEY_SRC, 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_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},
|
{KEY_RED, SCENE_TV_FORCE }, {KEY_GREEN, SCENE_FIRETV_FORCE}, {KEY_YELLO, SCENE_CHROMECAST_FORCE},{KEY_BLUE, SCENE_APPLETV_FORCE},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,6 +65,7 @@ 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(&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_PREV , makeCommandData(SCENE, {scene_gui_prev}));
|
||||||
register_command(&GUI_NEXT , makeCommandData(SCENE, {scene_gui_next}));
|
register_command(&GUI_NEXT , makeCommandData(SCENE, {scene_gui_next}));
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,11 @@
|
||||||
|
|
||||||
extern uint16_t SCENE_SELECTION; // command
|
extern uint16_t SCENE_SELECTION; // command
|
||||||
extern std::string scene_name_selection; // payload: name of this fake default scene
|
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 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_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::string scene_gui_next; // payload: name of this fake scene
|
||||||
|
|
||||||
extern std::map<char, repeatModes> key_repeatModes_default;
|
extern std::map<char, repeatModes> key_repeatModes_default;
|
||||||
|
|
Loading…
Reference in a new issue