gui for scene selection
This commit is contained in:
		
							parent
							
								
									4568d0338e
								
							
						
					
					
						commit
						90a098f3c8
					
				
					 36 changed files with 684 additions and 123 deletions
				
			
		|  | @ -9,13 +9,22 @@ void save_preferences_HAL(void) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string get_currentScene_HAL() { | std::string get_currentScene_HAL() { | ||||||
|   return currentScene; |   // if (currentScene == "") {
 | ||||||
|  |   // // 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_currentScene_HAL(std::string aCurrentScene) { | ||||||
|   currentScene = aCurrentScene; |   currentScene = aCurrentScene; | ||||||
| } | } | ||||||
| std::string get_currentGUIname_HAL(){ | std::string get_currentGUIname_HAL(){ | ||||||
|   return currentGUIname; |   // if (currentGUIname == "") {
 | ||||||
|  |   // // 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_currentGUIname_HAL(std::string aCurrentGUIname) { | ||||||
|   currentGUIname = aCurrentGUIname; |   currentGUIname = aCurrentGUIname; | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ build_flags = | ||||||
| 	-D ENABLE_KEYBOARD_MQTT=0 | 	-D ENABLE_KEYBOARD_MQTT=0 | ||||||
| 	-D ENABLE_BLUETOOTH=1 | 	-D ENABLE_BLUETOOTH=1 | ||||||
| 	-D ENABLE_KEYBOARD_BLE=1 | 	-D ENABLE_KEYBOARD_BLE=1 | ||||||
|  | 	-D USE_SCENE_SPECIFIC_GUI_LIST=1 | ||||||
| 	-D SCR_WIDTH=${env.custom_screen_width} | 	-D SCR_WIDTH=${env.custom_screen_width} | ||||||
| 	-D SCR_HEIGHT=${env.custom_screen_heigth} | 	-D SCR_HEIGHT=${env.custom_screen_heigth} | ||||||
| 	;-- lvgl ------------------------------------------------------------------ | 	;-- lvgl ------------------------------------------------------------------ | ||||||
|  | @ -68,6 +69,10 @@ build_flags = | ||||||
| 	; lvgl variant 2: | 	; lvgl variant 2: | ||||||
| 	; or define where lv_conf.h is, relative to the `lvgl` folder | 	; or define where lv_conf.h is, relative to the `lvgl` folder | ||||||
| 	;-D LV_CONF_PATH=../../../../src/gui_general_and_keys/lv_conf.h | 	;-D LV_CONF_PATH=../../../../src/gui_general_and_keys/lv_conf.h | ||||||
|  | 	; --- interesting lvgl debug infos (OSD) | ||||||
|  | 	;-D LV_USE_PERF_MONITOR=1 | ||||||
|  | 	;-D LV_USE_MEM_MONITOR=1 | ||||||
|  | 	;-D LV_USE_REFR_DEBUG=1 | ||||||
| 
 | 
 | ||||||
| [env:esp32] | [env:esp32] | ||||||
| platform = espressif32 | platform = espressif32 | ||||||
|  |  | ||||||
|  | @ -12,6 +12,8 @@ | ||||||
| // show received IR and MQTT messages
 | // show received IR and MQTT messages
 | ||||||
| #include "guis/gui_irReceiver.h" | #include "guis/gui_irReceiver.h" | ||||||
| 
 | 
 | ||||||
|  | uint16_t COMMAND_UNKNOWN; | ||||||
|  | 
 | ||||||
| uint16_t KEYBOARD_DUMMY_UP                  ; //"Keyboard_dummy_up"
 | uint16_t KEYBOARD_DUMMY_UP                  ; //"Keyboard_dummy_up"
 | ||||||
| uint16_t KEYBOARD_DUMMY_DOWN                ; //"Keyboard_dummy_down"
 | uint16_t KEYBOARD_DUMMY_DOWN                ; //"Keyboard_dummy_down"
 | ||||||
| uint16_t KEYBOARD_DUMMY_RIGHT               ; //"Keyboard_dummy_right"
 | uint16_t KEYBOARD_DUMMY_RIGHT               ; //"Keyboard_dummy_right"
 | ||||||
|  |  | ||||||
|  | @ -7,6 +7,8 @@ | ||||||
| #include "devices/keyboard/device_keyboard_mqtt/device_keyboard_mqtt.h" | #include "devices/keyboard/device_keyboard_mqtt/device_keyboard_mqtt.h" | ||||||
| #include "devices/keyboard/device_keyboard_ble/device_keyboard_ble.h" | #include "devices/keyboard/device_keyboard_ble/device_keyboard_ble.h" | ||||||
| 
 | 
 | ||||||
|  | extern uint16_t COMMAND_UNKNOWN; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|   Depending on which keyboard is enabled (BLE or MQTT), we define KEYBOARD_UP, KEYBOARD_DOWN and so on. |   Depending on which keyboard is enabled (BLE or MQTT), we define KEYBOARD_UP, KEYBOARD_DOWN and so on. | ||||||
|   These defines are used in keys.cpp, gui*.cpp and commandHandler.cpp |   These defines are used in keys.cpp, gui*.cpp and commandHandler.cpp | ||||||
|  |  | ||||||
|  | @ -2,6 +2,9 @@ | ||||||
| #include "applicationInternal/hardware/hardwarePresenter.h" | #include "applicationInternal/hardware/hardwarePresenter.h" | ||||||
| #include "applicationInternal/memoryUsage.h" | #include "applicationInternal/memoryUsage.h" | ||||||
| #include "applicationInternal/gui/guiMemoryOptimizer.h" | #include "applicationInternal/gui/guiMemoryOptimizer.h" | ||||||
|  | // for changing to scene Selection gui
 | ||||||
|  | #include "applicationInternal/commandHandler.h" | ||||||
|  | #include "scenes/scene__defaultKeys.h" | ||||||
| 
 | 
 | ||||||
| lv_color_t color_primary = lv_color_hex(0x303030); // gray
 | lv_color_t color_primary = lv_color_hex(0x303030); // gray
 | ||||||
| lv_obj_t* MemoryUsageLabel = NULL; | lv_obj_t* MemoryUsageLabel = NULL; | ||||||
|  | @ -26,10 +29,26 @@ lv_style_t style_red_border; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| void guis_doTabCreationAtStartup(); | void guis_doTabCreationAtStartup(); | ||||||
| void guis_doAfterSliding(int oldTabID, int newTabID); | void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList); | ||||||
| 
 | 
 | ||||||
| // Helper Functions -----------------------------------------------------------------------------------------------------------------------
 | // Helper Functions -----------------------------------------------------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|  | // callback when sceneLabel or pageIndicator was clicked
 | ||||||
|  | void sceneLabel_or_pageIndicator_event_cb(lv_event_t* e) { | ||||||
|  |   Serial.println("- Scene selection: sceneLabel or pageIndicator clicked received for navigating to scene selection page"); | ||||||
|  |   executeCommand(SCENE_SELECTION); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // callback for swipe down event to navigate to the scene selection page
 | ||||||
|  | void screen_gesture_event_cb(lv_event_t* e) { | ||||||
|  |   lv_obj_t* screen = lv_event_get_current_target(e); | ||||||
|  |   lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); | ||||||
|  |   if (dir == LV_DIR_BOTTOM) { | ||||||
|  |     Serial.println("- Scene selection: swipe down received for navigating to scene selection page"); | ||||||
|  |     executeCommand(SCENE_SELECTION); | ||||||
|  |   }     | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Set the page indicator (panel) scroll position relative to the tabview content scroll position
 | // Set the page indicator (panel) scroll position relative to the tabview content scroll position
 | ||||||
| // this is a callback if the CONTENT of the tabview is scrolled (LV_EVENT_SCROLL)
 | // this is a callback if the CONTENT of the tabview is scrolled (LV_EVENT_SCROLL)
 | ||||||
| void tabview_content_is_scrolling_event_cb(lv_event_t* e){ | void tabview_content_is_scrolling_event_cb(lv_event_t* e){ | ||||||
|  | @ -62,7 +81,7 @@ static void tabview_animation_ready_cb(lv_anim_t* a) { | ||||||
|   // 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);
 |   // guis_doAfterSliding(oldTabID, currentTabID, false);
 | ||||||
| 
 | 
 | ||||||
|   waitBeforeActionAfterSlidingAnimationEnded = true; |   waitBeforeActionAfterSlidingAnimationEnded = true; | ||||||
|   waitBeforeActionAfterSlidingAnimationEnded_timerStart = millis(); |   waitBeforeActionAfterSlidingAnimationEnded_timerStart = millis(); | ||||||
|  | @ -77,7 +96,7 @@ void tabview_tab_changed_event_cb(lv_event_t* e) { | ||||||
|     oldTabID = currentTabID; |     oldTabID = currentTabID; | ||||||
|     currentTabID = lv_tabview_get_tab_act(lv_event_get_target(e)); |     currentTabID = lv_tabview_get_tab_act(lv_event_get_target(e)); | ||||||
| 
 | 
 | ||||||
|     // Wait until the animation ended, then call "guis_doAfterSliding(oldTabID, currentTabID);"
 |     // Wait until the animation ended, then call "guis_doAfterSliding(oldTabID, currentTabID, false);"
 | ||||||
|     // 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_event_get_target(e); |     lv_obj_t* myTabview = lv_event_get_target(e); | ||||||
|     lv_obj_t* tabContainer = lv_tabview_get_content(myTabview); |     lv_obj_t* tabContainer = lv_tabview_get_content(myTabview); | ||||||
|  | @ -91,7 +110,7 @@ void tabview_tab_changed_event_cb(lv_event_t* e) { | ||||||
|     } 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); |       guis_doAfterSliding(oldTabID, currentTabID, false); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -131,6 +150,10 @@ void init_gui(void) { | ||||||
|   init_gui_memoryUsage_bar(); |   init_gui_memoryUsage_bar(); | ||||||
|   // status bar
 |   // status bar
 | ||||||
|   init_gui_status_bar(); |   init_gui_status_bar(); | ||||||
|  | 
 | ||||||
|  |   // register callback for swipe down event to navigate to the scene selection page
 | ||||||
|  |   lv_obj_add_event_cb(lv_scr_act(), screen_gesture_event_cb, LV_EVENT_GESTURE, NULL); | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int panelHeight; | int panelHeight; | ||||||
|  | @ -205,6 +228,7 @@ void init_gui_memoryUsage_bar() { | ||||||
| void init_gui_status_bar() { | void init_gui_status_bar() { | ||||||
|   // Create a status bar at the top -------------------------------------------------------------------------
 |   // Create a status bar at the top -------------------------------------------------------------------------
 | ||||||
|   statusbar = lv_btn_create(lv_scr_act()); |   statusbar = lv_btn_create(lv_scr_act()); | ||||||
|  |   lv_obj_clear_flag(statusbar, LV_OBJ_FLAG_CLICKABLE); | ||||||
|   lv_obj_set_size(statusbar, SCR_WIDTH, statusbarHeight); |   lv_obj_set_size(statusbar, SCR_WIDTH, statusbarHeight); | ||||||
|   lv_obj_set_style_shadow_width(statusbar, 0, LV_PART_MAIN); |   lv_obj_set_style_shadow_width(statusbar, 0, LV_PART_MAIN); | ||||||
|   lv_obj_set_style_bg_color(statusbar, lv_color_black(), LV_PART_MAIN); |   lv_obj_set_style_bg_color(statusbar, lv_color_black(), LV_PART_MAIN); | ||||||
|  | @ -231,6 +255,9 @@ void init_gui_status_bar() { | ||||||
|   lv_label_set_text(SceneLabel, ""); |   lv_label_set_text(SceneLabel, ""); | ||||||
|   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_event_cb(SceneLabel, sceneLabel_or_pageIndicator_event_cb, LV_EVENT_CLICKED, NULL); | ||||||
|  | 
 | ||||||
|   // Battery ----------------------------------------------------------------------
 |   // Battery ----------------------------------------------------------------------
 | ||||||
|   BattPercentageLabel = lv_label_create(statusbar); |   BattPercentageLabel = lv_label_create(statusbar); | ||||||
|   lv_label_set_text(BattPercentageLabel, ""); |   lv_label_set_text(BattPercentageLabel, ""); | ||||||
|  | @ -251,12 +278,12 @@ void gui_loop(void) { | ||||||
|     waitBeforeActionAfterSlidingAnimationEnded = false; |     waitBeforeActionAfterSlidingAnimationEnded = false; | ||||||
|   } else if (waitOneLoop) { |   } else if (waitOneLoop) { | ||||||
|     waitOneLoop = false; |     waitOneLoop = false; | ||||||
|     guis_doAfterSliding(oldTabID, currentTabID); |     guis_doAfterSliding(oldTabID, currentTabID, false); | ||||||
|   }; |   }; | ||||||
|   // // 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);
 |   //     guis_doAfterSliding(oldTabID, currentTabID, false);
 | ||||||
|   //     waitBeforeActionAfterSlidingAnimationEnded = false;
 |   //     waitBeforeActionAfterSlidingAnimationEnded = false;
 | ||||||
|   //   }
 |   //   }
 | ||||||
|   // }
 |   // }
 | ||||||
|  | @ -267,11 +294,13 @@ void gui_loop(void) { | ||||||
| void guis_doTabCreationAtStartup() { | void guis_doTabCreationAtStartup() { | ||||||
|   gui_memoryOptimizer_prepare_startup(); |   gui_memoryOptimizer_prepare_startup(); | ||||||
| 
 | 
 | ||||||
|   guis_doAfterSliding(-1, -1); |   guis_doAfterSliding(-1, -1, false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void guis_doAfterSliding(int oldTabID, int newTabID) { | void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList) { | ||||||
|   gui_memoryOptimizer_doAfterSliding_deletionAndCreation(&tabview, oldTabID, newTabID, &panel, &img1, &img2); |   // 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(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -30,8 +30,11 @@ 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 setActiveTab(uint32_t index, lv_anim_enable_t anim_en); | void setActiveTab(uint32_t index, lv_anim_enable_t anim_en); | ||||||
| // 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,13 +1,16 @@ | ||||||
| #include <lvgl.h> | #include <lvgl.h> | ||||||
| #include "applicationInternal/gui/guiBase.h" | #include "applicationInternal/gui/guiBase.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" | ||||||
| 
 | 
 | ||||||
| struct tab_in_memory { | struct tab_in_memory { | ||||||
|   lv_obj_t* tab; |   lv_obj_t* tab; | ||||||
|   int listIndex; |   int listIndex; | ||||||
|  |   std::string guiName; | ||||||
| }; | }; | ||||||
| tab_in_memory tabs_in_memory[3] = {{NULL, -1}, {NULL, -1}, {NULL, -1}}; | tab_in_memory tabs_in_memory[3] = {{NULL, -1, ""}, {NULL, -1, ""}, {NULL, -1, ""}}; | ||||||
|  | // holds the ids of the tabs we had in memory before, so that we can determine the next or previous id
 | ||||||
| int tabs_in_memory_previous_listIndex[3]= {-1 , -1, -1}; | int tabs_in_memory_previous_listIndex[3]= {-1 , -1, -1}; | ||||||
| 
 | 
 | ||||||
| void notify_active_tabs_before_delete() { | void notify_active_tabs_before_delete() { | ||||||
|  | @ -19,7 +22,9 @@ void notify_active_tabs_before_delete() { | ||||||
|       continue; |       continue; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     nameOfTab = list_of_guis_to_be_shown.at(tabs_in_memory[index].listIndex); |     // For deletion, do not use the listIndex, 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.
 | ||||||
|  |     nameOfTab = tabs_in_memory[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) { | ||||||
|  | @ -42,9 +47,9 @@ void clear_tabview(lv_obj_t* tabview) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // set struct tabs_in_memory to NULL
 |   // set struct tabs_in_memory to NULL
 | ||||||
|   tabs_in_memory[0] = {NULL, -1}; |   tabs_in_memory[0] = {NULL, -1, ""}; | ||||||
|   tabs_in_memory[1] = {NULL, -1}; |   tabs_in_memory[1] = {NULL, -1, ""}; | ||||||
|   tabs_in_memory[2] = {NULL, -1}; |   tabs_in_memory[2] = {NULL, -1, ""}; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -79,7 +84,8 @@ lv_obj_t* create_tabview() { | ||||||
| lv_obj_t* create_panel() { | lv_obj_t* create_panel() { | ||||||
|   // Create a page indicator at the bottom ------------------------------------------------------------------
 |   // Create a page indicator at the bottom ------------------------------------------------------------------
 | ||||||
|   lv_obj_t* panel = lv_obj_create(lv_scr_act()); |   lv_obj_t* panel = lv_obj_create(lv_scr_act()); | ||||||
|   lv_obj_clear_flag(panel, LV_OBJ_FLAG_CLICKABLE); // This indicator will not be clickable
 |   lv_obj_clear_flag(panel, LV_OBJ_FLAG_CLICKABLE);  // This indicator will not be clickable
 | ||||||
|  |   lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLLABLE); // This indicator will not be scrollable
 | ||||||
|   lv_obj_set_size(panel, SCR_WIDTH, panelHeight); |   lv_obj_set_size(panel, SCR_WIDTH, panelHeight); | ||||||
|   lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW); |   lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW); | ||||||
|   lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0); |   lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0); | ||||||
|  | @ -91,8 +97,8 @@ 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 <= list_of_guis_to_be_shown.size() -1) { |   } else if (index <= get_gui_list(get_currentScene())->size() -1) { | ||||||
|     return list_of_guis_to_be_shown.at(index); |     return get_gui_list(get_currentScene())->at(index); | ||||||
|   } else { |   } else { | ||||||
|     return ""; |     return ""; | ||||||
|   } |   } | ||||||
|  | @ -107,6 +113,8 @@ void create_new_tab(lv_obj_t* tabview, uint32_t tabs_in_memory_index) { | ||||||
|     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 at index %d because name %s was not found in registry\r\n", tabs_in_memory_index, 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\" at index %d\r\n", nameOfTab.c_str(), tabs_in_memory_index); | ||||||
|  |     // save name of tab for deletion later
 | ||||||
|  |     tabs_in_memory[tabs_in_memory_index].guiName = nameOfTab; | ||||||
|     // create tab and save pointer to tab in tabs_in_memory
 |     // create tab and save pointer to tab in tabs_in_memory
 | ||||||
|     tabs_in_memory[tabs_in_memory_index].tab = lv_tabview_add_tab(tabview, nameOfTab.c_str()); |     tabs_in_memory[tabs_in_memory_index].tab = lv_tabview_add_tab(tabview, nameOfTab.c_str()); | ||||||
|     // let the gui create it's content
 |     // let the gui create it's content
 | ||||||
|  | @ -117,7 +125,7 @@ void create_new_tab(lv_obj_t* tabview, uint32_t tabs_in_memory_index) { | ||||||
| void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t newTabID) { | 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: list_of_guis_to_be_shown: 0 1 2 3 4 |   example: gui_list: 0 1 2 3 4 | ||||||
|   in memory  active |   in memory  active | ||||||
|   0 1 -1     0 <- first state, special case - also the initial state |   0 1 -1     0 <- first state, special case - also the initial state | ||||||
|   0 1 2      1 |   0 1 2      1 | ||||||
|  | @ -132,8 +140,8 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n | ||||||
|   if ((oldTabID == -1) && (newTabID == -1)) { |   if ((oldTabID == -1) && (newTabID == -1)) { | ||||||
|     // This is the initialization after the ESP32 has booted.
 |     // This is the initialization after the ESP32 has booted.
 | ||||||
| 
 | 
 | ||||||
|     if ((tabs_in_memory_previous_listIndex[0] < list_of_guis_to_be_shown.size()) && (tabs_in_memory_previous_listIndex[0] != -1)) { |     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 list_of_guis_to_be_shown was saved, if found.
 |       // In gui_memoryOptimizer_prepare_startup, the index of get_currentGUIname() in gui_list was saved, if found.
 | ||||||
|       // We can resume at this old state.
 |       // We can resume at this old state.
 | ||||||
|       oldListIndex = tabs_in_memory_previous_listIndex[0] ;  |       oldListIndex = tabs_in_memory_previous_listIndex[0] ;  | ||||||
|       if (oldListIndex == 0) { |       if (oldListIndex == 0) { | ||||||
|  | @ -141,10 +149,10 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n | ||||||
|         Serial.printf("  Startup: will resume where we went to sleep with \"first state\"\r\n"); |         Serial.printf("  Startup: will resume where we went to sleep with \"first state\"\r\n"); | ||||||
|         tabs_in_memory[0] = {NULL, 0}; |         tabs_in_memory[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, list_of_guis_to_be_shown.size() >= 2 ? 1 : -1}; |         tabs_in_memory[1] = {NULL, get_gui_list(get_currentScene())->size() >= 2 ? 1 : -1}; | ||||||
|         tabs_in_memory[2] = {NULL, -1}; |         tabs_in_memory[2] = {NULL, -1}; | ||||||
|         tabToBeActivated = 0; |         tabToBeActivated = 0; | ||||||
|       } else if (oldListIndex == list_of_guis_to_be_shown.size() -1) { |       } else if (oldListIndex == get_gui_list(get_currentScene())->size() -1) { | ||||||
|         // last state
 |         // last state
 | ||||||
|         Serial.printf("  Startup: will resume where we went to sleep with \"last state\"\r\n"); |         Serial.printf("  Startup: will resume where we went to sleep with \"last state\"\r\n"); | ||||||
|         tabs_in_memory[0] = {NULL, oldListIndex -1}; |         tabs_in_memory[0] = {NULL, oldListIndex -1}; | ||||||
|  | @ -160,11 +168,11 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n | ||||||
|         tabToBeActivated = 1; |         tabToBeActivated = 1; | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       Serial.printf("  Startup: cannot resume old state, so we will show the first tabs from \"list_of_guis_to_be_shown\" as initial state\r\n"); |       Serial.printf("  Startup: cannot resume old state, so we will show the first tabs 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, list_of_guis_to_be_shown.size() != 0 ? 0 : -1}; |       tabs_in_memory[0] = {NULL, get_gui_list(get_currentScene())->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, list_of_guis_to_be_shown.size() >= 2 ? 1 : -1}; |       tabs_in_memory[1] = {NULL, get_gui_list(get_currentScene())->size() >= 2 ? 1 : -1}; | ||||||
|       tabs_in_memory[2] = {NULL, -1}; |       tabs_in_memory[2] = {NULL, -1}; | ||||||
|       tabToBeActivated = 0; |       tabToBeActivated = 0; | ||||||
|     } |     } | ||||||
|  | @ -193,7 +201,7 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n | ||||||
|     } else { |     } else { | ||||||
|       oldListIndex = tabs_in_memory_previous_listIndex[1]; |       oldListIndex = tabs_in_memory_previous_listIndex[1]; | ||||||
|     } |     } | ||||||
|     if (oldListIndex == list_of_guis_to_be_shown.size() -2) { |     if (oldListIndex == get_gui_list(get_currentScene())->size() -2) { | ||||||
|       // next state is the "last state"
 |       // next state is the "last state"
 | ||||||
|       tabs_in_memory[0] = {NULL, oldListIndex}; |       tabs_in_memory[0] = {NULL, oldListIndex}; | ||||||
|       tabs_in_memory[1] = {NULL, oldListIndex +1}; |       tabs_in_memory[1] = {NULL, oldListIndex +1}; | ||||||
|  | @ -213,8 +221,8 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n | ||||||
|     create_new_tab(tabview, i); |     create_new_tab(tabview, i); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (list_of_guis_to_be_shown.size() > 0) { |   if (get_gui_list(get_currentScene())->size() > 0) { | ||||||
|     std::string nameOfNewActiveTab = list_of_guis_to_be_shown.at(tabs_in_memory[tabToBeActivated].listIndex); |     std::string nameOfNewActiveTab = get_gui_list(get_currentScene())->at(tabs_in_memory[tabToBeActivated].listIndex); | ||||||
|     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 the tab we swiped to as active
 | ||||||
|  | @ -227,10 +235,24 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n | ||||||
| LV_IMG_DECLARE(gradientLeft); | LV_IMG_DECLARE(gradientLeft); | ||||||
| LV_IMG_DECLARE(gradientRight); | LV_IMG_DECLARE(gradientRight); | ||||||
| 
 | 
 | ||||||
|  | void getBreadcrumpPosition(uint8_t* breadcrumpPosition, std::string nameOfTab) { | ||||||
|  |   *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) { | 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 (list_of_guis_to_be_shown.size() == 0) { |   if (get_gui_list(get_currentScene())->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); | ||||||
|  | @ -250,7 +272,7 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv | ||||||
|   There needs to be two more screen indicators because of their different size (158 for page indicator, 240 for whole tab) |   There needs to be two more screen indicators because of their different size (158 for page indicator, 240 for whole tab) | ||||||
|   In some cases they need to have color black, if they are before the first tab or after the last tab. |   In some cases they need to have color black, if they are before the first tab or after the last tab. | ||||||
|   In all other cases, they have color "color_primary". See this list: |   In all other cases, they have color "color_primary". See this list: | ||||||
|   example: list_of_guis_to_be_shown: 0 1 2 3 4 |   example: gui_list: 0 1 2 3 4 | ||||||
|   in memory  color         active |   in memory  color         active | ||||||
|   0 1 -1     b p p p       0 <- first state, special case - also the initial state |   0 1 -1     b p p p       0 <- first state, special case - also the initial state | ||||||
|   0 1 2      b p p p p     1 |   0 1 2      b p p p p     1 | ||||||
|  | @ -268,21 +290,54 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv | ||||||
|     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 breadcrumpDotDistance = 2; // should be an even number
 | ||||||
|  |   int8_t breadcrumpStartPositionX = (-1) * (breadcrumpLength -1) * (breadcrumpDotSize + breadcrumpDotDistance) / 2; | ||||||
|  | 
 | ||||||
|   // 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 nameOfTab; | ||||||
|  |   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 (tabs_in_memory[i].listIndex != -1) { | ||||||
|       nameOfTab = get_name_of_gui_to_be_shown(tabs_in_memory[i].listIndex); |       nameOfTab = tabs_in_memory[i].guiName; | ||||||
|  |       getBreadcrumpPosition(&breadcrumpPosition, nameOfTab); | ||||||
| 
 | 
 | ||||||
|       // Create actual (non-clickable) buttons for every tab
 |       // Create actual buttons for every tab
 | ||||||
|       lv_obj_t* btn = lv_btn_create(panel); |       lv_obj_t* btn = lv_btn_create(panel); | ||||||
|       lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE); |       // 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_event_cb(btn, sceneLabel_or_pageIndicator_event_cb, LV_EVENT_CLICKED, NULL); | ||||||
|  |       } | ||||||
|       lv_obj_set_size(btn, 150, lv_pct(100)); |       lv_obj_set_size(btn, 150, lv_pct(100)); | ||||||
|       lv_obj_t* label = lv_label_create(btn); |       lv_obj_remove_style(btn, NULL, LV_STATE_PRESSED); | ||||||
|       lv_label_set_text_fmt(label, "%s", nameOfTab.c_str()); |  | ||||||
|       lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); |  | ||||||
|       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
 | ||||||
|  |       for (int j=0; j<breadcrumpLength; j++) { | ||||||
|  |         lv_obj_t* dot = lv_obj_create(btn); | ||||||
|  |         lv_obj_set_size(dot, breadcrumpDotSize, breadcrumpDotSize); | ||||||
|  |         lv_obj_set_style_radius(dot, LV_RADIUS_CIRCLE, LV_PART_MAIN); | ||||||
|  |         // hightlight dot if it is the one for the currently active tab
 | ||||||
|  |         if (j == (breadcrumpPosition-1)) { | ||||||
|  |           lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 200), LV_PART_MAIN); | ||||||
|  |         } else { | ||||||
|  |           lv_obj_set_style_bg_color(dot, lv_color_lighten(color_primary, 100), LV_PART_MAIN); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         lv_obj_align(dot, LV_ALIGN_TOP_MID, breadcrumpStartPositionX +j*(breadcrumpDotSize + breadcrumpDotDistance), -6); | ||||||
|  |         // this dot needs to get clickable again
 | ||||||
|  |         lv_obj_add_flag(dot, LV_OBJ_FLAG_CLICKABLE); | ||||||
|  |         lv_obj_add_flag(dot, LV_OBJ_FLAG_EVENT_BUBBLE); | ||||||
|  | 
 | ||||||
|  |       } | ||||||
|  |       lv_obj_t* label = lv_label_create(btn); | ||||||
|  |       lv_obj_set_style_text_font(label, &lv_font_montserrat_10, LV_PART_MAIN); | ||||||
|  |       lv_label_set_text_fmt(label, "%s", nameOfTab.c_str()); | ||||||
|  |       lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, 6); | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -290,8 +345,8 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv | ||||||
|   btn = lv_btn_create(panel); |   btn = lv_btn_create(panel); | ||||||
|   lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE); |   lv_obj_clear_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 == list_of_guis_to_be_shown.size()-1) || (tabs_in_memory[1].listIndex == list_of_guis_to_be_shown.size()-1) || (tabs_in_memory[1].listIndex == -1)) { |   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)) { | ||||||
|     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); | ||||||
|  | @ -333,40 +388,66 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void gui_memoryOptimizer_prepare_startup() { | void gui_memoryOptimizer_prepare_startup() { | ||||||
|   // find index of get_currentGUIname() in list_of_guis_to_be_shown
 |   // find index of get_currentGUIname() in gui_list
 | ||||||
|   for (int i=0; i<list_of_guis_to_be_shown.size(); i++) { |   for (int i=0; i<get_gui_list(get_currentScene())->size(); i++) { | ||||||
|     if (list_of_guis_to_be_shown[i] == get_currentGUIname()) { |     if (get_gui_list(get_currentScene())->at(i) == get_currentGUIname()) { | ||||||
|       Serial.printf("Startup: found GUI with name \"%s\" in \"list_of_guis_to_be_shown\" at position %d\r\n", get_currentGUIname().c_str(), i); |       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
 |       // save position so that "guis_doAfterSliding" can use it
 | ||||||
|       tabs_in_memory[0].listIndex = i; |       tabs_in_memory[0].listIndex = i; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   // if the gui was not found in main_gui_list, try to find it in scene specific list
 | ||||||
|  |   if (tabs_in_memory[0].listIndex == -1) { | ||||||
|  |     useSceneGUIlist = true; | ||||||
|  |     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 scene specific \"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 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, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2) { | 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) { | ||||||
|   // 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"); | ||||||
|  | 
 | ||||||
|   bool isInitialization = ((oldTabID == -1) && (newTabID == -1)); |   bool isInitialization = ((oldTabID == -1) && (newTabID == -1)); | ||||||
|   if (isInitialization) { |   if (isInitialization) { | ||||||
|     Serial.printf("Startup: will initially create the tabs to be shown\r\n"); |     Serial.printf("Startup: will initially create the tabs to be shown\r\n"); | ||||||
|   } else { |   } 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, list_of_guis_to_be_shown.at(tabs_in_memory[oldTabID].listIndex).c_str(), |       oldTabID, get_gui_list(get_currentScene())->at(tabs_in_memory[oldTabID].listIndex).c_str(), | ||||||
|       newTabID, list_of_guis_to_be_shown.at(tabs_in_memory[newTabID].listIndex).c_str()); |       newTabID, get_gui_list(get_currentScene())->at(tabs_in_memory[newTabID].listIndex).c_str()); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // save the ids of the tabs we had in memory before
 |   // 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.
 | ||||||
|   for (int i=0; i<3; i++) { |   for (int i=0; i<3; i++) { | ||||||
|     tabs_in_memory_previous_listIndex[i] = tabs_in_memory[i].listIndex; |     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
 |   // the old tabs need to be notified that they will be deleted so that they can persist their state if needed
 | ||||||
|   if (!isInitialization) notify_active_tabs_before_delete(); |   notify_active_tabs_before_delete(); | ||||||
|   // clear current tabview
 |   // clear current tabview
 | ||||||
|   clear_tabview(*tabview); |   clear_tabview(*tabview); | ||||||
|   // clear current panel for page indicator
 |   // clear current panel for page indicator
 | ||||||
|  | @ -374,13 +455,19 @@ void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview, | ||||||
| 
 | 
 | ||||||
|   // 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.
 | ||||||
|   // lv_obj_t * oldscr = lv_scr_act();
 |   // lv_obj_t* oldscr = lv_scr_act();
 | ||||||
|   // // create new screen
 |   // // create new screen
 | ||||||
|   // lv_obj_t * newscr = lv_obj_create(NULL);
 |   // lv_obj_t* newscr = lv_obj_create(NULL);
 | ||||||
|   // // load this new screen
 |   // // load this new screen
 | ||||||
|   // lv_scr_load(newscr);
 |   // lv_scr_load(newscr);
 | ||||||
|   // lv_obj_del(oldscr);
 |   // lv_obj_del(oldscr);
 | ||||||
| 
 | 
 | ||||||
|  |   if (newGuiList) { | ||||||
|  |     // If we are switching to a new gui list, then we need to set tabs_in_memory_previous_listIndex[0] = -1;
 | ||||||
|  |     // Doing so, doTabCreation_strategyMax3() knows that we cannot resume an old state.
 | ||||||
|  |     tabs_in_memory_previous_listIndex[0] = -1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   // recreate the tabview
 |   // recreate the tabview
 | ||||||
|   lv_obj_t* newTabview = create_tabview(); |   lv_obj_t* newTabview = create_tabview(); | ||||||
|   *tabview = newTabview; |   *tabview = newTabview; | ||||||
|  | @ -401,4 +488,6 @@ void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview, | ||||||
|   // Initialize scroll position of the page indicator
 |   // Initialize scroll position of the page indicator
 | ||||||
|   lv_event_send(lv_tabview_get_content(*tabview), LV_EVENT_SCROLL, NULL); |   lv_event_send(lv_tabview_get_content(*tabview), LV_EVENT_SCROLL, NULL); | ||||||
| 
 | 
 | ||||||
|  |   Serial.printf("------------ End of tab deletion and creation\r\n"); | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| void gui_memoryOptimizer_prepare_startup(); | void gui_memoryOptimizer_prepare_startup(); | ||||||
| void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview, int oldTabID, int newTabID, lv_obj_t** panel, lv_obj_t** img1, lv_obj_t** img2); | 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); | ||||||
|  |  | ||||||
|  | @ -6,13 +6,11 @@ | ||||||
| #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 "scenes/scene__defaultKeys.h" | ||||||
| 
 | 
 | ||||||
| // ------------------------------------------------------------------------------------
 | // ------------------------------------------------------------------------------------
 | ||||||
| // this is a map of the registered_guis that can be accessed by name
 | // this is a map of the registered_guis that can be accessed by name
 | ||||||
| std::map<std::string, gui_definition> registered_guis_byName_map; | std::map<std::string, gui_definition> registered_guis_byName_map; | ||||||
| // This is the list of the guis that we want to be available when swiping. Need not to be all the guis that have been registered, can be only a subset.
 |  | ||||||
| // You can swipe through these guis. Will be in the order you place them here in the vector.
 |  | ||||||
| std::vector<std::string> list_of_guis_to_be_shown; |  | ||||||
| 
 | 
 | ||||||
| // ------------------------------------------------------------------------------------
 | // ------------------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|  | @ -29,8 +27,8 @@ void register_gui(std::string a_name, create_tab_content a_create_tab_content, n | ||||||
|   // 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; | ||||||
| 
 | 
 | ||||||
|   // By default, put all registered guis in the sequence of guis to be shown
 |   // By default, put all registered guis in the sequence of guis to be shown of the default scene
 | ||||||
|   // Later we will have scene specific sequences of guis
 |   // Can be overwritten by scenes to have their own gui_list.
 | ||||||
|   list_of_guis_to_be_shown.insert(list_of_guis_to_be_shown.end(), {std::string(a_name)}); |   main_gui_list.insert(main_gui_list.end(), {std::string(a_name)}); | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -36,6 +36,5 @@ struct gui_definition { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| extern std::map<std::string, gui_definition> registered_guis_byName_map; | extern std::map<std::string, gui_definition> registered_guis_byName_map; | ||||||
| extern std::vector<std::string> list_of_guis_to_be_shown; |  | ||||||
| 
 | 
 | ||||||
| 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); | ||||||
|  |  | ||||||
|  | @ -1,7 +1,5 @@ | ||||||
| #include <string> | #include <string> | ||||||
| #include "devices/misc/device_specialCommands.h" |  | ||||||
| #include "applicationInternal/scenes/sceneRegistry.h" | #include "applicationInternal/scenes/sceneRegistry.h" | ||||||
| #include "applicationInternal/scenes/sceneHandler.h" |  | ||||||
| #include "applicationInternal/commandHandler.h" | #include "applicationInternal/commandHandler.h" | ||||||
| #include "applicationInternal/hardware/hardwarePresenter.h" | #include "applicationInternal/hardware/hardwarePresenter.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,11 +4,30 @@ | ||||||
| #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 "scenes/scene__defaultKeys.h" | ||||||
| 
 | 
 | ||||||
| void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") { | void handleScene(uint16_t command, commandData commandData, std::string additionalPayload = "") { | ||||||
| 
 | 
 | ||||||
|  |   // FORCE can be either as second payload in commandData
 | ||||||
|  |   // e.g. register_command(&SCENE_TV_FORCE  , makeCommandData(SCENE, {scene_name_TV, "FORCE"}));
 | ||||||
|  |   // or as additionalPayload, used by gui_sceneSelection.cpp
 | ||||||
|  |   // e.g. executeCommand(activate_scene_command, "FORCE");
 | ||||||
|  | 
 | ||||||
|   auto current = commandData.commandPayloads.begin(); |   auto current = commandData.commandPayloads.begin(); | ||||||
|   std::string scene_name = *current; |   std::string scene_name = *current; | ||||||
|  |   // we can have a second payload
 | ||||||
|  |   std::string isForcePayload = ""; | ||||||
|  |   ++current; | ||||||
|  |   if (current != commandData.commandPayloads.end()) { | ||||||
|  |     isForcePayload = *current; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // do not really switch scene, but show sceneSelection gui. From that on, we are in the main_gui_list.
 | ||||||
|  |   if (scene_name == scene_name_selection) { | ||||||
|  |     useSceneGUIlist = false; | ||||||
|  |     guis_doAfterSliding(-1, -1, true); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   // check if we know the new scene
 |   // check if we know the new scene
 | ||||||
|   if (!sceneExists(scene_name)) { |   if (!sceneExists(scene_name)) { | ||||||
|  | @ -18,30 +37,49 @@ void handleScene(uint16_t command, commandData commandData, std::string addition | ||||||
|     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", get_currentScene().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)
 | ||||||
|  |   bool callEndAndStartSequences; | ||||||
|  |   if ((scene_name == get_currentScene()) && ((isForcePayload != "FORCE") && (additionalPayload != "FORCE"))) { | ||||||
|  |     Serial.printf("scene: will not start scene again, because it is already active\r\n"); | ||||||
|  |     callEndAndStartSequences = false; | ||||||
|  |   } else if ((scene_name == get_currentScene()) && ((isForcePayload == "FORCE") || (additionalPayload == "FORCE"))) { | ||||||
|  |     Serial.printf("scene: scene is already active, but FORCE was set, so start scene again\r\n"); | ||||||
|  |     callEndAndStartSequences = true; | ||||||
|  |   } else { | ||||||
|  |     // this is the default when switching to a different scene
 | ||||||
|  |     callEndAndStartSequences = true; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, "changing...");} |   if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, "changing...");} | ||||||
|   gui_loop(); |   gui_loop(); | ||||||
| 
 | 
 | ||||||
|   // end old scene
 |   if (callEndAndStartSequences) { | ||||||
|   if (!sceneExists(get_currentScene()) && (get_currentScene() != "")) { |     // end old scene
 | ||||||
|     Serial.printf("scene: WARNING: cannot end scene %s, because it is unknown\r\n", get_currentScene().c_str()); |     if (!sceneExists(get_currentScene()) && (get_currentScene() != "")) { | ||||||
|  |       Serial.printf("scene: WARNING: cannot end scene %s, because it is unknown\r\n", get_currentScene().c_str()); | ||||||
|  |    | ||||||
|  |     } else { | ||||||
|  |       if (get_currentScene() != "") { | ||||||
|  |         Serial.printf("scene: will call end sequence for scene %s\r\n", get_currentScene().c_str()); | ||||||
|  |         scene_end_sequence_from_registry(get_currentScene()); | ||||||
|  |       } | ||||||
|    |    | ||||||
|   } else { |  | ||||||
|     if (get_currentScene() != "") { |  | ||||||
|       Serial.printf("scene: will call end sequence for scene %s\r\n", get_currentScene().c_str()); |  | ||||||
|       scene_end_sequence_from_registry(get_currentScene()); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // start new scene
 | ||||||
|  |     Serial.printf("scene: will call start sequence for scene %s\r\n", scene_name.c_str()); | ||||||
|  |     scene_start_sequence_from_registry(scene_name); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // start new scene
 |  | ||||||
|   Serial.printf("scene: will call start sequence for scene %s\r\n", scene_name.c_str()); |  | ||||||
|   scene_start_sequence_from_registry(scene_name); |  | ||||||
| 
 |  | ||||||
|   set_currentScene(scene_name); |   set_currentScene(scene_name); | ||||||
| 
 | 
 | ||||||
|   if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, get_currentScene().c_str());} |   if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, get_currentScene().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", get_currentScene().c_str()); | ||||||
|  | 
 | ||||||
|  |   useSceneGUIlist = true; | ||||||
|  |   // recreate the gui based on the current scene
 | ||||||
|  |   guis_doAfterSliding(-1, -1, true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void setLabelCurrentScene() { | void setLabelCurrentScene() { | ||||||
|  |  | ||||||
|  | @ -1,11 +1,16 @@ | ||||||
| #include <map> | #include <map> | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include "devices/misc/device_specialCommands.h" | #include "applicationInternal/commandHandler.h" | ||||||
| #include "applicationInternal/scenes/sceneRegistry.h" | #include "applicationInternal/scenes/sceneRegistry.h" | ||||||
| #include "applicationInternal/hardware/hardwarePresenter.h" | #include "applicationInternal/hardware/hardwarePresenter.h" | ||||||
| // scenes
 | // scenes
 | ||||||
| #include "scenes/scene__defaultKeys.h" | #include "scenes/scene__defaultKeys.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
 | // https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work
 | ||||||
| struct scene_definition { | struct scene_definition { | ||||||
|   scene_setKeys this_scene_setKeys; |   scene_setKeys this_scene_setKeys; | ||||||
|  | @ -14,9 +19,12 @@ struct scene_definition { | ||||||
|   key_repeatModes this_key_repeatModes; |   key_repeatModes this_key_repeatModes; | ||||||
|   key_commands_short this_key_commands_short; |   key_commands_short this_key_commands_short; | ||||||
|   key_commands_long this_key_commands_long; |   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; | ||||||
| 
 | 
 | ||||||
| void register_scene( | void register_scene( | ||||||
|   std::string a_scene_name, |   std::string a_scene_name, | ||||||
|  | @ -25,17 +33,27 @@ void register_scene( | ||||||
|   scene_end_sequence a_scene_end_sequence, |   scene_end_sequence a_scene_end_sequence, | ||||||
|   key_repeatModes a_key_repeatModes, |   key_repeatModes a_key_repeatModes, | ||||||
|   key_commands_short a_key_commands_short, |   key_commands_short a_key_commands_short, | ||||||
|   key_commands_long a_key_commands_long) { |   key_commands_long a_key_commands_long, | ||||||
|  |   gui_list a_gui_list, | ||||||
|  |   uint16_t a_activate_scene_command) { | ||||||
| 
 | 
 | ||||||
|  |   // put the scene_definition in a map that can be accessed by name
 | ||||||
|   registered_scenes[a_scene_name] = scene_definition{ |   registered_scenes[a_scene_name] = scene_definition{ | ||||||
|     a_scene_setKeys, |     a_scene_setKeys, | ||||||
|     a_scene_start_sequence, |     a_scene_start_sequence, | ||||||
|     a_scene_end_sequence, |     a_scene_end_sequence, | ||||||
|     a_key_repeatModes, |     a_key_repeatModes, | ||||||
|     a_key_commands_short, |     a_key_commands_short, | ||||||
|     a_key_commands_long |     a_key_commands_long, | ||||||
|  |     a_gui_list, | ||||||
|  |     a_activate_scene_command | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   // Additionally, put all registered scenes in a sequence of scenes to be shown in the sceneSelection gui.
 | ||||||
|  |   // Exactly in the order they have been registered.
 | ||||||
|  |   // Can be overwritten in main.cpp
 | ||||||
|  |   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()).
 |   // Whenever a new scene is registered, normally a new scene command has been defined immediately before (e.g. see register_scene_TV()).
 | ||||||
|   // 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.
 |   // 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.
 |   // So we have to set the keys again for all scenes that have been registered before.
 | ||||||
|  | @ -98,17 +116,17 @@ 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 current scene has a definition for it
 | ||||||
|     if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_short->count(keyChar) > 0)) { |     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); | ||||||
|      |      | ||||||
|     // look if there is a default definition
 |     // look if there is a default definition
 | ||||||
|     } else if (key_commands_short_default.count(keyChar) > 0) { |     } else if (key_commands_short_default.count(keyChar) > 0) { | ||||||
|       Serial.printf("get_command_short: will use default key\r\n"); |       // Serial.printf("get_command_short: will use default key\r\n");
 | ||||||
|       return key_commands_short_default.at(keyChar); |       return key_commands_short_default.at(keyChar); | ||||||
|      |      | ||||||
|     // no key definition found
 |     // no key definition found
 | ||||||
|     } else { |     } else { | ||||||
|       Serial.printf("get_command_short: WARNING no key definition found\r\n"); |       // Serial.printf("get_command_short: WARNING no key definition found\r\n");
 | ||||||
|       return COMMAND_UNKNOWN; |       return COMMAND_UNKNOWN; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -123,17 +141,17 @@ 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 current scene has a definition for it
 | ||||||
|     if ((registered_scenes.count(sceneName) > 0) && (registered_scenes.at(sceneName).this_key_commands_long->count(keyChar) > 0)) { |     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); | ||||||
|      |      | ||||||
|     // look if there is a default definition
 |     // look if there is a default definition
 | ||||||
|     } else if (key_commands_long_default.count(keyChar) > 0) { |     } else if (key_commands_long_default.count(keyChar) > 0) { | ||||||
|       Serial.printf("get_command_long: will use default key\r\n"); |       // Serial.printf("get_command_long: will use default key\r\n");
 | ||||||
|       return key_commands_long_default.at(keyChar); |       return key_commands_long_default.at(keyChar); | ||||||
|      |      | ||||||
|     // no key definition found
 |     // no key definition found
 | ||||||
|     } else { |     } else { | ||||||
|       Serial.printf("get_command_long: WARNING no key definition found\r\n"); |       // Serial.printf("get_command_long: WARNING no key definition found\r\n");
 | ||||||
|       return COMMAND_UNKNOWN; |       return COMMAND_UNKNOWN; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -144,6 +162,71 @@ uint16_t get_command_long(std::string sceneName, char keyChar) { | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | gui_list get_gui_list(std::string sceneName) { | ||||||
|  |   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).
 | ||||||
|  |     //   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.
 | ||||||
|  | 
 | ||||||
|  |     #if (USE_SCENE_SPECIFIC_GUI_LIST != 0) | ||||||
|  |     // 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; | ||||||
|  |      | ||||||
|  |     } | ||||||
|  |     #else | ||||||
|  |     // never use scene specific gui list
 | ||||||
|  |     return &main_gui_list; | ||||||
|  |     #endif | ||||||
|  |   } | ||||||
|  |   catch (const std::out_of_range& oor) { | ||||||
|  |     Serial.printf("get_gui_list: internal error, sceneName not registered\r\n"); | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t get_activate_scene_command(std::string sceneName) { | ||||||
|  |   try { | ||||||
|  |     // look if the current scene is known
 | ||||||
|  |     if ((registered_scenes.count(sceneName) > 0)) { | ||||||
|  |       // Serial.printf("get_activate_scene_command: will use activate_scene_command from scene %s\r\n", sceneName.c_str());
 | ||||||
|  |       return registered_scenes.at(sceneName).this_activate_scene_command; | ||||||
|  |      | ||||||
|  |     // if the scene is not know, simply return 0
 | ||||||
|  |     } else { | ||||||
|  |       // Serial.printf("get_activate_scene_command: will return 0\r\n");
 | ||||||
|  |       return 0; | ||||||
|  |      | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   catch (const std::out_of_range& oor) { | ||||||
|  |     Serial.printf("get_activate_scene_command: internal error, sceneName not registered\r\n"); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | scene_list get_scenes_on_sceneSelectionGUI() { | ||||||
|  |   return &scenes_on_sceneSelectionGUI; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void set_scenes_on_sceneSelectionGUI(t_scene_list a_scene_list) { | ||||||
|  |   scenes_on_sceneSelectionGUI.clear(); | ||||||
|  |   for (int i=0; i<a_scene_list.size(); i++) { | ||||||
|  |     scenes_on_sceneSelectionGUI.insert(scenes_on_sceneSelectionGUI.end(), a_scene_list.at(i)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| char KEY_OFF    = 'o'; | char KEY_OFF    = 'o'; | ||||||
| char KEY_STOP   = '='; | char KEY_STOP   = '='; | ||||||
| char KEY_REWI   = '<'; | char KEY_REWI   = '<'; | ||||||
|  |  | ||||||
|  | @ -3,14 +3,22 @@ | ||||||
| #include <string> | #include <string> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <map> | #include <map> | ||||||
|  | #include <vector> | ||||||
| #include "applicationInternal/keys.h" | #include "applicationInternal/keys.h" | ||||||
| 
 | 
 | ||||||
|  | extern bool useSceneGUIlist; | ||||||
|  | 
 | ||||||
|  | typedef std::vector<std::string> t_gui_list; | ||||||
|  | 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, repeatModes> *key_repeatModes; | ||||||
| typedef std::map<char, uint16_t> *key_commands_short; | typedef std::map<char, uint16_t> *key_commands_short; | ||||||
| typedef std::map<char, uint16_t> *key_commands_long; | typedef std::map<char, uint16_t> *key_commands_long; | ||||||
|  | typedef t_gui_list *gui_list; | ||||||
|  | typedef t_scene_list *scene_list; | ||||||
| 
 | 
 | ||||||
| void register_scene( | void register_scene( | ||||||
|   std::string a_scene_name, |   std::string a_scene_name, | ||||||
|  | @ -19,7 +27,9 @@ void register_scene( | ||||||
|   scene_end_sequence a_scene_end_sequence, |   scene_end_sequence a_scene_end_sequence, | ||||||
|   key_repeatModes a_key_repeatModes, |   key_repeatModes a_key_repeatModes, | ||||||
|   key_commands_short a_key_commands_short, |   key_commands_short a_key_commands_short, | ||||||
|   key_commands_long a_key_commands_long); |   key_commands_long a_key_commands_long, | ||||||
|  |   gui_list a_gui_list = NULL, | ||||||
|  |   uint16_t a_activate_scene_command = 0); | ||||||
| 
 | 
 | ||||||
| bool sceneExists(std::string sceneName); | bool sceneExists(std::string sceneName); | ||||||
| void scene_start_sequence_from_registry(std::string sceneName); | void scene_start_sequence_from_registry(std::string sceneName); | ||||||
|  | @ -27,6 +37,10 @@ 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); | ||||||
|  | uint16_t get_activate_scene_command(std::string sceneName); | ||||||
|  | scene_list get_scenes_on_sceneSelectionGUI(); | ||||||
|  | void set_scenes_on_sceneSelectionGUI(t_scene_list a_scene_list); | ||||||
| 
 | 
 | ||||||
| extern char KEY_OFF  ; | extern char KEY_OFF  ; | ||||||
| extern char KEY_STOP ; | extern char KEY_STOP ; | ||||||
|  |  | ||||||
|  | @ -57,7 +57,7 @@ uint16_t SAMSUNG_POWER_OFF       ; //"Samsung_power_off"; | ||||||
| uint16_t SAMSUNG_POWER_ON        ; //"Samsung_power_on";
 | uint16_t SAMSUNG_POWER_ON        ; //"Samsung_power_on";
 | ||||||
| uint16_t SAMSUNG_INPUT_HDMI_1    ; //"Samsung_input_hdmi_1";
 | uint16_t SAMSUNG_INPUT_HDMI_1    ; //"Samsung_input_hdmi_1";
 | ||||||
| uint16_t SAMSUNG_INPUT_HDMI_2    ; //"Samsung_input_hdmi_2";
 | uint16_t SAMSUNG_INPUT_HDMI_2    ; //"Samsung_input_hdmi_2";
 | ||||||
| // uint16_t SAMSUNG_INPUT_HDMI_3    ; //"Samsung_input_hdmi_3";
 | uint16_t SAMSUNG_INPUT_HDMI_3    ; //"Samsung_input_hdmi_3";
 | ||||||
| // uint16_t SAMSUNG_INPUT_HDMI_4    ; //"Samsung_input_hdmi_4";
 | // uint16_t SAMSUNG_INPUT_HDMI_4    ; //"Samsung_input_hdmi_4";
 | ||||||
| // uint16_t SAMSUNG_INPUT_COMPONENT ; //"Samsung_input_component";
 | // uint16_t SAMSUNG_INPUT_COMPONENT ; //"Samsung_input_component";
 | ||||||
| uint16_t SAMSUNG_INPUT_TV        ; //"Samsung_input_tv";
 | uint16_t SAMSUNG_INPUT_TV        ; //"Samsung_input_tv";
 | ||||||
|  | @ -121,7 +121,7 @@ void register_device_samsungTV() { | ||||||
|   register_command(&SAMSUNG_POWER_ON          , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E09966"})); |   register_command(&SAMSUNG_POWER_ON          , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E09966"})); | ||||||
|   register_command(&SAMSUNG_INPUT_HDMI_1      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E09768"})); |   register_command(&SAMSUNG_INPUT_HDMI_1      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E09768"})); | ||||||
|   register_command(&SAMSUNG_INPUT_HDMI_2      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E07D82"})); |   register_command(&SAMSUNG_INPUT_HDMI_2      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E07D82"})); | ||||||
|   // register_command(&SAMSUNG_INPUT_HDMI_3      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E043BC"}));
 |   register_command(&SAMSUNG_INPUT_HDMI_3      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E043BC"})); | ||||||
|   // register_command(&SAMSUNG_INPUT_HDMI_4      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E0A35C"}));
 |   // register_command(&SAMSUNG_INPUT_HDMI_4      , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E0A35C"}));
 | ||||||
|   // register_command(&SAMSUNG_INPUT_COMPONENT   , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E0619E"}));
 |   // register_command(&SAMSUNG_INPUT_COMPONENT   , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E0619E"}));
 | ||||||
|   register_command(&SAMSUNG_INPUT_TV          , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E0D827"})); |   register_command(&SAMSUNG_INPUT_TV          , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E0D827"})); | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ extern uint16_t SAMSUNG_POWER_OFF; | ||||||
| extern uint16_t SAMSUNG_POWER_ON; | extern uint16_t SAMSUNG_POWER_ON; | ||||||
| extern uint16_t SAMSUNG_INPUT_HDMI_1; | extern uint16_t SAMSUNG_INPUT_HDMI_1; | ||||||
| extern uint16_t SAMSUNG_INPUT_HDMI_2; | extern uint16_t SAMSUNG_INPUT_HDMI_2; | ||||||
| // extern uint16_t SAMSUNG_INPUT_HDMI_3;
 | extern uint16_t SAMSUNG_INPUT_HDMI_3; | ||||||
| // extern uint16_t SAMSUNG_INPUT_HDMI_4;
 | // extern uint16_t SAMSUNG_INPUT_HDMI_4;
 | ||||||
| // extern uint16_t SAMSUNG_INPUT_COMPONENT;
 | // extern uint16_t SAMSUNG_INPUT_COMPONENT;
 | ||||||
| extern uint16_t SAMSUNG_INPUT_TV; | extern uint16_t SAMSUNG_INPUT_TV; | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ static void smartHomeToggle_event_cb(lv_event_t* e){ | ||||||
| 
 | 
 | ||||||
| // Smart Home Slider Event handler
 | // Smart Home Slider Event handler
 | ||||||
| static void smartHomeSlider_event_cb(lv_event_t* e){ | static void smartHomeSlider_event_cb(lv_event_t* e){ | ||||||
|   lv_obj_t * slider = lv_event_get_target(e); |   lv_obj_t* slider = lv_event_get_target(e); | ||||||
|   char payload[8]; |   char payload[8]; | ||||||
|   sprintf(payload, "%.2f", float(lv_slider_get_value(slider))); |   sprintf(payload, "%.2f", float(lv_slider_get_value(slider))); | ||||||
|   std::string payload_str(payload); |   std::string payload_str(payload); | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| #include "applicationInternal/commandHandler.h" | #include "applicationInternal/commandHandler.h" | ||||||
| #include "device_specialCommands.h" | #include "device_specialCommands.h" | ||||||
| 
 | 
 | ||||||
| uint16_t COMMAND_UNKNOWN   ; |  | ||||||
| uint16_t MY_SPECIAL_COMMAND; //"My_special_command";
 | uint16_t MY_SPECIAL_COMMAND; //"My_special_command";
 | ||||||
| // uint16_t TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES;
 | // uint16_t TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES;
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| extern uint16_t COMMAND_UNKNOWN; |  | ||||||
| extern uint16_t MY_SPECIAL_COMMAND; | extern uint16_t MY_SPECIAL_COMMAND; | ||||||
| // extern uint16_t TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES;
 | // extern uint16_t TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES;
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										130
									
								
								Platformio/src/guis/gui_sceneSelection.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								Platformio/src/guis/gui_sceneSelection.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,130 @@ | ||||||
|  | #include <lvgl.h> | ||||||
|  | #include "applicationInternal/hardware/hardwarePresenter.h" | ||||||
|  | #include "applicationInternal/gui/guiBase.h" | ||||||
|  | #include "applicationInternal/gui/guiRegistry.h" | ||||||
|  | #include "applicationInternal/scenes/sceneRegistry.h" | ||||||
|  | #include "applicationInternal/commandHandler.h" | ||||||
|  | #include "guis/gui_sceneSelection.h" | ||||||
|  | 
 | ||||||
|  | static uint16_t activate_scene_command; | ||||||
|  | static bool doForceScene; | ||||||
|  | //void activate_scene_async(void *command) {
 | ||||||
|  | //  executeCommand(activate_scene_command);
 | ||||||
|  | //}
 | ||||||
|  | void activate_scene_cb(lv_timer_t *timer) { | ||||||
|  |   uint16_t scene_command_including_force = (uintptr_t)(timer->user_data); | ||||||
|  |   // get the force flag from the highest bit
 | ||||||
|  |   uint16_t activate_scene_command = scene_command_including_force & 0x7FFF; | ||||||
|  |   bool doForceScene = (scene_command_including_force & 0x8000) == 0x8000; | ||||||
|  |   if (doForceScene) { | ||||||
|  |     executeCommand(activate_scene_command, "FORCE"); | ||||||
|  |   } else { | ||||||
|  |     executeCommand(activate_scene_command); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int lastShortClickedReceived; | ||||||
|  | static unsigned long int lastShortClickedReceivedTime; | ||||||
|  | 
 | ||||||
|  | static void sceneSelection_event_cb(lv_event_t* e) { | ||||||
|  | 
 | ||||||
|  |   int user_data = (intptr_t)(e->user_data); | ||||||
|  | 
 | ||||||
|  |   // we will receive the following events in that order:
 | ||||||
|  |   // LV_EVENT_PRESSED
 | ||||||
|  |   // LV_EVENT_RELEASED
 | ||||||
|  |   // only on short press: LV_EVENT_SHORT_CLICKED
 | ||||||
|  |   // both on short press and long press: LV_EVENT_CLICKED
 | ||||||
|  |   // if (lv_event_get_code(e) == LV_EVENT_PRESSED) {
 | ||||||
|  |   //   Serial.println("pressed");
 | ||||||
|  |   // }
 | ||||||
|  |   // if (lv_event_get_code(e) == LV_EVENT_RELEASED) {
 | ||||||
|  |   //   Serial.println("released");
 | ||||||
|  |   // }
 | ||||||
|  |   if (lv_event_get_code(e) == LV_EVENT_SHORT_CLICKED) { | ||||||
|  |     lastShortClickedReceived = user_data; | ||||||
|  |     lastShortClickedReceivedTime = millis();  | ||||||
|  |     // Serial.println("short clicked, will see what happens next");
 | ||||||
|  |     return; | ||||||
|  | 
 | ||||||
|  |   } else if (lv_event_get_code(e) == LV_EVENT_CLICKED) { | ||||||
|  |     if ((lastShortClickedReceived == user_data) && (millis() - lastShortClickedReceivedTime < 10)) { | ||||||
|  |       // Serial.println("clicked, will send short click");
 | ||||||
|  |       doForceScene = false; | ||||||
|  |     } else { | ||||||
|  |       // Serial.println("clicked, will send long click");
 | ||||||
|  |       doForceScene = true; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   std::string scene_name = get_scenes_on_sceneSelectionGUI()->at(user_data); | ||||||
|  | 
 | ||||||
|  |   activate_scene_command = get_activate_scene_command(scene_name); | ||||||
|  |   if (activate_scene_command != 0) { | ||||||
|  |     // this line is needed
 | ||||||
|  |     if (SceneLabel != NULL) {lv_label_set_text(SceneLabel, "changing...");} | ||||||
|  |     // Problem: screen will not get updated and show "changing..." if "executeCommand(activate_scene_command);" is called here
 | ||||||
|  |     // test 1 (does not work): call lv_timer_handler();
 | ||||||
|  |     // lv_timer_handler();
 | ||||||
|  |     // test 2 (does not work): async_call
 | ||||||
|  |     // lv_async_call(activate_scene_async, &activate_scene_command);
 | ||||||
|  |     // test 3: lv_timer_create()
 | ||||||
|  |     // needs to run only once, and a very short period of 5 ms to wait until first run is enough
 | ||||||
|  |      | ||||||
|  |     uint16_t scene_command_including_force; | ||||||
|  |     if (doForceScene) { | ||||||
|  |       // put the force flag into the highest bit
 | ||||||
|  |       scene_command_including_force = activate_scene_command | 0x8000; | ||||||
|  |       Serial.printf("Scene with index %d and name %s was FORCE selected\r\n", user_data, scene_name.c_str()); | ||||||
|  |     } else { | ||||||
|  |       scene_command_including_force = activate_scene_command; | ||||||
|  |       Serial.printf("Scene with index %d and name %s was selected\r\n", user_data, scene_name.c_str()); | ||||||
|  |     } | ||||||
|  |     lv_timer_t *my_timer = lv_timer_create(activate_scene_cb, 20, (void *)(uintptr_t) scene_command_including_force); | ||||||
|  |     lv_timer_set_repeat_count(my_timer, 1); | ||||||
|  | 
 | ||||||
|  |   } else { | ||||||
|  |     Serial.printf("Cannot activate scene %s, because command was not found\r\n", scene_name.c_str()); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void create_tab_content_sceneSelection(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 each scene ----------------------------------------
 | ||||||
|  |   scene_list scenes = get_scenes_on_sceneSelectionGUI(); | ||||||
|  |   if ((scenes != NULL) && (scenes->size() > 0)) { | ||||||
|  |     for (int i=0; i<scenes->size(); i++) { | ||||||
|  |       lv_obj_t* button = lv_btn_create(tab); | ||||||
|  |       lv_obj_set_size(button, lv_pct(100), 42); | ||||||
|  |       lv_obj_set_style_radius(button, 30, LV_PART_MAIN); | ||||||
|  |       lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN); | ||||||
|  |       lv_obj_add_event_cb(button, sceneSelection_event_cb, LV_EVENT_CLICKED,       (void *)(intptr_t)i); | ||||||
|  |       lv_obj_add_event_cb(button, sceneSelection_event_cb, LV_EVENT_SHORT_CLICKED, (void *)(intptr_t)i); | ||||||
|  |       //lv_obj_add_event_cb(button, sceneSelection_event_cb, LV_EVENT_PRESSED,       (void *)(intptr_t)i);
 | ||||||
|  |       //lv_obj_add_event_cb(button, sceneSelection_event_cb, LV_EVENT_RELEASED,      (void *)(intptr_t)i);
 | ||||||
|  |    | ||||||
|  |       lv_obj_t* label = lv_label_create(button); | ||||||
|  |       lv_label_set_text(label, scenes->at(i).c_str()); | ||||||
|  |       lv_obj_center(label); | ||||||
|  |       } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void notify_tab_before_delete_sceneSelection(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_sceneSelection(void){ | ||||||
|  |   register_gui(std::string(tabName_sceneSelection), & create_tab_content_sceneSelection, & notify_tab_before_delete_sceneSelection); | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								Platformio/src/guis/gui_sceneSelection.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Platformio/src/guis/gui_sceneSelection.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <lvgl.h> | ||||||
|  | 
 | ||||||
|  | const char * const tabName_sceneSelection = "Scene selection"; | ||||||
|  | void register_gui_sceneSelection(void); | ||||||
|  | @ -15,7 +15,7 @@ lv_obj_t* objBattSettingsPercentage; | ||||||
| 
 | 
 | ||||||
| // Slider Event handler
 | // Slider Event handler
 | ||||||
| static void bl_slider_event_cb(lv_event_t* e){ | static void bl_slider_event_cb(lv_event_t* e){ | ||||||
|   lv_obj_t * slider = lv_event_get_target(e); |   lv_obj_t* slider = lv_event_get_target(e); | ||||||
|   int32_t slider_value = lv_slider_get_value(slider); |   int32_t slider_value = lv_slider_get_value(slider); | ||||||
|   if (slider_value < 60)  {slider_value = 60;} |   if (slider_value < 60)  {slider_value = 60;} | ||||||
|   if (slider_value > 255) {slider_value = 255;} |   if (slider_value > 255) {slider_value = 255;} | ||||||
|  | @ -29,7 +29,7 @@ static void WakeEnableSetting_event_cb(lv_event_t* e){ | ||||||
| 
 | 
 | ||||||
| // timout event handler
 | // timout event handler
 | ||||||
| static void timout_event_cb(lv_event_t* e){ | static void timout_event_cb(lv_event_t* e){ | ||||||
|   lv_obj_t * drop = lv_event_get_target(e); |   lv_obj_t* drop = lv_event_get_target(e); | ||||||
|   uint16_t selected = lv_dropdown_get_selected(drop); |   uint16_t selected = lv_dropdown_get_selected(drop); | ||||||
|   switch (selected) { |   switch (selected) { | ||||||
|     case 0: {set_sleepTimeout(  10000); break;} |     case 0: {set_sleepTimeout(  10000); break;} | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
| // register gui and keys
 | // register gui and keys
 | ||||||
| #include "applicationInternal/gui/guiBase.h" | #include "applicationInternal/gui/guiBase.h" | ||||||
| #include "applicationInternal/gui/guiRegistry.h" | #include "applicationInternal/gui/guiRegistry.h" | ||||||
|  | #include "guis/gui_sceneSelection.h" | ||||||
| #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" | ||||||
|  | @ -29,6 +30,7 @@ | ||||||
| #include "scenes/scene_TV.h" | #include "scenes/scene_TV.h" | ||||||
| #include "scenes/scene_fireTV.h" | #include "scenes/scene_fireTV.h" | ||||||
| #include "scenes/scene_chromecast.h" | #include "scenes/scene_chromecast.h" | ||||||
|  | #include "scenes/scene_appleTV.h" | ||||||
| #include "applicationInternal/scenes/sceneHandler.h" | #include "applicationInternal/scenes/sceneHandler.h" | ||||||
| 
 | 
 | ||||||
| #if defined(ARDUINO) | #if defined(ARDUINO) | ||||||
|  | @ -79,26 +81,35 @@ int main(int argc, char *argv[]) { | ||||||
|   #endif |   #endif | ||||||
|   register_keyboardCommands(); |   register_keyboardCommands(); | ||||||
| 
 | 
 | ||||||
|  |   // register the scenes and their key_commands_*
 | ||||||
|  |   register_scene_defaultKeys(); | ||||||
|  |   register_scene_TV(); | ||||||
|  |   register_scene_fireTV(); | ||||||
|  |   register_scene_chromecast(); | ||||||
|  |   register_scene_appleTV(); | ||||||
|  |   register_scene_allOff(); | ||||||
|  |   // Only show these scenes on the sceneSelection gui. If you don't set this explicitely, by default all registered scenes are shown.
 | ||||||
|  |   set_scenes_on_sceneSelectionGUI({scene_name_TV, scene_name_fireTV, scene_name_chromecast, scene_name_appleTV}); | ||||||
|  | 
 | ||||||
|   // register the GUIs. They will be displayed in the order they have been registered.
 |   // register the GUIs. They will be displayed in the order they have been registered.
 | ||||||
|  |   register_gui_sceneSelection(); | ||||||
|   register_gui_irReceiver(); |   register_gui_irReceiver(); | ||||||
|   register_gui_settings(); |   register_gui_settings(); | ||||||
|   register_gui_appleTV(); |   register_gui_appleTV(); | ||||||
|   register_gui_numpad(); |   register_gui_numpad(); | ||||||
|   register_gui_smarthome(); |   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(); | ||||||
|   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
 | ||||||
|   init_IMU(); |   init_IMU(); | ||||||
| 
 | 
 | ||||||
|   // register the scenes and their key_commands_*
 |  | ||||||
|   register_scene_defaultKeys(); |  | ||||||
|   register_scene_allOff(); |  | ||||||
|   register_scene_TV(); |  | ||||||
|   register_scene_fireTV(); |  | ||||||
|   register_scene_chromecast(); |  | ||||||
|   setLabelCurrentScene(); |  | ||||||
| 
 |  | ||||||
|   // init WiFi - needs to be after init_gui() because WifiLabel must be available
 |   // init WiFi - needs to be after init_gui() because WifiLabel must be available
 | ||||||
|   #if (ENABLE_WIFI_AND_MQTT == 1) |   #if (ENABLE_WIFI_AND_MQTT == 1) | ||||||
|   init_mqtt(); |   init_mqtt(); | ||||||
|  |  | ||||||
|  | @ -7,8 +7,11 @@ | ||||||
| #include "devices/TV/device_samsungTV/device_samsungTV.h" | #include "devices/TV/device_samsungTV/device_samsungTV.h" | ||||||
| #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | ||||||
| #include "applicationInternal/commandHandler.h" | #include "applicationInternal/commandHandler.h" | ||||||
|  | // guis
 | ||||||
|  | #include "guis/gui_numpad.h" | ||||||
| 
 | 
 | ||||||
| uint16_t SCENE_TV          ; //"Scene_tv"
 | uint16_t SCENE_TV         ; //"Scene_tv"
 | ||||||
|  | uint16_t SCENE_TV_FORCE   ; //"Scene_tv_force"
 | ||||||
| 
 | 
 | ||||||
| std::map<char, repeatModes> key_repeatModes_TV; | std::map<char, repeatModes> key_repeatModes_TV; | ||||||
| std::map<char, uint16_t> key_commands_short_TV; | std::map<char, uint16_t> key_commands_short_TV; | ||||||
|  | @ -64,9 +67,11 @@ void scene_end_sequence_TV(void) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string scene_name_TV = "TV"; | std::string scene_name_TV = "TV"; | ||||||
|  | t_gui_list scene_TV_gui_list = {tabName_numpad}; | ||||||
| 
 | 
 | ||||||
| void register_scene_TV(void) { | void register_scene_TV(void) { | ||||||
|   register_command(&SCENE_TV         , makeCommandData(SCENE, {scene_name_TV})); |   register_command(&SCENE_TV,       makeCommandData(SCENE, {scene_name_TV})); | ||||||
|  |   register_command(&SCENE_TV_FORCE, makeCommandData(SCENE, {scene_name_TV, "FORCE"})); | ||||||
| 
 | 
 | ||||||
|   register_scene( |   register_scene( | ||||||
|     scene_name_TV, |     scene_name_TV, | ||||||
|  | @ -75,5 +80,7 @@ void register_scene_TV(void) { | ||||||
|     & scene_end_sequence_TV, |     & scene_end_sequence_TV, | ||||||
|     & key_repeatModes_TV, |     & key_repeatModes_TV, | ||||||
|     & key_commands_short_TV, |     & key_commands_short_TV, | ||||||
|     & key_commands_long_TV); |     & key_commands_long_TV, | ||||||
|  |     & scene_TV_gui_list, | ||||||
|  |     SCENE_TV); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| extern uint16_t SCENE_TV; | extern uint16_t SCENE_TV; | ||||||
|  | // FORCE sends the start sequence again even if scene is already active
 | ||||||
|  | extern uint16_t SCENE_TV_FORCE; | ||||||
| 
 | 
 | ||||||
| extern std::string scene_name_TV; | extern std::string scene_name_TV; | ||||||
| void register_scene_TV_commands(void); | void register_scene_TV_commands(void); | ||||||
|  |  | ||||||
|  | @ -1,19 +1,30 @@ | ||||||
| #include <map> | #include <map> | ||||||
| #include "applicationInternal/keys.h" | #include "applicationInternal/keys.h" | ||||||
| #include "applicationInternal/scenes/sceneRegistry.h" | #include "applicationInternal/scenes/sceneRegistry.h" | ||||||
|  | #include "applicationInternal/commandHandler.h" | ||||||
| // devices
 | // devices
 | ||||||
| #include "devices/misc/device_specialCommands.h" |  | ||||||
| #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | ||||||
| // scenes
 | // scenes
 | ||||||
|  | #include "scene__defaultKeys.h" | ||||||
| #include "scenes/scene_allOff.h" | #include "scenes/scene_allOff.h" | ||||||
| #include "scenes/scene_TV.h" | #include "scenes/scene_TV.h" | ||||||
| #include "scenes/scene_fireTV.h" | #include "scenes/scene_fireTV.h" | ||||||
| #include "scenes/scene_chromecast.h" | #include "scenes/scene_chromecast.h" | ||||||
|  | #include "scenes/scene_appleTV.h" | ||||||
|  | 
 | ||||||
|  | uint16_t SCENE_SELECTION; | ||||||
|  | std::string scene_name_selection = "sceneSelection"; | ||||||
| 
 | 
 | ||||||
| std::map<char, repeatModes> key_repeatModes_default; | std::map<char, repeatModes> key_repeatModes_default; | ||||||
| std::map<char, uint16_t> key_commands_short_default; | std::map<char, uint16_t> key_commands_short_default; | ||||||
| std::map<char, uint16_t> key_commands_long_default; | std::map<char, uint16_t> key_commands_long_default; | ||||||
| 
 | 
 | ||||||
|  | // This is the main list of guis we want to be shown when swiping. Need not to be all the guis that have been registered, can be only a subset.
 | ||||||
|  | // You can swipe through these guis. Will be in the order you place them here in the vector.
 | ||||||
|  | // By default, it is a list of the guis that have been registered in main.cpp
 | ||||||
|  | // If a scene defines a scene specific gui list, this will be used instead as long as the scene is active and we don't explicitely navigate back to main_gui_list
 | ||||||
|  | t_gui_list main_gui_list; | ||||||
|  | 
 | ||||||
| void register_scene_defaultKeys(void) { | void register_scene_defaultKeys(void) { | ||||||
|   key_repeatModes_default = { |   key_repeatModes_default = { | ||||||
|                                                                                                              {KEY_OFF,   SHORT            }, |                                                                                                              {KEY_OFF,   SHORT            }, | ||||||
|  | @ -29,16 +40,16 @@ void register_scene_defaultKeys(void) { | ||||||
|   }; |   }; | ||||||
|    |    | ||||||
|   key_commands_short_default = { |   key_commands_short_default = { | ||||||
|                                                                                                              {KEY_OFF,   SCENE_ALLOFF     }, |                                                                                                              {KEY_OFF,   SCENE_ALLOFF_FORCE}, | ||||||
|   /*{KEY_STOP,  COMMAND_UNKNOWN  },    {KEY_REWI,  COMMAND_UNKNOWN  },    {KEY_PLAY,  COMMAND_UNKNOWN  },    {KEY_FORW,  COMMAND_UNKNOWN  },*/ |   /*{KEY_STOP,  COMMAND_UNKNOWN  },    {KEY_REWI,  COMMAND_UNKNOWN  },    {KEY_PLAY,  COMMAND_UNKNOWN  },    {KEY_FORW,  COMMAND_UNKNOWN  },*/ | ||||||
|   /*{KEY_CONF,  COMMAND_UNKNOWN  },                                                                          {KEY_INFO,  COMMAND_UNKNOWN  },*/ |   /*{KEY_CONF,  COMMAND_UNKNOWN  },                                                                          {KEY_INFO,  COMMAND_UNKNOWN  },*/ | ||||||
|                                                      /*  {KEY_UP,    COMMAND_UNKNOWN  },*/ |                                                      /*  {KEY_UP,    COMMAND_UNKNOWN  },*/ | ||||||
|                    /* {KEY_LEFT,  COMMAND_UNKNOWN  },    {KEY_OK,    COMMAND_UNKNOWN  },    {KEY_RIGHT, COMMAND_UNKNOWN  },*/ |                    /* {KEY_LEFT,  COMMAND_UNKNOWN  },    {KEY_OK,    COMMAND_UNKNOWN  },    {KEY_RIGHT, COMMAND_UNKNOWN  },*/ | ||||||
|                                                      /*  {KEY_DOWN,  COMMAND_UNKNOWN  },*/ |                                                      /*  {KEY_DOWN,  COMMAND_UNKNOWN  },*/ | ||||||
|   /*{KEY_BACK,  COMMAND_UNKNOWN  },                                                                          {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,   COMMAND_UNKNOWN  },*/                 /*{KEY_CHDOW, COMMAND_UNKNOWN  },*/ | ||||||
|     {KEY_RED,   SCENE_TV         },    {KEY_GREEN, SCENE_FIRETV     },    {KEY_YELLO, SCENE_CHROMECAST },    {KEY_BLUE,  YAMAHA_STANDARD  }, |     {KEY_RED,   SCENE_TV_FORCE   },    {KEY_GREEN, SCENE_FIRETV_FORCE},  {KEY_YELLO, SCENE_CHROMECAST_FORCE},{KEY_BLUE,  SCENE_APPLETV_FORCE}, | ||||||
|   }; |   }; | ||||||
|    |    | ||||||
|   key_commands_long_default = { |   key_commands_long_default = { | ||||||
|  | @ -46,4 +57,6 @@ void register_scene_defaultKeys(void) { | ||||||
|    |    | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   register_command(&SCENE_SELECTION     , makeCommandData(SCENE, {scene_name_selection})); | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,8 +4,15 @@ | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <map> | #include <map> | ||||||
| #include "applicationInternal/keys.h" | #include "applicationInternal/keys.h" | ||||||
|  | #include "applicationInternal/scenes/sceneRegistry.h" | ||||||
|  | 
 | ||||||
|  | extern uint16_t SCENE_SELECTION;          // command
 | ||||||
|  | extern std::string scene_name_selection;  // name of this fake default scene
 | ||||||
| 
 | 
 | ||||||
| extern std::map<char, repeatModes> key_repeatModes_default; | extern std::map<char, repeatModes> key_repeatModes_default; | ||||||
| extern std::map<char, uint16_t> key_commands_short_default; | extern std::map<char, uint16_t> key_commands_short_default; | ||||||
| extern std::map<char, uint16_t> key_commands_long_default; | extern std::map<char, uint16_t> key_commands_long_default; | ||||||
|  | 
 | ||||||
|  | extern t_gui_list main_gui_list; | ||||||
|  | 
 | ||||||
| void register_scene_defaultKeys(void); | void register_scene_defaultKeys(void); | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #include "applicationInternal/commandHandler.h" | #include "applicationInternal/commandHandler.h" | ||||||
| 
 | 
 | ||||||
| uint16_t SCENE_ALLOFF      ; //"Scene_allOff"
 | uint16_t SCENE_ALLOFF      ; //"Scene_allOff"
 | ||||||
|  | uint16_t SCENE_ALLOFF_FORCE; //"Scene_allOff_force"
 | ||||||
| 
 | 
 | ||||||
| std::map<char, repeatModes> key_repeatModes_allOff; | std::map<char, repeatModes> key_repeatModes_allOff; | ||||||
| std::map<char, uint16_t> key_commands_short_allOff; | std::map<char, uint16_t> key_commands_short_allOff; | ||||||
|  | @ -77,7 +78,8 @@ void scene_end_sequence_allOff(void) { | ||||||
| std::string scene_name_allOff = "Off"; | std::string scene_name_allOff = "Off"; | ||||||
| 
 | 
 | ||||||
| void register_scene_allOff(void) { | void register_scene_allOff(void) { | ||||||
|   register_command(&SCENE_ALLOFF     , makeCommandData(SCENE, {scene_name_allOff})); |   register_command(&SCENE_ALLOFF      , makeCommandData(SCENE, {scene_name_allOff})); | ||||||
|  |   register_command(&SCENE_ALLOFF_FORCE, makeCommandData(SCENE, {scene_name_allOff, "FORCE"})); | ||||||
| 
 | 
 | ||||||
|   register_scene( |   register_scene( | ||||||
|     scene_name_allOff, |     scene_name_allOff, | ||||||
|  | @ -86,5 +88,7 @@ void register_scene_allOff(void) { | ||||||
|     & scene_end_sequence_allOff, |     & scene_end_sequence_allOff, | ||||||
|     & key_repeatModes_allOff, |     & key_repeatModes_allOff, | ||||||
|     & key_commands_short_allOff, |     & key_commands_short_allOff, | ||||||
|     & key_commands_long_allOff); |     & key_commands_long_allOff, | ||||||
|  |     NULL, | ||||||
|  |     SCENE_ALLOFF); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| extern uint16_t SCENE_ALLOFF; | extern uint16_t SCENE_ALLOFF; | ||||||
|  | // FORCE sends the start sequence again even if scene is already active
 | ||||||
|  | extern uint16_t SCENE_ALLOFF_FORCE; | ||||||
| 
 | 
 | ||||||
| extern std::string scene_name_allOff; | extern std::string scene_name_allOff; | ||||||
| void register_scene_allOff_commands(void); | void register_scene_allOff_commands(void); | ||||||
|  |  | ||||||
							
								
								
									
										86
									
								
								Platformio/src/scenes/scene_appleTV.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Platformio/src/scenes/scene_appleTV.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | ||||||
|  | #include <map> | ||||||
|  | #include "scenes/scene_appleTV.h" | ||||||
|  | #include "applicationInternal/keys.h" | ||||||
|  | #include "applicationInternal/scenes/sceneRegistry.h" | ||||||
|  | #include "applicationInternal/hardware/hardwarePresenter.h" | ||||||
|  | // devices
 | ||||||
|  | #include "devices/TV/device_samsungTV/device_samsungTV.h" | ||||||
|  | #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | ||||||
|  | #include "applicationInternal/commandHandler.h" | ||||||
|  | // guis
 | ||||||
|  | #include "devices/mediaPlayer/device_appleTV/gui_appleTV.h" | ||||||
|  | 
 | ||||||
|  | uint16_t SCENE_APPLETV      ; //"Scene_appleTV"
 | ||||||
|  | uint16_t SCENE_APPLETV_FORCE; //"Scene_appleTV_force"
 | ||||||
|  | 
 | ||||||
|  | std::map<char, repeatModes> key_repeatModes_appleTV; | ||||||
|  | std::map<char, uint16_t> key_commands_short_appleTV; | ||||||
|  | std::map<char, uint16_t> key_commands_long_appleTV; | ||||||
|  | 
 | ||||||
|  | void scene_setKeys_appleTV() { | ||||||
|  |   key_repeatModes_appleTV = { | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   }; | ||||||
|  |    | ||||||
|  |   key_commands_short_appleTV = { | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   }; | ||||||
|  |    | ||||||
|  |   key_commands_long_appleTV = { | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void scene_start_sequence_appleTV(void) { | ||||||
|  |   executeCommand(SAMSUNG_POWER_ON); | ||||||
|  |   delay(500); | ||||||
|  |   executeCommand(YAMAHA_POWER_ON); | ||||||
|  |   delay(1500); | ||||||
|  |   executeCommand(YAMAHA_INPUT_DVD); | ||||||
|  |   delay(3000); | ||||||
|  |   executeCommand(SAMSUNG_INPUT_HDMI_3); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void scene_end_sequence_appleTV(void) { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string scene_name_appleTV = "Apple TV"; | ||||||
|  | t_gui_list scene_appleTV_gui_list = {tabName_appleTV}; | ||||||
|  | 
 | ||||||
|  | void register_scene_appleTV(void) { | ||||||
|  |   register_command(&SCENE_APPLETV,       makeCommandData(SCENE, {scene_name_appleTV})); | ||||||
|  |   register_command(&SCENE_APPLETV_FORCE, makeCommandData(SCENE, {scene_name_appleTV, "FORCE"})); | ||||||
|  | 
 | ||||||
|  |   register_scene( | ||||||
|  |     scene_name_appleTV, | ||||||
|  |     & scene_setKeys_appleTV, | ||||||
|  |     & scene_start_sequence_appleTV, | ||||||
|  |     & scene_end_sequence_appleTV, | ||||||
|  |     & key_repeatModes_appleTV, | ||||||
|  |     & key_commands_short_appleTV, | ||||||
|  |     & key_commands_long_appleTV, | ||||||
|  |     & scene_appleTV_gui_list, | ||||||
|  |     SCENE_APPLETV); | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								Platformio/src/scenes/scene_appleTV.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Platformio/src/scenes/scene_appleTV.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <string> | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | extern uint16_t SCENE_APPLETV; | ||||||
|  | // FORCE sends the start sequence again even if scene is already active
 | ||||||
|  | extern uint16_t SCENE_APPLETV_FORCE; | ||||||
|  | 
 | ||||||
|  | extern std::string scene_name_appleTV; | ||||||
|  | void register_scene_appleTV_commands(void); | ||||||
|  | void register_scene_appleTV(void); | ||||||
|  | @ -8,7 +8,8 @@ | ||||||
| #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | ||||||
| #include "applicationInternal/commandHandler.h" | #include "applicationInternal/commandHandler.h" | ||||||
| 
 | 
 | ||||||
| uint16_t SCENE_CHROMECAST  ; //"Scene_chromecast"
 | uint16_t SCENE_CHROMECAST      ; //"Scene_chromecast"
 | ||||||
|  | uint16_t SCENE_CHROMECAST_FORCE; //"Scene_chromecast_force"
 | ||||||
| 
 | 
 | ||||||
| std::map<char, repeatModes> key_repeatModes_chromecast; | std::map<char, repeatModes> key_repeatModes_chromecast; | ||||||
| std::map<char, uint16_t> key_commands_short_chromecast; | std::map<char, uint16_t> key_commands_short_chromecast; | ||||||
|  | @ -66,7 +67,8 @@ void scene_end_sequence_chromecast(void) { | ||||||
| std::string scene_name_chromecast = "Chromecast"; | std::string scene_name_chromecast = "Chromecast"; | ||||||
| 
 | 
 | ||||||
| void register_scene_chromecast(void) { | void register_scene_chromecast(void) { | ||||||
|   register_command(&SCENE_CHROMECAST , makeCommandData(SCENE, {scene_name_chromecast})); |   register_command(&SCENE_CHROMECAST,       makeCommandData(SCENE, {scene_name_chromecast})); | ||||||
|  |   register_command(&SCENE_CHROMECAST_FORCE, makeCommandData(SCENE, {scene_name_chromecast, "FORCE"})); | ||||||
| 
 | 
 | ||||||
|   register_scene( |   register_scene( | ||||||
|     scene_name_chromecast, |     scene_name_chromecast, | ||||||
|  | @ -75,5 +77,7 @@ void register_scene_chromecast(void) { | ||||||
|     & scene_end_sequence_chromecast, |     & scene_end_sequence_chromecast, | ||||||
|     & key_repeatModes_chromecast, |     & key_repeatModes_chromecast, | ||||||
|     & key_commands_short_chromecast, |     & key_commands_short_chromecast, | ||||||
|     & key_commands_long_chromecast); |     & key_commands_long_chromecast, | ||||||
|  |     NULL, | ||||||
|  |     SCENE_CHROMECAST); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| extern uint16_t SCENE_CHROMECAST; | extern uint16_t SCENE_CHROMECAST; | ||||||
|  | // FORCE sends the start sequence again even if scene is already active
 | ||||||
|  | extern uint16_t SCENE_CHROMECAST_FORCE; | ||||||
| 
 | 
 | ||||||
| extern std::string scene_name_chromecast; | extern std::string scene_name_chromecast; | ||||||
| void register_scene_chromecast_commands(void); | void register_scene_chromecast_commands(void); | ||||||
|  |  | ||||||
|  | @ -7,8 +7,11 @@ | ||||||
| #include "devices/TV/device_samsungTV/device_samsungTV.h" | #include "devices/TV/device_samsungTV/device_samsungTV.h" | ||||||
| #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | #include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h" | ||||||
| #include "applicationInternal/commandHandler.h" | #include "applicationInternal/commandHandler.h" | ||||||
|  | // guis
 | ||||||
|  | #include "guis/gui_numpad.h" | ||||||
| 
 | 
 | ||||||
| uint16_t SCENE_FIRETV      ; //"Scene_firetv"
 | uint16_t SCENE_FIRETV      ; //"Scene_firetv"
 | ||||||
|  | uint16_t SCENE_FIRETV_FORCE; //"Scene_firetv_force"
 | ||||||
| 
 | 
 | ||||||
| std::map<char, repeatModes> key_repeatModes_fireTV; | std::map<char, repeatModes> key_repeatModes_fireTV; | ||||||
| std::map<char, uint16_t> key_commands_short_fireTV; | std::map<char, uint16_t> key_commands_short_fireTV; | ||||||
|  | @ -73,9 +76,11 @@ void scene_end_sequence_fireTV(void) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string scene_name_fireTV = "Fire TV"; | std::string scene_name_fireTV = "Fire TV"; | ||||||
|  | t_gui_list scene_fireTV_gui_list = {tabName_numpad}; | ||||||
| 
 | 
 | ||||||
| void register_scene_fireTV(void) { | void register_scene_fireTV(void) { | ||||||
|   register_command(&SCENE_FIRETV     , makeCommandData(SCENE, {scene_name_fireTV})); |   register_command(&SCENE_FIRETV,       makeCommandData(SCENE, {scene_name_fireTV})); | ||||||
|  |   register_command(&SCENE_FIRETV_FORCE, makeCommandData(SCENE, {scene_name_fireTV, "FORCE"})); | ||||||
| 
 | 
 | ||||||
|   register_scene( |   register_scene( | ||||||
|     scene_name_fireTV, |     scene_name_fireTV, | ||||||
|  | @ -84,5 +89,7 @@ void register_scene_fireTV(void) { | ||||||
|     & scene_end_sequence_fireTV, |     & scene_end_sequence_fireTV, | ||||||
|     & key_repeatModes_fireTV, |     & key_repeatModes_fireTV, | ||||||
|     & key_commands_short_fireTV, |     & key_commands_short_fireTV, | ||||||
|     & key_commands_long_fireTV); |     & key_commands_long_fireTV, | ||||||
|  |     & scene_fireTV_gui_list, | ||||||
|  |     SCENE_FIRETV); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| extern uint16_t SCENE_FIRETV; | extern uint16_t SCENE_FIRETV; | ||||||
|  | // FORCE sends the start sequence again even if scene is already active
 | ||||||
|  | extern uint16_t SCENE_FIRETV_FORCE; | ||||||
| 
 | 
 | ||||||
| extern std::string scene_name_fireTV; | extern std::string scene_name_fireTV; | ||||||
| void register_scene_fireTV_commands(void); | void register_scene_fireTV_commands(void); | ||||||
|  |  | ||||||
|  | @ -74,9 +74,8 @@ The [housing and buttons](https://github.com/CoretechR/OMOTE/tree/main/CAD) can | ||||||
| 
 | 
 | ||||||
| Short term goals | Short term goals | ||||||
| - [x] simulator for creating pages in Windows, WSL2 and Linux | - [x] simulator for creating pages in Windows, WSL2 and Linux | ||||||
| - [ ] scene selector page as start page | - [x] scene selector page as start page | ||||||
| - [ ] available gui pages based on the currently active scene. Hide pages not needed in a scene | - [x] available gui pages based on the currently active scene. Hide pages not needed in a scene | ||||||
| - [ ] make gui actions context sensitive for the currently active scene |  | ||||||
| 
 | 
 | ||||||
| Long term goals (not yet scheduled) | Long term goals (not yet scheduled) | ||||||
| - [ ] Easier configuration | - [ ] Easier configuration | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue