gui for scene selection
This commit is contained in:
parent
4568d0338e
commit
4488b1e589
36 changed files with 684 additions and 123 deletions
|
@ -9,13 +9,22 @@ void save_preferences_HAL(void) {
|
|||
}
|
||||
|
||||
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) {
|
||||
currentScene = aCurrentScene;
|
||||
}
|
||||
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) {
|
||||
currentGUIname = aCurrentGUIname;
|
||||
|
|
|
@ -23,6 +23,7 @@ build_flags =
|
|||
-D ENABLE_KEYBOARD_MQTT=0
|
||||
-D ENABLE_BLUETOOTH=1
|
||||
-D ENABLE_KEYBOARD_BLE=1
|
||||
-D USE_SCENE_SPECIFIC_GUI_LIST=1
|
||||
-D SCR_WIDTH=${env.custom_screen_width}
|
||||
-D SCR_HEIGHT=${env.custom_screen_heigth}
|
||||
;-- lvgl ------------------------------------------------------------------
|
||||
|
@ -68,6 +69,10 @@ build_flags =
|
|||
; lvgl variant 2:
|
||||
; or define where lv_conf.h is, relative to the `lvgl` folder
|
||||
;-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]
|
||||
platform = espressif32
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
// show received IR and MQTT messages
|
||||
#include "guis/gui_irReceiver.h"
|
||||
|
||||
uint16_t COMMAND_UNKNOWN;
|
||||
|
||||
uint16_t KEYBOARD_DUMMY_UP ; //"Keyboard_dummy_up"
|
||||
uint16_t KEYBOARD_DUMMY_DOWN ; //"Keyboard_dummy_down"
|
||||
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_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.
|
||||
These defines are used in keys.cpp, gui*.cpp and commandHandler.cpp
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||
#include "applicationInternal/memoryUsage.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_obj_t* MemoryUsageLabel = NULL;
|
||||
|
@ -26,10 +29,26 @@ lv_style_t style_red_border;
|
|||
#endif
|
||||
|
||||
void guis_doTabCreationAtStartup();
|
||||
void guis_doAfterSliding(int oldTabID, int newTabID);
|
||||
void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList);
|
||||
|
||||
// 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
|
||||
// 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){
|
||||
|
@ -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();
|
||||
// calling lv_timer_handler(); here does not help
|
||||
// lv_timer_handler();
|
||||
// guis_doAfterSliding(oldTabID, currentTabID);
|
||||
// guis_doAfterSliding(oldTabID, currentTabID, false);
|
||||
|
||||
waitBeforeActionAfterSlidingAnimationEnded = true;
|
||||
waitBeforeActionAfterSlidingAnimationEnded_timerStart = millis();
|
||||
|
@ -77,7 +96,7 @@ void tabview_tab_changed_event_cb(lv_event_t* e) {
|
|||
oldTabID = currentTabID;
|
||||
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
|
||||
lv_obj_t* myTabview = lv_event_get_target(e);
|
||||
lv_obj_t* tabContainer = lv_tabview_get_content(myTabview);
|
||||
|
@ -91,7 +110,7 @@ void tabview_tab_changed_event_cb(lv_event_t* e) {
|
|||
} else {
|
||||
// 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.");
|
||||
guis_doAfterSliding(oldTabID, currentTabID);
|
||||
guis_doAfterSliding(oldTabID, currentTabID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +150,10 @@ void init_gui(void) {
|
|||
init_gui_memoryUsage_bar();
|
||||
// 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;
|
||||
|
@ -205,6 +228,7 @@ void init_gui_memoryUsage_bar() {
|
|||
void init_gui_status_bar() {
|
||||
// Create a status bar at the top -------------------------------------------------------------------------
|
||||
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_style_shadow_width(statusbar, 0, 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_obj_align(SceneLabel, LV_ALIGN_TOP_MID, 0, labelsPositionTopStatusbar);
|
||||
lv_obj_set_style_text_font(SceneLabel, &lv_font_montserrat_12, LV_PART_MAIN);
|
||||
lv_obj_add_flag(SceneLabel, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_add_event_cb(SceneLabel, sceneLabel_or_pageIndicator_event_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
// Battery ----------------------------------------------------------------------
|
||||
BattPercentageLabel = lv_label_create(statusbar);
|
||||
lv_label_set_text(BattPercentageLabel, "");
|
||||
|
@ -251,12 +278,12 @@ void gui_loop(void) {
|
|||
waitBeforeActionAfterSlidingAnimationEnded = false;
|
||||
} else if (waitOneLoop) {
|
||||
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.
|
||||
// if (waitBeforeActionAfterSlidingAnimationEnded) {
|
||||
// if (millis() - waitBeforeActionAfterSlidingAnimationEnded_timerStart >= 5) {
|
||||
// guis_doAfterSliding(oldTabID, currentTabID);
|
||||
// guis_doAfterSliding(oldTabID, currentTabID, false);
|
||||
// waitBeforeActionAfterSlidingAnimationEnded = false;
|
||||
// }
|
||||
// }
|
||||
|
@ -267,11 +294,13 @@ void gui_loop(void) {
|
|||
void guis_doTabCreationAtStartup() {
|
||||
gui_memoryOptimizer_prepare_startup();
|
||||
|
||||
guis_doAfterSliding(-1, -1);
|
||||
guis_doAfterSliding(-1, -1, false);
|
||||
}
|
||||
|
||||
void guis_doAfterSliding(int oldTabID, int newTabID) {
|
||||
gui_memoryOptimizer_doAfterSliding_deletionAndCreation(&tabview, oldTabID, newTabID, &panel, &img1, &img2);
|
||||
void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList) {
|
||||
// With parameter newGuiList it is signaled that we are changing from a scene specific list to the main list or vice versa
|
||||
// In that case, we have to do special treatment because we are not simply sliding to the left or to the right, but we start newly with a different gui list.
|
||||
gui_memoryOptimizer_doAfterSliding_deletionAndCreation(&tabview, oldTabID, newTabID, newGuiList, &panel, &img1, &img2);
|
||||
|
||||
doLogMemoryUsage();
|
||||
}
|
||||
|
|
|
@ -30,8 +30,11 @@ void gui_loop(void);
|
|||
// used by guiMemoryOptimizer.cpp
|
||||
void tabview_content_is_scrolling_event_cb(lv_event_t* e);
|
||||
void tabview_tab_changed_event_cb(lv_event_t* e);
|
||||
void sceneLabel_or_pageIndicator_event_cb(lv_event_t* e);
|
||||
void setActiveTab(uint32_t index, lv_anim_enable_t anim_en);
|
||||
// used by memoryUsage.cpp
|
||||
void showMemoryUsageBar(bool showBar);
|
||||
// used by commandHandler to show WiFi status
|
||||
void showWiFiConnected(bool connected);
|
||||
|
||||
void guis_doAfterSliding(int oldTabID, int newTabID, bool newGuiList);
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
#include <lvgl.h>
|
||||
#include "applicationInternal/gui/guiBase.h"
|
||||
#include "applicationInternal/gui/guiRegistry.h"
|
||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||
|
||||
struct tab_in_memory {
|
||||
lv_obj_t* tab;
|
||||
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};
|
||||
|
||||
void notify_active_tabs_before_delete() {
|
||||
|
@ -19,7 +22,9 @@ void notify_active_tabs_before_delete() {
|
|||
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 == "") {
|
||||
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) {
|
||||
|
@ -42,9 +47,9 @@ void clear_tabview(lv_obj_t* tabview) {
|
|||
}
|
||||
|
||||
// set struct tabs_in_memory to NULL
|
||||
tabs_in_memory[0] = {NULL, -1};
|
||||
tabs_in_memory[1] = {NULL, -1};
|
||||
tabs_in_memory[2] = {NULL, -1};
|
||||
tabs_in_memory[0] = {NULL, -1, ""};
|
||||
tabs_in_memory[1] = {NULL, -1, ""};
|
||||
tabs_in_memory[2] = {NULL, -1, ""};
|
||||
|
||||
}
|
||||
|
||||
|
@ -79,7 +84,8 @@ lv_obj_t* create_tabview() {
|
|||
lv_obj_t* create_panel() {
|
||||
// Create a page indicator at the bottom ------------------------------------------------------------------
|
||||
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_flex_flow(panel, LV_FLEX_FLOW_ROW);
|
||||
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) {
|
||||
if (index == -1) {
|
||||
return "";
|
||||
} else if (index <= list_of_guis_to_be_shown.size() -1) {
|
||||
return list_of_guis_to_be_shown.at(index);
|
||||
} else if (index <= get_gui_list(get_currentScene())->size() -1) {
|
||||
return get_gui_list(get_currentScene())->at(index);
|
||||
} else {
|
||||
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());
|
||||
} else {
|
||||
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
|
||||
tabs_in_memory[tabs_in_memory_index].tab = lv_tabview_add_tab(tabview, nameOfTab.c_str());
|
||||
// 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) {
|
||||
// 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
|
||||
0 1 -1 0 <- first state, special case - also the initial state
|
||||
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)) {
|
||||
// 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)) {
|
||||
// In gui_memoryOptimizer_prepare_startup, the index of get_currentGUIname() in list_of_guis_to_be_shown was saved, if found.
|
||||
if ((tabs_in_memory_previous_listIndex[0] < get_gui_list(get_currentScene())->size()) && (tabs_in_memory_previous_listIndex[0] != -1)) {
|
||||
// In gui_memoryOptimizer_prepare_startup, the index of get_currentGUIname() in gui_list was saved, if found.
|
||||
// We can resume at this old state.
|
||||
oldListIndex = tabs_in_memory_previous_listIndex[0] ;
|
||||
if (oldListIndex == 0) {
|
||||
|
@ -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");
|
||||
tabs_in_memory[0] = {NULL, 0};
|
||||
// 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};
|
||||
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
|
||||
Serial.printf(" Startup: will resume where we went to sleep with \"last state\"\r\n");
|
||||
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;
|
||||
}
|
||||
} 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
|
||||
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
|
||||
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};
|
||||
tabToBeActivated = 0;
|
||||
}
|
||||
|
@ -193,7 +201,7 @@ void doTabCreation_strategyMax3(lv_obj_t* tabview, uint32_t oldTabID, uint32_t n
|
|||
} else {
|
||||
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"
|
||||
tabs_in_memory[0] = {NULL, oldListIndex};
|
||||
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);
|
||||
}
|
||||
|
||||
if (list_of_guis_to_be_shown.size() > 0) {
|
||||
std::string nameOfNewActiveTab = list_of_guis_to_be_shown.at(tabs_in_memory[tabToBeActivated].listIndex);
|
||||
if (get_gui_list(get_currentScene())->size() > 0) {
|
||||
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());
|
||||
|
||||
// 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(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) {
|
||||
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");
|
||||
// at least add the style
|
||||
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)
|
||||
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:
|
||||
example: list_of_guis_to_be_shown: 0 1 2 3 4
|
||||
example: gui_list: 0 1 2 3 4
|
||||
in memory color active
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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
|
||||
std::string nameOfTab;
|
||||
uint8_t breadcrumpPosition;
|
||||
for (int i=0; i<3; i++) {
|
||||
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_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_t* label = lv_label_create(btn);
|
||||
lv_label_set_text_fmt(label, "%s", nameOfTab.c_str());
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_remove_style(btn, NULL, LV_STATE_PRESSED);
|
||||
lv_obj_set_style_shadow_width(btn, 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN);
|
||||
|
||||
// create a breadcrump dot for each gui in the list
|
||||
for (int j=0; j<breadcrumpLength; j++) {
|
||||
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);
|
||||
lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_size(btn, 150, lv_pct(100));
|
||||
// 4 at last position 4 at middle position only one tab available overall
|
||||
if ((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)) {
|
||||
// 4 at last position 4 at middle position only one tab available overall
|
||||
if ((tabs_in_memory[2].listIndex == get_gui_list(get_currentScene())->size()-1) || (tabs_in_memory[1].listIndex == get_gui_list(get_currentScene())->size()-1) || (tabs_in_memory[1].listIndex == -1)) {
|
||||
lv_obj_set_style_bg_color(btn, lv_color_black(), LV_PART_MAIN);
|
||||
} else {
|
||||
lv_obj_set_style_bg_color(btn, color_primary, LV_PART_MAIN);
|
||||
|
@ -333,40 +388,66 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
|
|||
}
|
||||
|
||||
void gui_memoryOptimizer_prepare_startup() {
|
||||
// find index of get_currentGUIname() in list_of_guis_to_be_shown
|
||||
for (int i=0; i<list_of_guis_to_be_shown.size(); i++) {
|
||||
if (list_of_guis_to_be_shown[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);
|
||||
// find index of get_currentGUIname() in gui_list
|
||||
for (int i=0; i<get_gui_list(get_currentScene())->size(); i++) {
|
||||
if (get_gui_list(get_currentScene())->at(i) == get_currentGUIname()) {
|
||||
Serial.printf("Startup: found GUI with name \"%s\" in \"gui_list\" at position %d\r\n", get_currentGUIname().c_str(), i);
|
||||
// save position so that "guis_doAfterSliding" can use it
|
||||
tabs_in_memory[0].listIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// if the gui was not found in main_gui_list, try to find it in scene specific list
|
||||
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.
|
||||
// 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.
|
||||
// So we always have 3 tabs.
|
||||
// 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));
|
||||
if (isInitialization) {
|
||||
Serial.printf("Startup: will initially create the tabs to be shown\r\n");
|
||||
} else {
|
||||
Serial.printf("Changing from oldTabID %d \"%s\" to newTabID %d \"%s\"\r\n",
|
||||
oldTabID, list_of_guis_to_be_shown.at(tabs_in_memory[oldTabID].listIndex).c_str(),
|
||||
newTabID, list_of_guis_to_be_shown.at(tabs_in_memory[newTabID].listIndex).c_str());
|
||||
oldTabID, get_gui_list(get_currentScene())->at(tabs_in_memory[oldTabID].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++) {
|
||||
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
|
||||
if (!isInitialization) notify_active_tabs_before_delete();
|
||||
notify_active_tabs_before_delete();
|
||||
// clear current tabview
|
||||
clear_tabview(*tabview);
|
||||
// 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 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
|
||||
// lv_obj_t * newscr = lv_obj_create(NULL);
|
||||
// lv_obj_t* newscr = lv_obj_create(NULL);
|
||||
// // load this new screen
|
||||
// lv_scr_load(newscr);
|
||||
// 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
|
||||
lv_obj_t* newTabview = create_tabview();
|
||||
*tabview = newTabview;
|
||||
|
@ -401,4 +488,6 @@ void gui_memoryOptimizer_doAfterSliding_deletionAndCreation(lv_obj_t** tabview,
|
|||
// Initialize scroll position of the page indicator
|
||||
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
|
||||
|
||||
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 "applicationInternal/gui/guiBase.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
|
||||
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
|
||||
registered_guis_byName_map[a_name] = new_gui_definition;
|
||||
|
||||
// By default, put all registered guis in the sequence of guis to be shown
|
||||
// Later we will have scene specific sequences of guis
|
||||
list_of_guis_to_be_shown.insert(list_of_guis_to_be_shown.end(), {std::string(a_name)});
|
||||
// By default, put all registered guis in the sequence of guis to be shown of the default scene
|
||||
// Can be overwritten by scenes to have their own gui_list.
|
||||
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::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);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <string>
|
||||
#include "devices/misc/device_specialCommands.h"
|
||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||
#include "applicationInternal/scenes/sceneHandler.h"
|
||||
#include "applicationInternal/commandHandler.h"
|
||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||
|
||||
|
|
|
@ -4,11 +4,30 @@
|
|||
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||
#include "applicationInternal/commandHandler.h"
|
||||
#include "scenes/scene__defaultKeys.h"
|
||||
|
||||
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();
|
||||
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
|
||||
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());
|
||||
}
|
||||
|
||||
// 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...");}
|
||||
gui_loop();
|
||||
|
||||
// end old scene
|
||||
if (!sceneExists(get_currentScene()) && (get_currentScene() != "")) {
|
||||
Serial.printf("scene: WARNING: cannot end scene %s, because it is unknown\r\n", get_currentScene().c_str());
|
||||
if (callEndAndStartSequences) {
|
||||
// end old scene
|
||||
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);
|
||||
|
||||
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());
|
||||
|
||||
useSceneGUIlist = true;
|
||||
// recreate the gui based on the current scene
|
||||
guis_doAfterSliding(-1, -1, true);
|
||||
}
|
||||
|
||||
void setLabelCurrentScene() {
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include "devices/misc/device_specialCommands.h"
|
||||
#include "applicationInternal/commandHandler.h"
|
||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||
// scenes
|
||||
#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
|
||||
struct scene_definition {
|
||||
scene_setKeys this_scene_setKeys;
|
||||
|
@ -14,9 +19,12 @@ struct scene_definition {
|
|||
key_repeatModes this_key_repeatModes;
|
||||
key_commands_short this_key_commands_short;
|
||||
key_commands_long this_key_commands_long;
|
||||
gui_list this_gui_list;
|
||||
uint16_t this_activate_scene_command;
|
||||
};
|
||||
|
||||
std::map<std::string, scene_definition> registered_scenes;
|
||||
t_scene_list scenes_on_sceneSelectionGUI;
|
||||
|
||||
void register_scene(
|
||||
std::string a_scene_name,
|
||||
|
@ -25,17 +33,27 @@ void register_scene(
|
|||
scene_end_sequence a_scene_end_sequence,
|
||||
key_repeatModes a_key_repeatModes,
|
||||
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{
|
||||
a_scene_setKeys,
|
||||
a_scene_start_sequence,
|
||||
a_scene_end_sequence,
|
||||
a_key_repeatModes,
|
||||
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()).
|
||||
// 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.
|
||||
|
@ -98,17 +116,17 @@ uint16_t get_command_short(std::string sceneName, char keyChar) {
|
|||
try {
|
||||
// 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)) {
|
||||
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);
|
||||
|
||||
// look if there is a default definition
|
||||
} 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);
|
||||
|
||||
// no key definition found
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
@ -123,17 +141,17 @@ uint16_t get_command_long(std::string sceneName, char keyChar) {
|
|||
try {
|
||||
// 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)) {
|
||||
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);
|
||||
|
||||
// look if there is a default definition
|
||||
} 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);
|
||||
|
||||
// no key definition found
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
@ -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_STOP = '=';
|
||||
char KEY_REWI = '<';
|
||||
|
|
|
@ -3,14 +3,22 @@
|
|||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#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_start_sequence)(void);
|
||||
typedef void (*scene_end_sequence)(void);
|
||||
typedef std::map<char, repeatModes> *key_repeatModes;
|
||||
typedef std::map<char, uint16_t> *key_commands_short;
|
||||
typedef std::map<char, uint16_t> *key_commands_long;
|
||||
typedef t_gui_list *gui_list;
|
||||
typedef t_scene_list *scene_list;
|
||||
|
||||
void register_scene(
|
||||
std::string a_scene_name,
|
||||
|
@ -19,7 +27,9 @@ void register_scene(
|
|||
scene_end_sequence a_scene_end_sequence,
|
||||
key_repeatModes a_key_repeatModes,
|
||||
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);
|
||||
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);
|
||||
uint16_t get_command_short(std::string sceneName, char keyChar);
|
||||
uint16_t get_command_long(std::string sceneName, char keyChar);
|
||||
gui_list get_gui_list(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_STOP ;
|
||||
|
|
|
@ -57,7 +57,7 @@ uint16_t SAMSUNG_POWER_OFF ; //"Samsung_power_off";
|
|||
uint16_t SAMSUNG_POWER_ON ; //"Samsung_power_on";
|
||||
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_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_COMPONENT ; //"Samsung_input_component";
|
||||
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_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_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_COMPONENT , makeCommandData(IR, {std::to_string(IR_PROTOCOL_SAMSUNG), "0xE0E0619E"}));
|
||||
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_INPUT_HDMI_1;
|
||||
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_COMPONENT;
|
||||
extern uint16_t SAMSUNG_INPUT_TV;
|
||||
|
|
|
@ -35,7 +35,7 @@ static void smartHomeToggle_event_cb(lv_event_t* e){
|
|||
|
||||
// Smart Home Slider Event handler
|
||||
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];
|
||||
sprintf(payload, "%.2f", float(lv_slider_get_value(slider)));
|
||||
std::string payload_str(payload);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "applicationInternal/commandHandler.h"
|
||||
#include "device_specialCommands.h"
|
||||
|
||||
uint16_t COMMAND_UNKNOWN ;
|
||||
uint16_t MY_SPECIAL_COMMAND; //"My_special_command";
|
||||
// uint16_t TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint16_t COMMAND_UNKNOWN;
|
||||
extern uint16_t MY_SPECIAL_COMMAND;
|
||||
// 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
|
||||
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);
|
||||
if (slider_value < 60) {slider_value = 60;}
|
||||
if (slider_value > 255) {slider_value = 255;}
|
||||
|
@ -29,7 +29,7 @@ static void WakeEnableSetting_event_cb(lv_event_t* e){
|
|||
|
||||
// timout event handler
|
||||
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);
|
||||
switch (selected) {
|
||||
case 0: {set_sleepTimeout( 10000); break;}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
// register gui and keys
|
||||
#include "applicationInternal/gui/guiBase.h"
|
||||
#include "applicationInternal/gui/guiRegistry.h"
|
||||
#include "guis/gui_sceneSelection.h"
|
||||
#include "guis/gui_irReceiver.h"
|
||||
#include "guis/gui_settings.h"
|
||||
#include "guis/gui_numpad.h"
|
||||
|
@ -29,6 +30,7 @@
|
|||
#include "scenes/scene_TV.h"
|
||||
#include "scenes/scene_fireTV.h"
|
||||
#include "scenes/scene_chromecast.h"
|
||||
#include "scenes/scene_appleTV.h"
|
||||
#include "applicationInternal/scenes/sceneHandler.h"
|
||||
|
||||
#if defined(ARDUINO)
|
||||
|
@ -79,26 +81,35 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
register_keyboardCommands();
|
||||
|
||||
// register the scenes and their key_commands_*
|
||||
register_scene_defaultKeys();
|
||||
register_scene_TV();
|
||||
register_scene_fireTV();
|
||||
register_scene_chromecast();
|
||||
register_scene_appleTV();
|
||||
register_scene_allOff();
|
||||
// Only show these scenes on the sceneSelection gui. If you don't set this explicitely, by default all registered scenes are shown.
|
||||
set_scenes_on_sceneSelectionGUI({scene_name_TV, scene_name_fireTV, scene_name_chromecast, scene_name_appleTV});
|
||||
|
||||
// register the GUIs. They will be displayed in the order they have been registered.
|
||||
register_gui_sceneSelection();
|
||||
register_gui_irReceiver();
|
||||
register_gui_settings();
|
||||
register_gui_appleTV();
|
||||
register_gui_numpad();
|
||||
register_gui_smarthome();
|
||||
// Only show these GUIs in the main gui list. If you don't set this explicitely, by default all registered guis are shown.
|
||||
#if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
|
||||
main_gui_list = {tabName_sceneSelection, tabName_smarthome, tabName_settings, tabName_irReceiver};
|
||||
#endif
|
||||
// init GUI - will initialize tft, touch and lvgl
|
||||
init_gui();
|
||||
setLabelCurrentScene();
|
||||
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
|
||||
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
|
||||
#if (ENABLE_WIFI_AND_MQTT == 1)
|
||||
init_mqtt();
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
#include "devices/TV/device_samsungTV/device_samsungTV.h"
|
||||
#include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.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, uint16_t> key_commands_short_TV;
|
||||
|
@ -64,9 +67,11 @@ void scene_end_sequence_TV(void) {
|
|||
}
|
||||
|
||||
std::string scene_name_TV = "TV";
|
||||
t_gui_list scene_TV_gui_list = {tabName_numpad};
|
||||
|
||||
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(
|
||||
scene_name_TV,
|
||||
|
@ -75,5 +80,7 @@ void register_scene_TV(void) {
|
|||
& scene_end_sequence_TV,
|
||||
& key_repeatModes_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>
|
||||
|
||||
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;
|
||||
void register_scene_TV_commands(void);
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
#include <map>
|
||||
#include "applicationInternal/keys.h"
|
||||
#include "applicationInternal/scenes/sceneRegistry.h"
|
||||
#include "applicationInternal/commandHandler.h"
|
||||
// devices
|
||||
#include "devices/misc/device_specialCommands.h"
|
||||
#include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h"
|
||||
// scenes
|
||||
#include "scene__defaultKeys.h"
|
||||
#include "scenes/scene_allOff.h"
|
||||
#include "scenes/scene_TV.h"
|
||||
#include "scenes/scene_fireTV.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, uint16_t> key_commands_short_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) {
|
||||
key_repeatModes_default = {
|
||||
{KEY_OFF, SHORT },
|
||||
|
@ -29,16 +40,16 @@ void register_scene_defaultKeys(void) {
|
|||
};
|
||||
|
||||
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_CONF, COMMAND_UNKNOWN }, {KEY_INFO, COMMAND_UNKNOWN },*/
|
||||
/* {KEY_UP, COMMAND_UNKNOWN },*/
|
||||
/* {KEY_LEFT, COMMAND_UNKNOWN }, {KEY_OK, COMMAND_UNKNOWN }, {KEY_RIGHT, 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_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 = {
|
||||
|
@ -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 <map>
|
||||
#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, uint16_t> key_commands_short_default;
|
||||
extern std::map<char, uint16_t> key_commands_long_default;
|
||||
|
||||
extern t_gui_list main_gui_list;
|
||||
|
||||
void register_scene_defaultKeys(void);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "applicationInternal/commandHandler.h"
|
||||
|
||||
uint16_t SCENE_ALLOFF ; //"Scene_allOff"
|
||||
uint16_t SCENE_ALLOFF_FORCE; //"Scene_allOff_force"
|
||||
|
||||
std::map<char, repeatModes> key_repeatModes_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";
|
||||
|
||||
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(
|
||||
scene_name_allOff,
|
||||
|
@ -86,5 +88,7 @@ void register_scene_allOff(void) {
|
|||
& scene_end_sequence_allOff,
|
||||
& key_repeatModes_allOff,
|
||||
& key_commands_short_allOff,
|
||||
& key_commands_long_allOff);
|
||||
& key_commands_long_allOff,
|
||||
NULL,
|
||||
SCENE_ALLOFF);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
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 "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, uint16_t> key_commands_short_chromecast;
|
||||
|
@ -66,7 +67,8 @@ void scene_end_sequence_chromecast(void) {
|
|||
std::string scene_name_chromecast = "Chromecast";
|
||||
|
||||
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(
|
||||
scene_name_chromecast,
|
||||
|
@ -75,5 +77,7 @@ void register_scene_chromecast(void) {
|
|||
& scene_end_sequence_chromecast,
|
||||
& key_repeatModes_chromecast,
|
||||
& key_commands_short_chromecast,
|
||||
& key_commands_long_chromecast);
|
||||
& key_commands_long_chromecast,
|
||||
NULL,
|
||||
SCENE_CHROMECAST);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
void register_scene_chromecast_commands(void);
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
#include "devices/TV/device_samsungTV/device_samsungTV.h"
|
||||
#include "devices/AVreceiver/device_yamahaAmp/device_yamahaAmp.h"
|
||||
#include "applicationInternal/commandHandler.h"
|
||||
// guis
|
||||
#include "guis/gui_numpad.h"
|
||||
|
||||
uint16_t SCENE_FIRETV ; //"Scene_firetv"
|
||||
uint16_t SCENE_FIRETV_FORCE; //"Scene_firetv_force"
|
||||
|
||||
std::map<char, repeatModes> key_repeatModes_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";
|
||||
t_gui_list scene_fireTV_gui_list = {tabName_numpad};
|
||||
|
||||
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(
|
||||
scene_name_fireTV,
|
||||
|
@ -84,5 +89,7 @@ void register_scene_fireTV(void) {
|
|||
& scene_end_sequence_fireTV,
|
||||
& key_repeatModes_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>
|
||||
|
||||
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;
|
||||
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
|
||||
- [x] simulator for creating pages in Windows, WSL2 and Linux
|
||||
- [ ] scene selector page as start page
|
||||
- [ ] 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
|
||||
- [x] scene selector page as start page
|
||||
- [x] available gui pages based on the currently active scene. Hide pages not needed in a scene
|
||||
|
||||
Long term goals (not yet scheduled)
|
||||
- [ ] Easier configuration
|
||||
|
|
Loading…
Reference in a new issue