#include "page_stack.h" #include "esp_log.h" static const char* TAG = "PageStack"; PageStack::PageStack(lv_obj_t* parent_container) : parent_container_(parent_container) { if (!parent_container_) { ESP_LOGE(TAG, "Parent container is null"); } } PageStack::~PageStack() { clear(); } lv_obj_t* PageStack::create_page_container() { lv_obj_t* page = lv_obj_create(parent_container_); // Fill parent container lv_obj_set_size(page, LV_PCT(100), LV_PCT(100)); lv_obj_set_pos(page, 0, 0); // Remove padding and scrollbars lv_obj_set_style_pad_all(page, 0, 0); lv_obj_set_scrollbar_mode(page, LV_SCROLLBAR_MODE_OFF); // White background lv_obj_set_style_bg_color(page, lv_color_white(), 0); lv_obj_set_style_bg_opa(page, LV_OPA_COVER, 0); // Remove border lv_obj_set_style_border_width(page, 0, 0); return page; } lv_obj_t* PageStack::push(PageBuilder builder, PageCleanup cleanup) { if (!parent_container_) { ESP_LOGE(TAG, "Cannot push page: parent container is null"); return nullptr; } if (!builder) { ESP_LOGE(TAG, "Cannot push page: builder is null"); return nullptr; } // Hide current page if any if (!pages_.empty()) { lv_obj_add_flag(pages_.back().container, LV_OBJ_FLAG_HIDDEN); } // Create new page container lv_obj_t* page = create_page_container(); // Build page content builder(page); // Add to stack pages_.push_back({page, cleanup}); ESP_LOGD(TAG, "Pushed page (depth: %d)", pages_.size()); return page; } bool PageStack::pop() { if (pages_.empty()) { ESP_LOGW(TAG, "Cannot pop: stack is empty"); return false; } // Get and remove current page Page current = pages_.back(); pages_.pop_back(); // Call cleanup callback if provided if (current.cleanup) { current.cleanup(current.container); } // Delete page container lv_obj_del(current.container); // Show previous page if any if (!pages_.empty()) { lv_obj_clear_flag(pages_.back().container, LV_OBJ_FLAG_HIDDEN); } ESP_LOGD(TAG, "Popped page (depth: %d)", pages_.size()); return true; } void PageStack::clear() { ESP_LOGD(TAG, "Clearing all pages (depth: %d)", pages_.size()); // Pop all pages (calls cleanup callbacks) while (!pages_.empty()) { Page current = pages_.back(); pages_.pop_back(); if (current.cleanup) { current.cleanup(current.container); } lv_obj_del(current.container); } } lv_obj_t* PageStack::current_page() const { if (pages_.empty()) { return nullptr; } return pages_.back().container; }