/************************************************************** * demo_canvas_virtual_table_pages.c * LVGL 9.3 Canvas Virtual Table Pagination Demo (Fixed Buffer) * Screen: 1024x600 * Visible Rows: 15 * Total Rows: 200 **************************************************************/ #include "lvgl.h" #include #include #define SCREEN_W 1024 #define SCREEN_H 600 #define TOTAL_ROWS 200 #define VISIBLE_ROWS 15 #define HEADER_H 32 #define COL_CNT 6 #define ROW_H 36 /* ===== Dynamic Data for Row 7 ===== */ typedef struct { int vol; int temp; int res; } row_data_t; static row_data_t row7_data = {1,1,601}; /* Canvas Buffer - Pagination Buffer */ #define PAGE_ROWS 50 // Rows per page #define CANVAS_HEIGHT (HEADER_H + PAGE_ROWS * ROW_H) static lv_color_t cbuf[SCREEN_W * CANVAS_HEIGHT]; static lv_obj_t * canvas; static lv_obj_t * scroll_cont; static int current_page = 0; // Current page number, starting from 0 static const float col_ratio[COL_CNT] = {0.06f, 0.12f, 0.14f, 0.14f, 0.12f, 0.42f}; static int col_w[COL_CNT]; static int col_x[COL_CNT]; /* ===== Calculate Column Widths and Start X Positions ===== */ static void calc_col_layout(void) { int total_width = 0; for(int i=0; i TOTAL_ROWS) end_row = TOTAL_ROWS; for(int r=start_row; r= (current_page+1)*PAGE_ROWS) return; lv_layer_t layer; lv_canvas_init_layer(canvas,&layer); lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_init(&rect_dsc); rect_dsc.bg_color = lv_color_white(); rect_dsc.bg_opa = LV_OPA_COVER; rect_dsc.border_width = 0; lv_area_t clear_area = {0, y, SCREEN_W-1, y+ROW_H-1}; lv_draw_rect(&layer, &rect_dsc, &clear_area); lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); label_dsc.color = lv_color_black(); label_dsc.font = LV_FONT_DEFAULT; label_dsc.align = LV_TEXT_ALIGN_CENTER; label_dsc.text_local = true; char buf[32]; for(int c=0;c 0) { new_page = current_page - 1; is_scroll_up = true; // This is scrolling up } } else if(y > ((PAGE_ROWS - VISIBLE_ROWS) * ROW_H) + 50) { // Scroll down beyond bottom: Go to next page int max_page = (TOTAL_ROWS + PAGE_ROWS - 1) / PAGE_ROWS - 1; if(current_page < max_page) { new_page = current_page + 1; is_scroll_up = false; // This is scrolling down } } if(new_page != current_page) { current_page = new_page; lv_canvas_fill_bg(canvas, lv_color_white(), LV_OPA_COVER); draw_canvas_page(canvas, current_page); // Set different scroll positions based on page direction if(is_scroll_up) { // Scroll up: Show bottom of new page (last few rows) lv_obj_set_y(canvas, 0); // Reset canvas position lv_obj_scroll_to(cont, 0, (PAGE_ROWS - VISIBLE_ROWS) * ROW_H, LV_ANIM_OFF); } else { // Scroll down: Show top of new page (first few rows) lv_obj_set_y(canvas, 0); // Reset canvas position lv_obj_scroll_to(cont, 0, 0, LV_ANIM_OFF); } } } /* ===== Main Demo ===== */ void demo_virtual_canvas_pages(void) { calc_col_layout(); lv_obj_t * scr = lv_scr_act(); lv_obj_clean(scr); scroll_cont = lv_obj_create(scr); lv_obj_set_size(scroll_cont, SCREEN_W, SCREEN_H); lv_obj_set_scroll_dir(scroll_cont, LV_DIR_VER); lv_obj_set_scrollbar_mode(scroll_cont, LV_SCROLLBAR_MODE_AUTO); // Scroll callback lv_obj_add_event_cb(scroll_cont, scroll_event_cb, LV_EVENT_SCROLL, NULL); canvas = lv_canvas_create(scroll_cont); lv_canvas_set_buffer(canvas, cbuf, SCREEN_W, CANVAS_HEIGHT, LV_COLOR_FORMAT_RGB565); lv_canvas_fill_bg(canvas, lv_color_white(), LV_OPA_COVER); // Initial page current_page = 0; draw_canvas_page(canvas,current_page); lv_obj_set_pos(canvas,0,0); lv_timer_create(row7_timer_cb,500,NULL); }