diff --git a/internal/native/cgo/ctrl.c b/internal/native/cgo/ctrl.c index 787e99bf..93a49872 100644 --- a/internal/native/cgo/ctrl.c +++ b/internal/native/cgo/ctrl.c @@ -18,7 +18,7 @@ jetkvm_video_state_t state; jetkvm_video_state_handler_t *video_state_handler = NULL; - +jetkvm_rpc_handler_t *rpc_handler = NULL; jetkvm_video_handler_t *video_handler = NULL; @@ -34,6 +34,16 @@ void jetkvm_set_indev_handler(jetkvm_indev_handler_t *handler) { lvgl_set_indev_handler(handler); } +void jetkvm_set_rpc_handler(jetkvm_rpc_handler_t *handler) { + rpc_handler = handler; +} + +void jetkvm_call_rpc_handler(const char *method, const char *params) { + if (rpc_handler != NULL) { + (*rpc_handler)(method, params); + } +} + const char *jetkvm_ui_event_code_to_name(int code) { lv_event_code_t cCode = (lv_event_code_t)code; return lv_event_code_get_name(code); diff --git a/internal/native/cgo/ctrl.h b/internal/native/cgo/ctrl.h index 8fca70a9..c23b01af 100644 --- a/internal/native/cgo/ctrl.h +++ b/internal/native/cgo/ctrl.h @@ -16,12 +16,15 @@ typedef struct typedef void (jetkvm_video_state_handler_t)(jetkvm_video_state_t *state); typedef void (jetkvm_log_handler_t)(int level, const char *filename, const char *funcname, int line, const char *message); +typedef void (jetkvm_rpc_handler_t)(const char *method, const char *params); typedef void (jetkvm_video_handler_t)(const uint8_t *frame, ssize_t len); typedef void (jetkvm_indev_handler_t)(int code); void jetkvm_set_log_handler(jetkvm_log_handler_t *handler); void jetkvm_set_video_handler(jetkvm_video_handler_t *handler); void jetkvm_set_indev_handler(jetkvm_indev_handler_t *handler); +void jetkvm_set_rpc_handler(jetkvm_rpc_handler_t *handler); +void jetkvm_call_rpc_handler(const char *method, const char *params); void jetkvm_set_video_state_handler(jetkvm_video_state_handler_t *handler); void jetkvm_ui_set_var(const char *name, const char *value); diff --git a/internal/native/cgo/screen.c b/internal/native/cgo/screen.c index ecef3422..a468a6b3 100644 --- a/internal/native/cgo/screen.c +++ b/internal/native/cgo/screen.c @@ -9,6 +9,7 @@ // #include "st7789/lcd.h" #include "ui/ui.h" #include "ui_index.h" +#include "ctrl.h" #define DISP_BUF_SIZE (300 * 240 * 2) static lv_color_t buf[DISP_BUF_SIZE]; @@ -76,10 +77,9 @@ void lvgl_init(u_int16_t rotation) { ui_init(); + ui_set_rpc_handler((jetkvm_rpc_handler_t *)jetkvm_call_rpc_handler); + log_info("ui initalized"); - // lv_label_set_text(ui_Boot_Screen_Version, ""); - // lv_label_set_text(ui_Home_Content_Ip, "..."); - // lv_label_set_text(ui_Home_Header_Cloud_Status_Label, "0 active"); } void lvgl_tick(void) { diff --git a/internal/native/cgo/video.c b/internal/native/cgo/video.c index 0e67945b..14a5881c 100644 --- a/internal/native/cgo/video.c +++ b/internal/native/cgo/video.c @@ -323,7 +323,7 @@ void *run_video_stream(void *arg) { if (detected_signal == false) { - usleep(100000); + usleep(10000); // Reduced to 10ms for better responsiveness to streaming_flag changes continue; } diff --git a/internal/native/cgo_linux.go b/internal/native/cgo_linux.go index d108690b..5377cc17 100644 --- a/internal/native/cgo_linux.go +++ b/internal/native/cgo_linux.go @@ -37,6 +37,11 @@ extern void jetkvm_go_indev_handler(int code); static inline void jetkvm_cgo_setup_indev_handler() { jetkvm_set_indev_handler(&jetkvm_go_indev_handler); } + +extern void jetkvm_go_rpc_handler(cchar_t *method, cchar_t *params); +static inline void jetkvm_cgo_setup_rpc_handler() { + jetkvm_set_rpc_handler(&jetkvm_go_rpc_handler); +} */ import "C" @@ -75,6 +80,11 @@ func jetkvm_go_indev_handler(code C.int) { indevEventChan <- int(code) } +//export jetkvm_go_rpc_handler +func jetkvm_go_rpc_handler(method *C.cchar_t, params *C.cchar_t) { + rpcEventChan <- C.GoString(method) +} + var eventCodeToNameMap = map[int]string{} func uiEventCodeToName(code int) string { @@ -94,6 +104,7 @@ func setUpNativeHandlers() { C.jetkvm_cgo_setup_video_state_handler() C.jetkvm_cgo_setup_video_handler() C.jetkvm_cgo_setup_indev_handler() + C.jetkvm_cgo_setup_rpc_handler() } func uiInit(rotation uint16) { diff --git a/internal/native/chan.go b/internal/native/chan.go index a730689e..4162f260 100644 --- a/internal/native/chan.go +++ b/internal/native/chan.go @@ -11,6 +11,7 @@ var ( videoStateChan chan VideoState = make(chan VideoState) logChan chan nativeLogMessage = make(chan nativeLogMessage) indevEventChan chan int = make(chan int) + rpcEventChan chan string = make(chan string) ) func (n *Native) handleVideoFrameChan() { @@ -70,3 +71,10 @@ func (n *Native) handleIndevEventChan() { n.onIndevEvent(name) } } + +func (n *Native) handleRpcEventChan() { + for { + event := <-rpcEventChan + n.onRpcEvent(event) + } +} diff --git a/internal/native/eez/jetkvm.eez-project b/internal/native/eez/jetkvm.eez-project index efe179b6..81231dec 100644 --- a/internal/native/eez/jetkvm.eez-project +++ b/internal/native/eez/jetkvm.eez-project @@ -48,7 +48,7 @@ { "objID": "58af3ebb-96b3-494c-f4e3-9c23852e3e42", "fileName": "actions.c", - "template": "#include \"actions.h\"\n#include \"screens.h\"\n\nint handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int screenId) {\n lv_event_code_t event_code = lv_event_get_code(e);\n if (event_code != LV_EVENT_GESTURE) {\n return 0;\n }\n\n if (lv_indev_get_gesture_dir(lv_indev_get_act()) != direction) {\n return 0;\n }\n lv_indev_wait_release(lv_indev_get_act());\n loadScreen(screenId);\n return 1;\n}\n\nvoid action_switch_to_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_switch_to_advanced_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_ADVANCED_SCREEN);\n}\n\nvoid action_switch_to_status(lv_event_t *e) {\n loadScreen(SCREEN_ID_STATUS_SCREEN);\n}\n\nvoid action_switch_to_about(lv_event_t *e) {\n loadScreen(SCREEN_ID_ABOUT_SCREEN);\n}\n\nvoid action_menu_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_HOME_SCREEN);\n}\n\nvoid action_menu_advanced_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_reset_config_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_home_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_LEFT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_about_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nstatic const int RESET_LONG_PRESS_DURATION = 1000 * 20; // 20 seconds\n\nvoid action_reset_config(lv_event_t * e) \n lv_event_code_t event_code = lv_event_get_code(e);\n lv_obj_t *obj = lv_event_get_target(e);\n \n if (event_code == LV_EVENT_PRESSED) {\n // Button pressed - start timing\n reset_press_start_time = lv_tick_get();\n lv_obj_set_user_data(obj, (uint32_t) reset_press_start_time);\n }\n else if (event_code == LV_EVENT_PRESSING) {\n uint32_t reset_press_start_time = (uint32_t) lv_obj_get_user_data(obj);\n if (reset_press_start_time == 0) {\n return;\n }\n\n uint32_t current_time = lv_tick_get();\n if (current_time - reset_press_start_time >= RESET_LONG_PRESS_DURATION) {\n \n lv_obj_add_flag(objects.reset_config_spinner, LV_OBJ_FLAG_HIDDEN);\n }\n }\n}" + "template": "#include \"actions.h\"\n#include \"screens.h\"\n#include \"ui.h\"\n#include \n\nint handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int screenId) {\n lv_event_code_t event_code = lv_event_get_code(e);\n if (event_code != LV_EVENT_GESTURE) {\n return 0;\n }\n\n if (lv_indev_get_gesture_dir(lv_indev_get_act()) != direction) {\n return 0;\n }\n lv_indev_wait_release(lv_indev_get_act());\n loadScreen(screenId);\n return 1;\n}\n\nvoid action_switch_to_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_switch_to_advanced_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_ADVANCED_SCREEN);\n}\n\nvoid action_switch_to_status(lv_event_t *e) {\n loadScreen(SCREEN_ID_STATUS_SCREEN);\n}\n\nvoid action_switch_to_about(lv_event_t *e) {\n loadScreen(SCREEN_ID_ABOUT_SCREEN);\n}\n\nvoid action_switch_to_reset_config(lv_event_t *e) {\n loadScreen(SCREEN_ID_RESET_CONFIG_SCREEN);\n}\n\nvoid action_switch_to_reboot(lv_event_t *e) {\n loadScreen(SCREEN_ID_REBOOT_SCREEN);\n}\n\nvoid action_menu_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_HOME_SCREEN);\n}\n\nvoid action_menu_advanced_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_reset_config_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_home_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_LEFT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_about_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\n// user_data doesn't seem to be working, so we use a global variable here\nstatic uint32_t t_reset_config;\nstatic uint32_t t_reboot;\nconst int RESET_CONFIG_HOLD_TIME = 10;\nconst int REBOOT_HOLD_TIME = 5;\n\nvoid action_reset_config(lv_event_t * e) {\n lv_event_code_t event_code = lv_event_get_code(e);\n lv_obj_t *obj = lv_event_get_target(e);\n \n if (event_code == LV_EVENT_PRESSED) {\n t_reset_config = lv_tick_get();\n }\n else if (event_code == LV_EVENT_PRESSING) {\n int remaining_time = RESET_CONFIG_HOLD_TIME * 1000 - lv_tick_elaps(t_reset_config);\n if (remaining_time <= 0) { \n lv_obj_add_flag(objects.reset_config_button, LV_OBJ_FLAG_HIDDEN);\n lv_obj_clear_flag(objects.reset_config_spinner, LV_OBJ_FLAG_HIDDEN); \n ui_call_rpc_handler(\"resetConfig\", NULL);\n } else {\n char buf[100];\n int remaining_time_seconds = remaining_time / 1000;\n if (remaining_time_seconds <= 1) {\n remaining_time_seconds = 1;\n }\n sprintf(buf, \"Press and hold for %d seconds\", remaining_time_seconds);\n lv_label_set_text(objects.reset_config_label, buf);\n }\n }\n}\n\nvoid action_reboot(lv_event_t * e) {\n lv_event_code_t event_code = lv_event_get_code(e);\n lv_obj_t *obj = lv_event_get_target(e);\n \n if (event_code == LV_EVENT_PRESSED) {\n t_reboot = lv_tick_get();\n }\n else if (event_code == LV_EVENT_PRESSING) {\n int remaining_time = REBOOT_HOLD_TIME * 1000 - lv_tick_elaps(t_reboot);\n if (remaining_time <= 0) {\n ui_call_rpc_handler(\"reboot\", NULL);\n } else {\n char buf[100];\n int remaining_time_seconds = remaining_time / 1000;\n if (remaining_time_seconds <= 1) {\n remaining_time_seconds = 1;\n }\n sprintf(buf, \"Press and hold for %d seconds\", remaining_time_seconds);\n lv_label_set_text(objects.reboot_label, buf);\n }\n }\n}" }, { "objID": "1dbd1b7e-7270-47f0-ee02-e80bdae287cf", @@ -93,12 +93,12 @@ { "objID": "118ba563-bf4b-4ce9-8f7d-67c550f7ebd2", "fileName": "ui.h", - "template": "#ifndef EEZ_LVGL_UI_GUI_H\n#define EEZ_LVGL_UI_GUI_H\n\n//${eez-studio LVGL_INCLUDE}\n\n//${eez-studio EEZ_FOR_LVGL_CHECK}\n\n#if defined(EEZ_FOR_LVGL)\n#include \n#endif\n\n#if !defined(EEZ_FOR_LVGL)\n#include \"screens.h\"\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n//${eez-studio GUI_ASSETS_DECL}\n\nvoid ui_init();\nvoid ui_tick();\n\n#if !defined(EEZ_FOR_LVGL)\nvoid loadScreen(enum ScreensEnum screenId);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // EEZ_LVGL_UI_GUI_H" + "template": "#ifndef EEZ_LVGL_UI_GUI_H\n#define EEZ_LVGL_UI_GUI_H\n\n//${eez-studio LVGL_INCLUDE}\n\ntypedef void (jetkvm_rpc_handler_t)(const char *method, const char *params);\n\nvoid ui_set_rpc_handler(jetkvm_rpc_handler_t *handler);\nvoid ui_call_rpc_handler(const char *method, const char *params);\n\n\n\n//${eez-studio EEZ_FOR_LVGL_CHECK}\n\n#if defined(EEZ_FOR_LVGL)\n#include \n#endif\n\n#if !defined(EEZ_FOR_LVGL)\n#include \"screens.h\"\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n//${eez-studio GUI_ASSETS_DECL}\n\nvoid ui_init();\nvoid ui_tick();\n\n#if !defined(EEZ_FOR_LVGL)\nvoid loadScreen(enum ScreensEnum screenId);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // EEZ_LVGL_UI_GUI_H" }, { "objID": "3697d44a-db04-48a2-f3e5-098172727346", "fileName": "ui.c", - "template": "#if defined(EEZ_FOR_LVGL)\n#include \n#endif\n\n#include \"ui.h\"\n#include \"screens.h\"\n#include \"images.h\"\n#include \"actions.h\"\n#include \"vars.h\"\n\n//${eez-studio GUI_ASSETS_DEF}\n\n//${eez-studio LVGL_NATIVE_VARS_TABLE_DEF}\n\n//${eez-studio LVGL_ACTIONS_ARRAY_DEF}\n\n#if defined(EEZ_FOR_LVGL)\n\nvoid ui_init() {\n eez_flow_init(assets, sizeof(assets), (lv_obj_t **)&objects, sizeof(objects), images, sizeof(images), actions);\n}\n\nvoid ui_tick() {\n eez_flow_tick();\n tick_screen(g_currentScreen);\n}\n\n#else\n\n#include \n\nstatic int16_t currentScreen = -1;\n\nstatic lv_obj_t *getLvglObjectFromIndex(int32_t index) {\n if (index == -1) {\n return 0;\n }\n return ((lv_obj_t **)&objects)[index];\n}\n\nvoid loadScreen(enum ScreensEnum screenId) {\n currentScreen = screenId - 1;\n lv_obj_t *screen = getLvglObjectFromIndex(currentScreen);\n lv_scr_load(screen);\n // lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);\n}\n\nvoid ui_init() {\n create_screens();\n//${eez-studio LVGL_LOAD_FIRST_SCREEN}\n}\n\nvoid ui_tick() {\n tick_screen(currentScreen);\n}\n\n#endif\n" + "template": "#if defined(EEZ_FOR_LVGL)\n#include \n#endif\n\n#include \"ui.h\"\n#include \"screens.h\"\n#include \"images.h\"\n#include \"actions.h\"\n#include \"vars.h\"\n\n//${eez-studio GUI_ASSETS_DEF}\n\n//${eez-studio LVGL_NATIVE_VARS_TABLE_DEF}\n\n//${eez-studio LVGL_ACTIONS_ARRAY_DEF}\n\n\njetkvm_rpc_handler_t *ui_rpc_handler = NULL;\n\nvoid ui_set_rpc_handler(jetkvm_rpc_handler_t *handler) {\n ui_rpc_handler = handler;\n}\n\nvoid ui_call_rpc_handler(const char *method, const char *params) {\n if (ui_rpc_handler != NULL) {\n (*ui_rpc_handler)(method, params);\n }\n}\n\n#if defined(EEZ_FOR_LVGL)\n\nvoid ui_init() {\n eez_flow_init(assets, sizeof(assets), (lv_obj_t **)&objects, sizeof(objects), images, sizeof(images), actions);\n}\n\nvoid ui_tick() {\n eez_flow_tick();\n tick_screen(g_currentScreen);\n}\n\n#else\n\n#include \n\nstatic int16_t currentScreen = -1;\n\nstatic lv_obj_t *getLvglObjectFromIndex(int32_t index) {\n if (index == -1) {\n return 0;\n }\n return ((lv_obj_t **)&objects)[index];\n}\n\nvoid loadScreen(enum ScreensEnum screenId) {\n currentScreen = screenId - 1;\n lv_obj_t *screen = getLvglObjectFromIndex(currentScreen);\n lv_scr_load(screen);\n // lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);\n}\n\nvoid ui_init() {\n create_screens();\n//${eez-studio LVGL_LOAD_FIRST_SCREEN}\n}\n\nvoid ui_tick() {\n tick_screen(currentScreen);\n}\n\n#endif\n" } ], "destinationFolder": "src\\ui", @@ -162,6 +162,14 @@ "userProperties": [], "name": "SwitchToAdvancedMenu" }, + { + "objID": "7a5c014d-5d9c-4401-b604-09417c95ea38", + "components": [], + "connectionLines": [], + "localVariables": [], + "userProperties": [], + "name": "SwitchToResetConfig" + }, { "objID": "50a38244-1805-40c3-ef63-4f0798e46498", "components": [], @@ -241,6 +249,22 @@ "localVariables": [], "userProperties": [], "name": "ResetConfig" + }, + { + "objID": "0fc0513e-bf14-4e77-83cc-34294b7c06a3", + "components": [], + "connectionLines": [], + "localVariables": [], + "userProperties": [], + "name": "Reboot" + }, + { + "objID": "8ca31236-6234-452d-b9b9-4354d0ea66ba", + "components": [], + "connectionLines": [], + "localVariables": [], + "userProperties": [], + "name": "SwitchToReboot" } ], "userPages": [ @@ -2993,7 +3017,7 @@ "left": 0, "top": 0, "width": 100, - "height": 224, + "height": 108, "customInputs": [], "customOutputs": [], "style": { @@ -3024,8 +3048,17 @@ "conditionalStyles": [], "childStyles": [] }, + "hiddenInEditor": true, "timeline": [], - "eventHandlers": [], + "eventHandlers": [ + { + "objID": "92167a24-7274-4cfe-8a9a-edeacccaeb21", + "eventName": "PRESSED", + "handlerType": "action", + "action": "ResetConfig", + "userData": 0 + } + ], "identifier": "MenuBtnAdvancedDeveloperMode", "leftUnit": "px", "topUnit": "px", @@ -3047,6 +3080,7 @@ "conditionalStyles": [], "childStyles": [] }, + "hiddenInEditor": true, "timeline": [], "eventHandlers": [], "identifier": "", @@ -3078,6 +3112,7 @@ } ], "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlag": true, "hiddenFlagType": "literal", "clickableFlag": true, "clickableFlagType": "literal", @@ -3110,6 +3145,7 @@ "conditionalStyles": [], "childStyles": [] }, + "hiddenInEditor": true, "timeline": [], "eventHandlers": [], "identifier": "MenuBtnAdvancedUSBEmulation", @@ -3133,6 +3169,7 @@ "conditionalStyles": [], "childStyles": [] }, + "hiddenInEditor": true, "timeline": [], "eventHandlers": [], "leftUnit": "px", @@ -3163,6 +3200,7 @@ } ], "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlag": true, "hiddenFlagType": "literal", "clickableFlag": true, "clickableFlagType": "literal", @@ -3195,9 +3233,18 @@ "conditionalStyles": [], "childStyles": [] }, + "locked": false, "hiddenInEditor": false, "timeline": [], - "eventHandlers": [], + "eventHandlers": [ + { + "objID": "ddf88376-fba1-4e5f-fc35-ab162c19cf9f", + "eventName": "PRESSED", + "handlerType": "action", + "action": "SwitchToReboot", + "userData": 0 + } + ], "identifier": "MenuBtnAdvancedReboot", "leftUnit": "px", "topUnit": "px", @@ -3250,6 +3297,7 @@ } ], "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW", + "hiddenFlag": false, "hiddenFlagType": "literal", "clickableFlag": true, "clickableFlagType": "literal", @@ -3283,7 +3331,15 @@ "childStyles": [] }, "timeline": [], - "eventHandlers": [], + "eventHandlers": [ + { + "objID": "cd3b5095-606c-4007-c053-a2b362818cc4", + "eventName": "PRESSED", + "handlerType": "action", + "action": "SwitchToResetConfig", + "userData": 0 + } + ], "identifier": "MenuBtnAdvancedResetConfig", "leftUnit": "px", "topUnit": "px", @@ -6557,7 +6613,7 @@ "type": "LVGLLabelWidget", "left": 0, "top": 0, - "width": 117, + "width": 116, "height": 20, "customInputs": [], "customOutputs": [], @@ -6586,7 +6642,7 @@ "objID": "a7abc8b4-5ce5-4506-8ecb-e4a3d059e35c" }, "groupIndex": 0, - "text": "Reset Device", + "text": "Reset Config", "textType": "literal", "longMode": "WRAP", "recolor": false @@ -6679,7 +6735,7 @@ }, "timeline": [], "eventHandlers": [], - "identifier": "ResetConfigLabel", + "identifier": "ResetConfigLabelContainer", "leftUnit": "px", "topUnit": "px", "widthUnit": "%", @@ -6702,7 +6758,7 @@ }, "timeline": [], "eventHandlers": [], - "identifier": "", + "identifier": "ResetConfigLabel", "leftUnit": "px", "topUnit": "px", "widthUnit": "%", @@ -6731,7 +6787,7 @@ }, "group": "", "groupIndex": 0, - "text": "Press and hold for\n20 seconds", + "text": "Press and hold for\n10 seconds", "textType": "literal", "longMode": "WRAP", "recolor": false, @@ -6767,7 +6823,7 @@ "groupIndex": 0 }, { - "objID": "cbac637a-7b3f-450b-c962-2ceca07a0a43", + "objID": "8a70fd05-3313-4713-9d38-f7d95f9f7648", "type": "LVGLContainerWidget", "left": 0, "top": 0, @@ -6776,12 +6832,12 @@ "customInputs": [], "customOutputs": [], "style": { - "objID": "5c719542-cd7f-4b66-c0b4-3b2812132e3f", + "objID": "3844c45f-c3ce-4eae-aa76-9fde7cca04b9", "useStyle": "default", "conditionalStyles": [], "childStyles": [] }, - "hiddenInEditor": true, + "hiddenInEditor": false, "timeline": [], "eventHandlers": [], "identifier": "ResetConfigSpinner", @@ -6791,7 +6847,7 @@ "heightUnit": "content", "children": [ { - "objID": "abf38156-7bc2-4c4e-93fc-e08d9ee999e7", + "objID": "7e07aff7-ba61-465d-c204-cb1d2f10c061", "type": "LVGLSpinnerWidget", "left": 0, "top": 0, @@ -6800,12 +6856,11 @@ "customInputs": [], "customOutputs": [], "style": { - "objID": "8f4f24d3-5bd6-433f-bac5-e15c05820742", + "objID": "b6389edb-790f-47ac-d2ec-cf7ad2262a8e", "useStyle": "default", "conditionalStyles": [], "childStyles": [] }, - "hiddenInEditor": true, "timeline": [], "eventHandlers": [], "leftUnit": "px", @@ -6824,15 +6879,16 @@ "disabledStateType": "literal", "states": "", "localStyles": { - "objID": "e8d49d0f-a7e9-44df-afa0-db6cde72f306" + "objID": "cdfe03f8-cdc5-4b9e-c4c0-1d6d4686431f" }, "group": "", "groupIndex": 0 } ], "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlag": true, "hiddenFlagType": "literal", - "clickableFlag": true, + "clickableFlag": false, "clickableFlagType": "literal", "flagScrollbarMode": "", "flagScrollDirection": "", @@ -6843,7 +6899,7 @@ "states": "", "useStyle": "FlexColumnStart", "localStyles": { - "objID": "46a10ecd-c85a-4dfa-a7a8-412a90c09ee1", + "objID": "033be319-ac3b-4fa0-b8ab-fa37038c754a", "definition": { "MAIN": { "DEFAULT": { @@ -6900,8 +6956,15 @@ "timeline": [], "eventHandlers": [ { - "objID": "ecf97e0e-553c-4f12-d07d-75b8641d9374", - "eventName": "LONG_PRESSED", + "objID": "dd7fca79-3ff3-483a-9cbf-fdb14acf5979", + "eventName": "PRESSED", + "handlerType": "action", + "action": "ResetConfig", + "userData": 0 + }, + { + "objID": "c2e40610-5f7d-4c0e-e476-21a691336d09", + "eventName": "PRESSING", "handlerType": "action", "action": "ResetConfig", "userData": 0 @@ -6917,7 +6980,7 @@ "type": "LVGLLabelWidget", "left": 0, "top": 0, - "width": 94, + "width": 145, "height": 16, "customInputs": [], "customOutputs": [], @@ -6958,7 +7021,7 @@ }, "group": "", "groupIndex": 0, - "text": "Hold to reset", + "text": "Reset configuration", "textType": "literal", "longMode": "WRAP", "recolor": false @@ -7107,6 +7170,651 @@ "isUsedAsUserWidget": false, "createAtStart": true, "deleteOnScreenUnload": false + }, + { + "objID": "08c14f9e-dfe7-4b21-dd8e-fda8cf3c3050", + "components": [ + { + "objID": "07967261-bc17-488c-9a11-d19a01fbfe28", + "type": "LVGLScreenWidget", + "left": 0, + "top": 0, + "width": 300, + "height": 240, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "6f262fdf-8cf1-4c21-875d-5f1aa441f852", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [ + { + "objID": "eb60e3d5-4409-4497-878c-9a309b98d729", + "eventName": "GESTURE", + "handlerType": "action", + "action": "AboutScreenGesture", + "userData": 0 + } + ], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "px", + "heightUnit": "px", + "children": [ + { + "objID": "fbb29f7b-edbc-40fb-8bbe-d401d5baaef8", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 100, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "f2618f34-91a0-4377-88cd-964116e5dcbe", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "%", + "children": [ + { + "objID": "55459a31-97d4-44fa-9395-f049ee6160c8", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 32, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "2156ab89-2e70-48e0-f9b8-5df09832fd13", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "RebootHeader", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "abdd9bd2-62de-41d8-ee18-da39bccf1844", + "type": "LVGLButtonWidget", + "left": 0, + "top": 0, + "width": 32, + "height": 32, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "30cd4c39-de2f-44cd-fbfb-6ea880df54b3", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [ + { + "objID": "6b2fe929-8516-45ad-f2d0-e6d4d5d2de91", + "eventName": "CLICKED", + "handlerType": "action", + "action": "SwitchToMenu", + "userData": 0 + } + ], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "px", + "heightUnit": "px", + "children": [ + { + "objID": "5b346529-992e-42bc-eae7-921ea24dd865", + "type": "LVGLImageWidget", + "left": -1, + "top": 2, + "width": 8, + "height": 12, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "9687a8bc-08a8-4eba-dc85-fa136ca66d5d", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "content", + "heightUnit": "content", + "children": [], + "widgetFlags": "ADV_HITTEST|CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "localStyles": { + "objID": "6b767ea7-aa49-4b55-b74d-e00e9093c807" + }, + "group": "", + "groupIndex": 0, + "image": "back-caret", + "setPivot": false, + "pivotX": 0, + "pivotY": 0, + "zoom": 256, + "angle": 0, + "innerAlign": "CENTER" + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "BackButton", + "localStyles": { + "objID": "5ae1b220-a20e-4139-88d0-4306e9c7a8a4" + }, + "group": "", + "groupIndex": 0 + }, + { + "objID": "97d81954-5fc7-46f8-8805-1017eaab32f1", + "type": "LVGLLabelWidget", + "left": 0, + "top": 0, + "width": 131, + "height": 20, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "57bf65c3-724e-43cf-e62e-8020827485fc", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "", + "leftUnit": "%", + "topUnit": "%", + "widthUnit": "content", + "heightUnit": "content", + "children": [], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "HeaderLink", + "localStyles": { + "objID": "e9d6f329-0eab-4410-f3e1-e192b9da3516" + }, + "groupIndex": 0, + "text": "Reboot Device", + "textType": "literal", + "longMode": "WRAP", + "recolor": false + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlowRowSpaceBetween", + "localStyles": { + "objID": "8430c074-9478-4925-9cfc-ca66c40cebab", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 4 + } + } + } + }, + "group": "", + "groupIndex": 0 + }, + { + "objID": "786e6022-e155-4817-85c7-4fb14ba32abf", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 80, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "ae6ca605-56d9-4520-e1a9-aabd32d5a6e4", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "RebootContainer", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "%", + "children": [ + { + "objID": "5b9d41c7-6ef0-4801-a451-03698a3cab62", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 118, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "887e0a83-0776-4fb3-b14c-0aca586acd1b", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "a4d2abb4-8fe3-427b-96ee-9374e1db7fbc", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 60, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "470bb18c-321e-4360-c405-151f213b5ece", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "RebootLabelContainer", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "f4d2f437-87ee-4502-cf0c-c908b40df1b7", + "type": "LVGLLabelWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 40, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "9b36d75b-68b5-472e-bbc4-f816a8e8f399", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "RebootLabel", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "InfoContentLabel", + "localStyles": { + "objID": "120486ec-a295-475b-c099-687261502c2a", + "definition": { + "MAIN": { + "DEFAULT": { + "text_font": "FontBook20" + } + } + } + }, + "group": "", + "groupIndex": 0, + "text": "Press and hold for\n5 seconds", + "textType": "literal", + "longMode": "WRAP", + "recolor": false, + "previewValue": "0.0.1" + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "3a8dee11-73af-4910-f1c7-1468f5431a8a", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 10, + "pad_left": 10, + "pad_top": 10, + "pad_bottom": 10 + } + } + } + }, + "group": "", + "groupIndex": 0 + }, + { + "objID": "45ea864f-58c1-4d5d-e127-b97555add8bf", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 50, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "6ad1372a-50a8-40e1-f7d2-a2590f6e2165", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "hiddenInEditor": false, + "timeline": [], + "eventHandlers": [], + "identifier": "RebootConfigButton", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "63f1761b-6e49-4dc6-b332-30433d40bacf", + "type": "LVGLButtonWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 50, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "df54f6fe-592f-48bf-aa40-a4484f296e3e", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "hiddenInEditor": false, + "timeline": [], + "eventHandlers": [ + { + "objID": "a7796219-cfc4-45e7-bf90-9d374e674003", + "eventName": "PRESSED", + "handlerType": "action", + "action": "Reboot", + "userData": 0 + }, + { + "objID": "35cd8033-6cd0-4359-c995-e627dac3815c", + "eventName": "PRESSING", + "handlerType": "action", + "action": "Reboot", + "userData": 0 + } + ], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "px", + "children": [ + { + "objID": "4fcf0c6c-39e7-48bd-8567-18093e91e6f2", + "type": "LVGLLabelWidget", + "left": 0, + "top": 0, + "width": 106, + "height": 16, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "06433a39-c46c-4c09-dd93-6521174405e0", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "hiddenInEditor": false, + "timeline": [], + "eventHandlers": [], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "content", + "heightUnit": "content", + "children": [], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "localStyles": { + "objID": "f88937ae-2537-4599-b0b3-6b41ad50c8cb", + "definition": { + "MAIN": { + "DEFAULT": { + "align": "CENTER", + "text_align": "LEFT" + } + } + } + }, + "group": "", + "groupIndex": 0, + "text": "Hold to reboot", + "textType": "literal", + "longMode": "WRAP", + "recolor": false + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "", + "localStyles": { + "objID": "375a8cfa-03c1-4c33-8135-e3a841edb1df", + "definition": { + "MAIN": { + "DEFAULT": { + "bg_color": "DC2626", + "text_align": "LEFT", + "pad_right": 13 + } + } + } + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "00264c51-c7f0-49f6-f367-f932e00a0ca5" + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "91a33d82-74c3-48c4-b623-3cc82961c053", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 10 + } + } + } + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_VER|SNAPPABLE|SCROLL_ELASTIC|SCROLL_WITH_ARROW|SCROLL_MOMENTUM|SCROLL_CHAIN_HOR|SCROLLABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "auto", + "flagScrollDirection": "ver", + "scrollSnapX": "start", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "d8f53da5-0b49-44e7-bf3c-0dfaabf57ced", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 4 + } + } + } + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE|SCROLL_ELASTIC", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexStart", + "localStyles": { + "objID": "a33e581f-4cdf-47d8-91cd-db93f2b49bf5" + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICKABLE|PRESS_LOCK|CLICK_FOCUSABLE|GESTURE_BUBBLE|SNAPPABLE|SCROLLABLE|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexScreenMenu", + "localStyles": { + "objID": "22536b90-1d84-4789-8229-4db6155fa9d0" + }, + "groupIndex": 0 + } + ], + "connectionLines": [], + "localVariables": [], + "userProperties": [], + "name": "RebootScreen", + "left": 0, + "top": 0, + "width": 300, + "height": 240, + "isUsedAsUserWidget": false, + "createAtStart": true, + "deleteOnScreenUnload": false } ], "userWidgets": [], diff --git a/internal/native/eez/jetkvm.eez-project-ui-state b/internal/native/eez/jetkvm.eez-project-ui-state index 6685cef6..897e3ad3 100644 --- a/internal/native/eez/jetkvm.eez-project-ui-state +++ b/internal/native/eez/jetkvm.eez-project-ui-state @@ -1,7 +1,7 @@ { "navigation": { "selectedUserPageObject": "[jetkvm.eez-project]:/userPages/8", - "selectedActionObject": "[jetkvm.eez-project]:/actions/5", + "selectedActionObject": "[jetkvm.eez-project]:/actions/12", "selectedGlobalVariableObject": "[jetkvm.eez-project]:/variables/globalVariables/1", "selectedStyleObject": "[jetkvm.eez-project]:/lvglStyles/styles/8", "selectedThemeObject": "[jetkvm.eez-project]:/themes/0", @@ -30,7 +30,7 @@ { "type": "border", "selected": 2, - "size": 296.5, + "size": 271.5, "location": "right", "children": [ { @@ -130,7 +130,6 @@ "type": "tabset", "id": "#2e3d9a08-c69c-42b5-b434-525109f2a5a7", "weight": 1, - "selected": 1, "enableClose": false, "children": [ { @@ -196,25 +195,25 @@ { "type": "tabset", "id": "EDITORS", - "weight": 56.255429602160085, - "selected": 2, + "weight": 52.479136828866125, + "selected": 5, "enableDeleteWhenEmpty": false, "enableClose": false, "children": [ { "type": "tab", - "id": "#4610a27a-ce31-4747-b3c0-488eafeb606b", - "name": "StatusScreen", + "id": "#2b774476-9ef3-4363-83f8-8b478f163b02", + "name": "MenuAdvancedScreen", "component": "editor", "config": { - "objectPath": "[jetkvm.eez-project]:/userPages/7", + "objectPath": "[jetkvm.eez-project]:/userPages/4", "permanent": false }, "icon": "svg:page" }, { "type": "tab", - "id": "#ef9d764d-e942-47f4-beec-136cbd40ffd7", + "id": "#7bbd8382-ea41-467d-8ad3-4312a2d47266", "name": "ResetConfigScreen", "component": "editor", "config": { @@ -223,21 +222,10 @@ }, "icon": "svg:page" }, - { - "type": "tab", - "id": "#aec56ae8-5b75-4a2f-ad81-f0d7d683c77a", - "name": "FontBook24", - "component": "editor", - "config": { - "objectPath": "[jetkvm.eez-project]:/fonts/4", - "permanent": false - }, - "icon": "material:font_download" - }, { "type": "tab", "id": "#c8dece00-e490-46b8-8a14-5dcfa8bbce36", - "name": "NoNetworkScreen", + "name": "StatusScreen", "component": "editor", "config": { "objectPath": "[jetkvm.eez-project]:/userPages/7", @@ -259,7 +247,7 @@ { "type": "tab", "id": "#f5a057a5-977c-46be-8702-5447d603a34f", - "name": "MenuScreen", + "name": "HomeScreen", "component": "editor", "config": { "objectPath": "[jetkvm.eez-project]:/userPages/2", @@ -285,7 +273,7 @@ { "type": "row", "id": "#ee319cf9-6145-49e4-b40e-1d999be897c8", - "weight": 18.007499872650474, + "weight": 21.78379264594443, "children": [ { "type": "tabset", @@ -1237,15 +1225,11 @@ "0": { "0": { "0": { - "0": { - "$selected": true - } + "0": {} }, "1": { "0": { - "0": {}, - "1": {}, - "2": {} + "3": {} } } } @@ -1253,8 +1237,8 @@ }, "transform": { "translate": { - "x": -176, - "y": -127 + "x": -181, + "y": -256.3828125 }, "scale": 1 }, @@ -1372,16 +1356,19 @@ "selection": { "0": { "0": { - "0": {}, + "0": { + "0": {} + }, "1": { "0": { - "0": {}, - "1": { + "0": { "0": { - "0": { - "$selected": true - } + "$selected": true } + }, + "1": {}, + "2": { + "0": {} } } } @@ -1418,10 +1405,8 @@ "lvglPart": "MAIN", "lvglState": "DEFAULT", "lvglExpandedPropertiesGroup": [ - "TEXT", - "ARC", "POSITION AND SIZE", - "PADDING" + "LAYOUT" ], "showInactiveFlowsInDebugger": true, "globalFlowZoom": true, diff --git a/internal/native/eez/src/ui/actions.c b/internal/native/eez/src/ui/actions.c index 257d4505..3deb1f1c 100644 --- a/internal/native/eez/src/ui/actions.c +++ b/internal/native/eez/src/ui/actions.c @@ -1,5 +1,7 @@ #include "actions.h" #include "screens.h" +#include "ui.h" +#include int handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int screenId) { lv_event_code_t event_code = lv_event_get_code(e); @@ -31,6 +33,14 @@ void action_switch_to_about(lv_event_t *e) { loadScreen(SCREEN_ID_ABOUT_SCREEN); } +void action_switch_to_reset_config(lv_event_t *e) { + loadScreen(SCREEN_ID_RESET_CONFIG_SCREEN); +} + +void action_switch_to_reboot(lv_event_t *e) { + loadScreen(SCREEN_ID_REBOOT_SCREEN); +} + void action_menu_screen_gesture(lv_event_t * e) { handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_HOME_SCREEN); } @@ -51,27 +61,56 @@ void action_about_screen_gesture(lv_event_t * e) { handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN); } -static const int RESET_LONG_PRESS_DURATION = 1000 * 20; // 20 seconds +// user_data doesn't seem to be working, so we use a global variable here +static uint32_t t_reset_config; +static uint32_t t_reboot; +const int RESET_CONFIG_HOLD_TIME = 10; +const int REBOOT_HOLD_TIME = 5; void action_reset_config(lv_event_t * e) { lv_event_code_t event_code = lv_event_get_code(e); lv_obj_t *obj = lv_event_get_target(e); if (event_code == LV_EVENT_PRESSED) { - // Button pressed - start timing - uint32_t reset_press_start_time = lv_tick_get(); - lv_obj_set_user_data(obj, (uint32_t) reset_press_start_time); + t_reset_config = lv_tick_get(); } else if (event_code == LV_EVENT_PRESSING) { - uint32_t reset_press_start_time = (uint32_t) lv_obj_get_user_data(obj); - if (reset_press_start_time == 0) { - return; - } - - uint32_t current_time = lv_tick_get(); - if (current_time - reset_press_start_time >= RESET_LONG_PRESS_DURATION) { + int remaining_time = RESET_CONFIG_HOLD_TIME * 1000 - lv_tick_elaps(t_reset_config); + if (remaining_time <= 0) { lv_obj_add_flag(objects.reset_config_button, LV_OBJ_FLAG_HIDDEN); - lv_obj_clear_flag(objects.reset_config_spinner, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(objects.reset_config_spinner, LV_OBJ_FLAG_HIDDEN); + ui_call_rpc_handler("resetConfig", NULL); + } else { + char buf[100]; + int remaining_time_seconds = remaining_time / 1000; + if (remaining_time_seconds <= 1) { + remaining_time_seconds = 1; + } + sprintf(buf, "Press and hold for %d seconds", remaining_time_seconds); + lv_label_set_text(objects.reset_config_label, buf); + } + } +} + +void action_reboot(lv_event_t * e) { + lv_event_code_t event_code = lv_event_get_code(e); + lv_obj_t *obj = lv_event_get_target(e); + + if (event_code == LV_EVENT_PRESSED) { + t_reboot = lv_tick_get(); + } + else if (event_code == LV_EVENT_PRESSING) { + int remaining_time = REBOOT_HOLD_TIME * 1000 - lv_tick_elaps(t_reboot); + if (remaining_time <= 0) { + ui_call_rpc_handler("reboot", NULL); + } else { + char buf[100]; + int remaining_time_seconds = remaining_time / 1000; + if (remaining_time_seconds <= 1) { + remaining_time_seconds = 1; + } + sprintf(buf, "Press and hold for %d seconds", remaining_time_seconds); + lv_label_set_text(objects.reboot_label, buf); } } } \ No newline at end of file diff --git a/internal/native/eez/src/ui/actions.h b/internal/native/eez/src/ui/actions.h index 398ff723..f4a24e44 100644 --- a/internal/native/eez/src/ui/actions.h +++ b/internal/native/eez/src/ui/actions.h @@ -11,6 +11,7 @@ extern int handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int s extern void action_switch_to_menu(lv_event_t * e); extern void action_switch_to_advanced_menu(lv_event_t * e); +extern void action_switch_to_reset_config(lv_event_t * e); extern void action_switch_to_about(lv_event_t * e); extern void action_menu_screen_gesture(lv_event_t * e); extern void action_home_screen_gesture(lv_event_t * e); @@ -21,6 +22,8 @@ extern void action_switch_to_status(lv_event_t * e); extern void action_common_click_event(lv_event_t * e); extern void action_handle_common_press_event(lv_event_t * e); extern void action_reset_config(lv_event_t * e); +extern void action_reboot(lv_event_t * e); +extern void action_switch_to_reboot(lv_event_t * e); #ifdef __cplusplus diff --git a/internal/native/eez/src/ui/screens.c b/internal/native/eez/src/ui/screens.c index 6844b32a..9ee7fc60 100644 --- a/internal/native/eez/src/ui/screens.c +++ b/internal/native/eez/src/ui/screens.c @@ -829,6 +829,8 @@ void create_screen_menu_advanced_screen() { objects.menu_btn_advanced_developer_mode = obj; lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_PCT(100), 50); + lv_obj_add_event_cb(obj, action_reset_config, LV_EVENT_PRESSED, (void *)0); + lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN); add_style_menu_button(obj); { lv_obj_t *parent_obj = obj; @@ -847,6 +849,7 @@ void create_screen_menu_advanced_screen() { objects.menu_btn_advanced_usb_emulation = obj; lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_PCT(100), 50); + lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN); add_style_menu_button(obj); { lv_obj_t *parent_obj = obj; @@ -865,6 +868,7 @@ void create_screen_menu_advanced_screen() { objects.menu_btn_advanced_reboot = obj; lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_PCT(100), 50); + lv_obj_add_event_cb(obj, action_switch_to_reboot, LV_EVENT_PRESSED, (void *)0); lv_obj_clear_flag(obj, LV_OBJ_FLAG_SNAPPABLE); add_style_menu_button(obj); { @@ -884,6 +888,7 @@ void create_screen_menu_advanced_screen() { objects.menu_btn_advanced_reset_config = obj; lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_PCT(100), 50); + lv_obj_add_event_cb(obj, action_switch_to_reset_config, LV_EVENT_PRESSED, (void *)0); lv_obj_clear_flag(obj, LV_OBJ_FLAG_SNAPPABLE); add_style_menu_button(obj); lv_obj_set_style_bg_color(obj, lv_color_hex(0xffdc2626), LV_PART_MAIN | LV_STATE_DEFAULT); @@ -1780,7 +1785,7 @@ void create_screen_reset_config_screen() { lv_obj_set_pos(obj, LV_PCT(0), LV_PCT(0)); lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); add_style_header_link(obj); - lv_label_set_text(obj, "Reset Device"); + lv_label_set_text(obj, "Reset Config"); } } } @@ -1819,9 +1824,9 @@ void create_screen_reset_config_screen() { { lv_obj_t *parent_obj = obj; { - // ResetConfigLabel + // ResetConfigLabelContainer lv_obj_t *obj = lv_obj_create(parent_obj); - objects.reset_config_label = obj; + objects.reset_config_label_container = obj; lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); @@ -1836,12 +1841,14 @@ void create_screen_reset_config_screen() { { lv_obj_t *parent_obj = obj; { + // ResetConfigLabel lv_obj_t *obj = lv_label_create(parent_obj); + objects.reset_config_label = obj; lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); add_style_info_content_label(obj); lv_obj_set_style_text_font(obj, &ui_font_font_book20, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_label_set_text(obj, "Press and hold for\n20 seconds"); + lv_label_set_text(obj, "Press and hold for\n10 seconds"); } } } @@ -1858,7 +1865,8 @@ void create_screen_reset_config_screen() { lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE|LV_OBJ_FLAG_SCROLLABLE); add_style_flex_column_start(obj); lv_obj_set_style_flex_main_place(obj, LV_FLEX_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_flex_cross_place(obj, LV_FLEX_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); @@ -1895,7 +1903,8 @@ void create_screen_reset_config_screen() { objects.obj0 = obj; lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_PCT(100), 50); - lv_obj_add_event_cb(obj, action_reset_config, LV_EVENT_LONG_PRESSED, (void *)0); + lv_obj_add_event_cb(obj, action_reset_config, LV_EVENT_PRESSED, (void *)0); + lv_obj_add_event_cb(obj, action_reset_config, LV_EVENT_PRESSING, (void *)0); lv_obj_set_style_bg_color(obj, lv_color_hex(0xffdc2626), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(obj, 13, LV_PART_MAIN | LV_STATE_DEFAULT); @@ -1907,7 +1916,7 @@ void create_screen_reset_config_screen() { lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_style_align(obj, LV_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_label_set_text(obj, "Hold to reset"); + lv_label_set_text(obj, "Reset configuration"); } } } @@ -1927,6 +1936,189 @@ void create_screen_reset_config_screen() { void tick_screen_reset_config_screen() { } +void create_screen_reboot_screen() { + lv_obj_t *obj = lv_obj_create(0); + objects.reboot_screen = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, 300, 240); + lv_obj_add_event_cb(obj, action_about_screen_gesture, LV_EVENT_GESTURE, (void *)0); + add_style_flex_screen_menu(obj); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_obj_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_start(obj); + { + lv_obj_t *parent_obj = obj; + { + // RebootHeader + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.reboot_header = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + add_style_flow_row_space_between(obj); + lv_obj_set_style_pad_right(obj, 4, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_button_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, 32, 32); + lv_obj_add_event_cb(obj, action_switch_to_menu, LV_EVENT_CLICKED, (void *)0); + add_style_back_button(obj); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_image_create(parent_obj); + lv_obj_set_pos(obj, -1, 2); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_image_set_src(obj, &img_back_caret); + } + } + } + { + lv_obj_t *obj = lv_label_create(parent_obj); + lv_obj_set_pos(obj, LV_PCT(0), LV_PCT(0)); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + add_style_header_link(obj); + lv_label_set_text(obj, "Reboot Device"); + } + } + } + { + // RebootContainer + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.reboot_container = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_PCT(80)); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_AUTO); + lv_obj_set_scroll_dir(obj, LV_DIR_VER); + lv_obj_set_scroll_snap_x(obj, LV_SCROLL_SNAP_START); + add_style_flex_column_start(obj); + lv_obj_set_style_pad_right(obj, 4, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_obj_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_column_start(obj); + lv_obj_set_style_pad_right(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + // RebootLabelContainer + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.reboot_label_container = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_column_start(obj); + lv_obj_set_style_pad_right(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + // RebootLabel + lv_obj_t *obj = lv_label_create(parent_obj); + objects.reboot_label = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + add_style_info_content_label(obj); + lv_obj_set_style_text_font(obj, &ui_font_font_book20, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_label_set_text(obj, "Press and hold for\n5 seconds"); + } + } + } + { + // RebootConfigButton + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.reboot_config_button = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_column_start(obj); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_button_create(parent_obj); + objects.obj1 = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), 50); + lv_obj_add_event_cb(obj, action_reboot, LV_EVENT_PRESSED, (void *)0); + lv_obj_add_event_cb(obj, action_reboot, LV_EVENT_PRESSING, (void *)0); + lv_obj_set_style_bg_color(obj, lv_color_hex(0xffdc2626), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 13, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_label_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_style_align(obj, LV_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_label_set_text(obj, "Hold to reboot"); + } + } + } + } + } + } + } + } + } + } + } + } + + tick_screen_reboot_screen(); +} + +void tick_screen_reboot_screen() { +} + typedef void (*tick_screen_func_t)(); @@ -1940,6 +2132,7 @@ tick_screen_func_t tick_screen_funcs[] = { tick_screen_about_screen, tick_screen_status_screen, tick_screen_reset_config_screen, + tick_screen_reboot_screen, }; void tick_screen(int screen_index) { tick_screen_funcs[screen_index](); @@ -1962,4 +2155,5 @@ void create_screens() { create_screen_about_screen(); create_screen_status_screen(); create_screen_reset_config_screen(); + create_screen_reboot_screen(); } diff --git a/internal/native/eez/src/ui/screens.h b/internal/native/eez/src/ui/screens.h index 3ae5941f..da05f543 100644 --- a/internal/native/eez/src/ui/screens.h +++ b/internal/native/eez/src/ui/screens.h @@ -17,6 +17,7 @@ typedef struct _objects_t { lv_obj_t *about_screen; lv_obj_t *status_screen; lv_obj_t *reset_config_screen; + lv_obj_t *reboot_screen; lv_obj_t *boot_logo; lv_obj_t *boot_screen_version; lv_obj_t *no_network_header_container; @@ -86,10 +87,17 @@ typedef struct _objects_t { lv_obj_t *cloud_domain; lv_obj_t *reset_config_header; lv_obj_t *reset_config_container; + lv_obj_t *reset_config_label_container; lv_obj_t *reset_config_label; lv_obj_t *reset_config_spinner; lv_obj_t *reset_config_button; lv_obj_t *obj0; + lv_obj_t *reboot_header; + lv_obj_t *reboot_container; + lv_obj_t *reboot_label_container; + lv_obj_t *reboot_label; + lv_obj_t *reboot_config_button; + lv_obj_t *obj1; } objects_t; extern objects_t objects; @@ -104,6 +112,7 @@ enum ScreensEnum { SCREEN_ID_ABOUT_SCREEN = 7, SCREEN_ID_STATUS_SCREEN = 8, SCREEN_ID_RESET_CONFIG_SCREEN = 9, + SCREEN_ID_REBOOT_SCREEN = 10, }; void create_screen_boot_screen(); @@ -132,6 +141,9 @@ void tick_screen_status_screen(); void create_screen_reset_config_screen(); void tick_screen_reset_config_screen(); + +void create_screen_reboot_screen(); +void tick_screen_reboot_screen(); void tick_screen_by_id(enum ScreensEnum screenId); void tick_screen(int screen_index); diff --git a/internal/native/eez/src/ui/ui.c b/internal/native/eez/src/ui/ui.c index 8d9c9c15..b1ef44a6 100644 --- a/internal/native/eez/src/ui/ui.c +++ b/internal/native/eez/src/ui/ui.c @@ -14,6 +14,19 @@ + +jetkvm_rpc_handler_t *ui_rpc_handler = NULL; + +void ui_set_rpc_handler(jetkvm_rpc_handler_t *handler) { + ui_rpc_handler = handler; +} + +void ui_call_rpc_handler(const char *method, const char *params) { + if (ui_rpc_handler != NULL) { + (*ui_rpc_handler)(method, params); + } +} + #if defined(EEZ_FOR_LVGL) void ui_init() { diff --git a/internal/native/eez/src/ui/ui.h b/internal/native/eez/src/ui/ui.h index de16057e..34d90416 100644 --- a/internal/native/eez/src/ui/ui.h +++ b/internal/native/eez/src/ui/ui.h @@ -3,6 +3,13 @@ #include +typedef void (jetkvm_rpc_handler_t)(const char *method, const char *params); + +void ui_set_rpc_handler(jetkvm_rpc_handler_t *handler); +void ui_call_rpc_handler(const char *method, const char *params); + + + #if defined(EEZ_FOR_LVGL) diff --git a/internal/native/lib/libjknative.a b/internal/native/lib/libjknative.a index ca20b69d..2c8a4dde 100644 Binary files a/internal/native/lib/libjknative.a and b/internal/native/lib/libjknative.a differ diff --git a/internal/native/native.go b/internal/native/native.go index 7ba4a6d3..8cf51560 100644 --- a/internal/native/native.go +++ b/internal/native/native.go @@ -18,6 +18,7 @@ type Native struct { onVideoStateChange func(state VideoState) onVideoFrameReceived func(frame []byte, duration time.Duration) onIndevEvent func(event string) + onRpcEvent func(event string) videoLock sync.Mutex } @@ -28,6 +29,7 @@ type NativeOptions struct { OnVideoStateChange func(state VideoState) OnVideoFrameReceived func(frame []byte, duration time.Duration) OnIndevEvent func(event string) + OnRpcEvent func(event string) } func NewNative(opts NativeOptions) *Native { @@ -52,6 +54,13 @@ func NewNative(opts NativeOptions) *Native { } } + onRpcEvent := opts.OnRpcEvent + if onRpcEvent == nil { + onRpcEvent = func(event string) { + nativeLogger.Info().Str("event", event).Msg("rpc event") + } + } + return &Native{ ready: make(chan struct{}), l: nativeLogger, @@ -62,6 +71,7 @@ func NewNative(opts NativeOptions) *Native { onVideoStateChange: opts.OnVideoStateChange, onVideoFrameReceived: opts.OnVideoFrameReceived, onIndevEvent: opts.OnIndevEvent, + onRpcEvent: opts.OnRpcEvent, videoLock: sync.Mutex{}, } } @@ -76,6 +86,7 @@ func (n *Native) Start() { go n.handleVideoStateChan() go n.handleVideoFrameChan() go n.handleIndevEventChan() + go n.handleRpcEventChan() n.initUI() go n.tickUI() diff --git a/native.go b/native.go index ce36a230..4c272b9a 100644 --- a/native.go +++ b/native.go @@ -24,6 +24,18 @@ func initNative(systemVersion *semver.Version, appVersion *semver.Version) { nativeLogger.Trace().Str("event", event).Msg("indev event received") wakeDisplay(false, "indev_event") }, + OnRpcEvent: func(event string) { + nativeLogger.Trace().Str("event", event).Msg("rpc event received") + switch event { + case "resetConfig": + rpcResetConfig() + rpcReboot(true) + case "reboot": + rpcReboot(true) + default: + nativeLogger.Warn().Str("event", event).Msg("unknown rpc event received") + } + }, OnVideoFrameReceived: func(frame []byte, duration time.Duration) { if currentSession != nil { err := currentSession.VideoTrack.WriteSample(media.Sample{Data: frame, Duration: duration})