/***************************************************************************** | File : LVGL_Driver.c | help : The provided LVGL library file must be installed first ******************************************************************************/ #include "LVGL_Driver.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; // kept for backward compatibility static lv_obj_t *network_container = nullptr; static lv_obj_t *network_labels[20] = {nullptr}; static int network_count = 0; // static lv_color_t* buf1 = (lv_color_t*) heap_caps_malloc(LVGL_BUF_LEN, MALLOC_CAP_SPIRAM); // static lv_color_t* buf2 = (lv_color_t*) heap_caps_malloc(LVGL_BUF_LEN, MALLOC_CAP_SPIRAM); /* Serial debugging */ void Lvgl_print(const char * buf) { // Serial.printf(buf); // Serial.flush(); } void Ui_SetWifiStatus(const char *text) { if (status_label != nullptr) { lv_label_set_text(status_label, text); } } void Ui_SetWifiList(const char *text) { if (list_label != nullptr) { lv_label_set_text(list_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); } /* Display flushing Displays LVGL content on the LCD This function implements associating LVGL data to the LCD screen */ 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 ); } /*Read the touchpad*/ void Lvgl_Touchpad_Read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data ) { // NULL } void example_increase_lvgl_tick(void *arg) { /* Tell LVGL how many milliseconds has elapsed */ 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); /*Initialize the display*/ static lv_disp_drv_t disp_drv; lv_disp_drv_init( &disp_drv ); /*Change the following line to your display resolution*/ 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 ); /*Initialize the (dummy) input device driver*/ 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); 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, "WiFi Networks"); lv_obj_align(title, LV_ALIGN_TOP_LEFT, 10, 8); 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 scan..."); lv_obj_align(status_label, LV_ALIGN_TOP_LEFT, 10, 30); lv_obj_t *list_panel = lv_obj_create(lv_scr_act()); lv_obj_set_size(list_panel, 164, 260); lv_obj_align(list_panel, LV_ALIGN_TOP_LEFT, 4, 52); 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); // Container for network labels 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); // Keep list_label for backward compatibility (hidden) list_label = lv_label_create(list_panel); lv_obj_set_width(list_label, lv_pct(100)); lv_obj_set_style_text_color(list_label, lv_palette_main(LV_PALETTE_GREEN), 0); lv_obj_set_style_text_font(list_label, &lv_font_montserrat_12, 0); lv_label_set_long_mode(list_label, LV_LABEL_LONG_WRAP); 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) { lv_timer_handler(); /* let the GUI do its work */ // delay( 5 ); }