#pragma once #include "ui_app.h" #include "app_registry.h" #include "root_layout.h" #include "esp_err.h" // Forward declaration class RootLayout; /** * @brief UI Handler - manages app lifecycle and rendering * * The UIHandler manages: * - Creation and destruction of UI apps * - Switching between apps * - Main screen layout (header, app container, navigation bar) * - System event routing to active app * - Displaying special screens (shutdown, etc.) */ class UIHandler { public: /** * @brief Initialize the UI system with default layout * * Creates the main screen with: * - Header area (top) * - App container (middle) * - Navigation bar (bottom) * * @return ESP_OK on success, error code otherwise */ esp_err_t init(void); /** * @brief Deinitialize the UI system * * Cleans up the current app and destroys the main screen. * * @return ESP_OK on success, error code otherwise */ esp_err_t deinit(void); /** * @brief Switch to a new app * * Deinitializes the current app (if any), initializes the new app, * and updates the display. * * @param app Pointer to the new app to switch to * @return ESP_OK on success, error code otherwise */ esp_err_t switch_app(UIApp* app); /** * @brief Switch to an app by its descriptor * * Convenience method that extracts the UIApp from the descriptor * and calls switch_app(). * * @param app_descriptor Pointer to the app descriptor * @return ESP_OK on success, error code otherwise */ esp_err_t switch_app(AppDescriptor* app_descriptor); /** * @brief Get the currently active app * * @return Pointer to the active UIApp, or nullptr if none */ UIApp* get_active_app(void) const { return _active_app; } /** * @brief Route a system event to the active app * * If an app is active, this forwards the event to it. * * @param event_type Type/ID of the event * @param event_data Optional event data payload */ void route_event(uint32_t event_type, void* event_data = nullptr); /** * @brief Display shutdown screen * * Shows a shutdown screen with a message. Typically called * before the system enters deep sleep or powers off. * * @param message Optional message to display (e.g., "Shutting down...") * @return ESP_OK on success, error code otherwise */ esp_err_t show_shutdown_screen(std::string message = ""); /** * @brief Get the main screen object * * @return lv_obj_t* pointer to the main screen */ lv_obj_t* get_main_screen(void) const { return _main_screen; } /** * @brief Get the app container (where apps render) * * @return lv_obj_t* pointer to the app container */ lv_obj_t* get_app_container(void) const { return _root_layout ? _root_layout->get_app_container() : nullptr; } /** * @brief Get the header object * * @return lv_obj_t* pointer to the header container */ lv_obj_t* get_header(void) const { return _root_layout ? _root_layout->get_header() : nullptr; } /** * @brief Get the navigation bar object * * @return lv_obj_t* pointer to the navigation bar container */ lv_obj_t* get_nav_bar(void) const { return _root_layout ? _root_layout->get_nav_bar() : nullptr; } /** * @brief Return to main screen (deinit app and show app icons) * * Deinitializes the active app and displays the app icons * in the navigation bar, returning to the home screen. * * @return ESP_OK on success, error code otherwise */ esp_err_t return_to_main_screen(void); private: lv_obj_t* _main_screen = nullptr; ///< Root screen RootLayout* _root_layout = nullptr; ///< Root layout manager UIApp* _active_app = nullptr; ///< Currently active app UIApp* _shutdown_app = nullptr; ///< Cached shutdown app };