202 lines
4.8 KiB
C++
202 lines
4.8 KiB
C++
#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;
|
|
}
|