#include "ui/ui_handler.h" #include "ui/root_layout.h" #include "ui/app_registry.h" #include "esp_log.h" #define TAG "UIHandler" // Display dimensions from constants.h #define DISPLAY_WIDTH 800 #define DISPLAY_HEIGHT 480 // Layout dimensions #define HEADER_HEIGHT 40 #define NAV_BAR_HEIGHT 50 #define _APP_CONTAINERHEIGHT (DISPLAY_HEIGHT - HEADER_HEIGHT - NAV_BAR_HEIGHT) esp_err_t UIHandler::init(void) { ESP_LOGI(TAG, "Initializing UIHandler"); // Create main screen _main_screen = lv_obj_create(NULL); if (!_main_screen) { ESP_LOGE(TAG, "Failed to create main screen"); return ESP_FAIL; } lv_obj_set_style_bg_color(_main_screen, lv_color_black(), 0); lv_obj_set_size(_main_screen, DISPLAY_WIDTH, DISPLAY_HEIGHT); // Create root layout _root_layout = new RootLayout(this); if (!_root_layout) { ESP_LOGE(TAG, "Failed to allocate RootLayout"); return ESP_FAIL; } if (_root_layout->init(_main_screen) != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize root layout"); delete _root_layout; _root_layout = nullptr; return ESP_FAIL; } // Render app icons from registry if (_root_layout->render_app_icons() != ESP_OK) { ESP_LOGW(TAG, "Failed to render app icons"); } // Load the main screen lv_screen_load(_main_screen); ESP_LOGI(TAG, "UIHandler initialized successfully"); return ESP_OK; } esp_err_t UIHandler::deinit(void) { ESP_LOGI(TAG, "Deinitializing UIHandler"); // Deinit current app if (_active_app) { if (_active_app->deinit() != ESP_OK) { ESP_LOGW(TAG, "Error deinitializing active app: %s", _active_app->get_name()); } _active_app = nullptr; } // Delete shutdown app if cached if (_shutdown_app) { delete _shutdown_app; _shutdown_app = nullptr; } // Clean up root layout if (_root_layout) { _root_layout->deinit(); delete _root_layout; _root_layout = nullptr; } // Main screen will be cleaned up by LVGL _main_screen = nullptr; return ESP_OK; } esp_err_t UIHandler::switch_app(UIApp* app) { if (!app) { ESP_LOGE(TAG, "Cannot switch to null app"); return ESP_ERR_INVALID_ARG; } lv_obj_t* app_container = get_app_container(); if (!app_container) { ESP_LOGE(TAG, "App container not initialized"); return ESP_FAIL; } ESP_LOGI(TAG, "Switching to app: %s", app->get_name()); // Deinit current app if (_active_app) { if (_active_app->deinit() != ESP_OK) { ESP_LOGW(TAG, "Error deinitializing app: %s", _active_app->get_name()); } } // Clear the app container lv_obj_clean(app_container); // Initialize new app if (app->init(app_container) != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize app: %s", app->get_name()); _active_app = nullptr; return ESP_FAIL; } _active_app = app; // Update header through RootLayout if (_root_layout) { _root_layout->update_header(_active_app->get_name()); _root_layout->show_back_button(); } return ESP_OK; } esp_err_t UIHandler::switch_app(AppDescriptor* app_descriptor) { if (!app_descriptor) { ESP_LOGE(TAG, "Cannot switch to null app descriptor"); return ESP_ERR_INVALID_ARG; } UIApp* app = app_descriptor->get_app_instance(); if (!app) { ESP_LOGE(TAG, "App descriptor has null app instance"); return ESP_ERR_INVALID_ARG; } return switch_app(app); } void UIHandler::route_event(uint32_t event_type, void* event_data) { if (_active_app) { _active_app->handle_event(event_type, event_data); } } esp_err_t UIHandler::show_shutdown_screen(std::string message) { ESP_LOGI(TAG, "Showing shutdown screen"); lv_obj_t* app_container = get_app_container(); if (!app_container) { ESP_LOGE(TAG, "App container not initialized"); return ESP_FAIL; } // Clear current app reference _active_app = nullptr; // Clear the app container lv_obj_clean(app_container); // Create shutdown message lv_obj_t* shutdown_label = lv_label_create(app_container); lv_label_set_text(shutdown_label, message.empty() ? "Shutting down..." : message.c_str()); lv_obj_set_style_text_color(shutdown_label, lv_color_white(), 0); lv_obj_align(shutdown_label, LV_ALIGN_CENTER, 0, 0); // Update header through RootLayout if (_root_layout) { _root_layout->update_header("System Shutdown"); } return ESP_OK; } esp_err_t UIHandler::return_to_main_screen(void) { ESP_LOGI(TAG, "Returning to main screen"); // Deinit current app if (_active_app) { if (_active_app->deinit() != ESP_OK) { ESP_LOGW(TAG, "Error deinitializing app: %s", _active_app->get_name()); } _active_app = nullptr; } // Clear the app container lv_obj_t* app_container = get_app_container(); if (app_container) { lv_obj_clean(app_container); } // Update header and hide back button through RootLayout if (_root_layout) { _root_layout->update_header(""); _root_layout->hide_back_button(); } return ESP_OK; }