#include "LVGL_Driver.h" #include "SPI_Bus_Lock.h" static lv_disp_draw_buf_t draw_buf; static lv_color_t buf1[LVGL_BUF_LEN]; static lv_color_t buf2[LVGL_BUF_LEN]; static lv_obj_t *status_label = nullptr; static lv_obj_t *list_label = nullptr; static lv_obj_t *network_container = nullptr; static lv_obj_t *network_labels[20] = {nullptr}; static int network_count = 0; static lv_obj_t *progress_bar = nullptr; static lv_obj_t *progress_label = nullptr; void Ui_SetWifiStatus(const char *text) { if (status_label != nullptr) { lv_label_set_text(status_label, text); } } void Ui_ClearNetworkList(void) { if (network_container == nullptr) return; for (int i = 0; i < network_count; i++) { if (network_labels[i] != nullptr) { lv_obj_del(network_labels[i]); network_labels[i] = nullptr; } } network_count = 0; } void Ui_AddNetwork(const char* text, int index) { if (network_container == nullptr || index < 0 || index >= 20) return; if (network_labels[index] != nullptr) { lv_label_set_text(network_labels[index], text); return; } lv_obj_t* label = lv_label_create(network_container); lv_label_set_text(label, text); lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_GREEN), 0); lv_obj_set_style_text_font(label, &lv_font_montserrat_12, 0); lv_obj_set_width(label, lv_pct(100)); network_labels[index] = label; if (index >= network_count) network_count = index + 1; } void Ui_SetNetworkColor(int index, lv_color_t color) { if (index < 0 || index >= 20 || network_labels[index] == nullptr) return; lv_obj_set_style_text_color(network_labels[index], color, 0); } void Ui_SetNetworkText(int index, const char* text) { if (index < 0 || index >= 20 || network_labels[index] == nullptr) return; lv_label_set_text(network_labels[index], text); } void Ui_SetProgress(int current, int total) { if (progress_bar == nullptr) return; if (total <= 0) { lv_bar_set_value(progress_bar, 0, LV_ANIM_OFF); if (progress_label) lv_label_set_text(progress_label, ""); return; } int pct = (current * 100) / total; lv_bar_set_value(progress_bar, pct, LV_ANIM_ON); char buf[16]; snprintf(buf, sizeof(buf), "%d/%d", current, total); if (progress_label) lv_label_set_text(progress_label, buf); } void Ui_ShowProgress(bool visible) { if (progress_bar == nullptr) return; if (visible) { lv_obj_clear_flag(progress_bar, LV_OBJ_FLAG_HIDDEN); if (progress_label) lv_obj_clear_flag(progress_label, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(progress_bar, LV_OBJ_FLAG_HIDDEN); if (progress_label) lv_obj_add_flag(progress_label, LV_OBJ_FLAG_HIDDEN); } } void Lvgl_Display_LCD(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) { LCD_addWindow(area->x1, area->y1, area->x2, area->y2, (uint16_t*)&color_p->full); lv_disp_flush_ready(disp_drv); } void Lvgl_Touchpad_Read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { (void)indev_drv; (void)data; } void example_increase_lvgl_tick(void *arg) { (void)arg; lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS); } void Lvgl_Init(void) { lv_init(); lv_disp_draw_buf_init(&draw_buf, buf1, buf2, LVGL_BUF_LEN); static lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.hor_res = LVGL_WIDTH; disp_drv.ver_res = LVGL_HEIGHT; disp_drv.flush_cb = Lvgl_Display_LCD; disp_drv.full_refresh = 0; disp_drv.draw_buf = &draw_buf; lv_disp_drv_register(&disp_drv); static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = Lvgl_Touchpad_Read; lv_indev_drv_register(&indev_drv); lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), 0); lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_COVER, 0); // Title lv_obj_t *title = lv_label_create(lv_scr_act()); lv_obj_set_style_text_color(title, lv_palette_main(LV_PALETTE_GREEN), 0); lv_obj_set_style_text_font(title, &lv_font_montserrat_16, 0); lv_label_set_text(title, LV_SYMBOL_WIFI " Capture"); lv_obj_align(title, LV_ALIGN_TOP_LEFT, 10, 6); // Status line status_label = lv_label_create(lv_scr_act()); lv_obj_set_style_text_color(status_label, lv_palette_lighten(LV_PALETTE_GREEN, 2), 0); lv_obj_set_style_text_font(status_label, &lv_font_montserrat_12, 0); lv_label_set_text(status_label, "Starting..."); lv_obj_align(status_label, LV_ALIGN_TOP_LEFT, 10, 28); // Progress bar (hidden until capture starts) progress_bar = lv_bar_create(lv_scr_act()); lv_obj_set_size(progress_bar, 114, 6); lv_obj_align(progress_bar, LV_ALIGN_TOP_LEFT, 10, 44); lv_bar_set_range(progress_bar, 0, 100); lv_bar_set_value(progress_bar, 0, LV_ANIM_OFF); lv_obj_set_style_bg_color(progress_bar, lv_color_make(25, 25, 25), LV_PART_MAIN); lv_obj_set_style_bg_opa(progress_bar, LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_color(progress_bar, lv_palette_main(LV_PALETTE_GREEN), LV_PART_INDICATOR); lv_obj_set_style_bg_opa(progress_bar, LV_OPA_COVER, LV_PART_INDICATOR); lv_obj_set_style_radius(progress_bar, 2, LV_PART_MAIN); lv_obj_set_style_radius(progress_bar, 2, LV_PART_INDICATOR); lv_obj_add_flag(progress_bar, LV_OBJ_FLAG_HIDDEN); // Progress count label (right of bar) progress_label = lv_label_create(lv_scr_act()); lv_obj_set_style_text_color(progress_label, lv_palette_main(LV_PALETTE_GREEN), 0); lv_obj_set_style_text_font(progress_label, &lv_font_montserrat_12, 0); lv_label_set_text(progress_label, ""); lv_obj_align(progress_label, LV_ALIGN_TOP_LEFT, 130, 41); lv_obj_add_flag(progress_label, LV_OBJ_FLAG_HIDDEN); // Network list panel lv_obj_t *list_panel = lv_obj_create(lv_scr_act()); lv_obj_set_size(list_panel, 164, 254); lv_obj_align(list_panel, LV_ALIGN_TOP_LEFT, 4, 54); lv_obj_set_style_bg_color(list_panel, lv_color_black(), 0); lv_obj_set_style_bg_opa(list_panel, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(list_panel, 1, 0); lv_obj_set_style_border_color(list_panel, lv_palette_darken(LV_PALETTE_GREEN, 2), 0); lv_obj_set_style_pad_all(list_panel, 6, 0); lv_obj_set_scrollbar_mode(list_panel, LV_SCROLLBAR_MODE_OFF); network_container = lv_obj_create(list_panel); lv_obj_set_size(network_container, lv_pct(100), lv_pct(100)); lv_obj_set_flex_flow(network_container, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(network_container, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_clear_flag(network_container, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_pad_all(network_container, 0, 0); lv_obj_set_style_border_width(network_container, 0, 0); lv_obj_set_style_bg_opa(network_container, LV_OPA_TRANSP, 0); list_label = lv_label_create(list_panel); lv_obj_set_width(list_label, lv_pct(100)); lv_label_set_text(list_label, ""); lv_obj_add_flag(list_label, LV_OBJ_FLAG_HIDDEN); const esp_timer_create_args_t lvgl_tick_timer_args = { .callback = &example_increase_lvgl_tick, .name = "lvgl_tick" }; esp_timer_handle_t lvgl_tick_timer = NULL; esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer); esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000); } void Timer_Loop(void) { if (SPIBus_IsDisplayPaused()) return; lv_timer_handler(); }