@@ -108,15 +108,35 @@ void notify_active_tabs_before_delete(t_gui_state *gui_state) {
108108 }
109109}
110110
111+ void safe_delete_lv_obj (lv_obj_t * obj, const char * obj_name) {
112+ if (obj == NULL ) {
113+ return ;
114+ }
115+
116+ if (!lv_obj_is_valid (obj)) {
117+ omote_log_w (" safe_delete_lv_obj: %s object is invalid, skipping deletion\n " , obj_name);
118+ return ;
119+ }
120+
121+ lv_obj_del (obj);
122+ }
123+
111124void clear_tabview (lv_obj_t * tabview, t_gui_state *gui_state) {
112- if (tabview != NULL ) {
113- // first remove events for the tabview
114- lv_obj_remove_event_cb (tabview, tabview_tab_changed_event_cb);
115- lv_obj_remove_event_cb (tabview, tabview_content_is_scrolling_event_cb);
116- // delete tabview
117- lv_obj_del (tabview);
118- tabview = NULL ;
125+ if (tabview == NULL ) {
126+ return ;
119127 }
128+
129+ if (!lv_obj_is_valid (tabview)) {
130+ omote_log_w (" clear_tabview: tabview object is invalid, skipping deletion\n " );
131+ return ;
132+ }
133+
134+ // first remove events for the tabview
135+ lv_obj_remove_event_cb (tabview, tabview_tab_changed_event_cb);
136+ lv_obj_remove_event_cb (tabview, tabview_content_is_scrolling_event_cb);
137+ // delete tabview
138+ lv_obj_del (tabview);
139+ tabview = NULL ;
120140
121141 // the gui_list_index_previous is needed for setGUIlistIndicesToBeShown_afterSlide();
122142 gui_state->gui_on_tab [0 ] = {NULL , " " , -1 , gui_state->gui_on_tab [0 ].gui_list_index };
@@ -126,19 +146,9 @@ void clear_tabview(lv_obj_t* tabview, t_gui_state *gui_state) {
126146}
127147
128148void clear_panel (lv_obj_t * panel, lv_obj_t * img1, lv_obj_t * img2) {
129- if (panel != NULL ) {
130- lv_obj_del (panel);
131- panel = NULL ;
132- }
133- if (img1 != NULL ) {
134- lv_obj_del (img1);
135- img1 = NULL ;
136- }
137- if (img2 != NULL ) {
138- lv_obj_del (img2);
139- img2 = NULL ;
140- }
141-
149+ safe_delete_lv_obj (panel, " panel" );
150+ safe_delete_lv_obj (img1, " img1" );
151+ safe_delete_lv_obj (img2, " img2" );
142152}
143153
144154lv_obj_t * create_tabview () {
@@ -318,6 +328,17 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
318328 #endif
319329 return ;
320330 }
331+
332+ // Check available memory before creating many objects
333+ size_t free_heap = esp_get_free_heap_size ();
334+ if (free_heap < 5000 ) { // Less than 5KB free
335+ omote_log_w (" fillPanelWithPageIndicator: Low memory (%zu bytes), skipping page indicators\n " , free_heap);
336+ lv_obj_add_style (panel, &panel_style, 0 );
337+ #ifdef drawRedBorderAroundMainWidgets
338+ lv_obj_add_style (panel, &style_red_border, LV_PART_MAIN);
339+ #endif
340+ return ;
341+ }
321342
322343 // This small hidden button enables the page indicator to scroll further
323344 lv_obj_t * btn = lv_btn_create (panel);
@@ -409,8 +430,14 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
409430 // create a breadcrump dot for each gui in the main_gui_list
410431 for (int j=0 ; j<breadcrumpMainGuiListLength; j++) {
411432 lv_obj_t * dot = lv_obj_create (btn);
433+ if (dot == NULL ) {
434+ omote_log_e (" fillPanelWithPageIndicator: Failed to create dot object, out of memory\n " );
435+ continue ;
436+ }
437+
412438 lv_obj_set_size (dot, breadcrumpDotSize, breadcrumpDotSize);
413439 lv_obj_set_style_radius (dot, LV_RADIUS_CIRCLE, LV_PART_MAIN);
440+
414441 // hightlight dot if it is the one for the currently active tab
415442 #if (USE_SCENE_SPECIFIC_GUI_LIST != 0)
416443 if ( ((gui_memoryOptimizer_getActiveGUIlist () == MAIN_GUI_LIST) || !get_scene_has_gui_list (gui_memoryOptimizer_getActiveSceneName ()))
@@ -437,6 +464,11 @@ void fillPanelWithPageIndicator_strategyMax3(lv_obj_t* panel, lv_obj_t* img1, lv
437464 if (show_scene_gui_list) {
438465 for (int j=0 ; j<breadcrumpSceneGuiListLength; j++) {
439466 lv_obj_t * dot = lv_obj_create (btn);
467+ if (dot == NULL ) {
468+ omote_log_e (" fillPanelWithPageIndicator: Failed to create scene dot object, out of memory\n " );
469+ continue ;
470+ }
471+
440472 lv_obj_set_size (dot, breadcrumpDotSize, breadcrumpDotSize);
441473 lv_obj_set_style_radius (dot, LV_RADIUS_CIRCLE, LV_PART_MAIN);
442474 if ((gui_memoryOptimizer_getActiveGUIlist () == SCENE_GUI_LIST) && (j == (breadcrumpPosition-1 ))) {
0 commit comments