1 #include "../lv_examples.h"
2 #if LV_BUILD_EXAMPLES && LV_USE_FLEX
3 
4 static lv_obj_t * high_label;
5 static lv_obj_t * low_label;
6 static int32_t top_num;
7 static int32_t bottom_num;
8 static bool update_scroll_running = false;
9 
load_item(lv_obj_t * parent,int32_t num)10 static lv_obj_t * load_item(lv_obj_t * parent, int32_t num)
11 {
12     lv_obj_t * new = lv_obj_create(parent);
13     lv_obj_set_size(new, LV_PCT(100), LV_SIZE_CONTENT);
14     lv_obj_t * label = lv_label_create(new);
15     lv_label_set_text_fmt(label, "%"PRId32, num);
16     return new;
17 }
18 
update_scroll(lv_obj_t * obj)19 static void update_scroll(lv_obj_t * obj)
20 {
21     /* do not re-enter this function when `lv_obj_scroll_by`
22      * triggers this callback again.
23      */
24     if(update_scroll_running) return;
25     update_scroll_running = true;
26 
27     int32_t top_num_original = top_num;
28     int32_t bottom_num_original = bottom_num;
29 
30     /* load items we're getting close to */
31     while(bottom_num > -30 && lv_obj_get_scroll_bottom(obj) < 200) {
32         bottom_num -= 1;
33         load_item(obj, bottom_num);
34         lv_obj_update_layout(obj);
35         LV_LOG_USER("loaded bottom num: %"PRId32, bottom_num);
36     }
37     while(top_num < 30 && lv_obj_get_scroll_top(obj) < 200) {
38         top_num += 1;
39         int32_t bottom_before = lv_obj_get_scroll_bottom(obj);
40         lv_obj_t * new_item = load_item(obj, top_num);
41         lv_obj_move_to_index(new_item, 0);
42         lv_obj_update_layout(obj);
43         int32_t bottom_after = lv_obj_get_scroll_bottom(obj);
44         lv_obj_scroll_by(obj, 0, bottom_before - bottom_after, LV_ANIM_OFF);
45         LV_LOG_USER("loaded top num: %"PRId32, top_num);
46     }
47 
48     /* delete far-away items */
49     while(lv_obj_get_scroll_bottom(obj) > 600) {
50         bottom_num += 1;
51         lv_obj_t * child = lv_obj_get_child(obj, -1);
52         lv_obj_delete(child);
53         lv_obj_update_layout(obj);
54         LV_LOG_USER("deleted bottom num: %"PRId32, bottom_num);
55     }
56     while(lv_obj_get_scroll_top(obj) > 600) {
57         top_num -= 1;
58         int32_t bottom_before = lv_obj_get_scroll_bottom(obj);
59         lv_obj_t * child = lv_obj_get_child(obj, 0);
60         lv_obj_delete(child);
61         lv_obj_update_layout(obj);
62         int32_t bottom_after = lv_obj_get_scroll_bottom(obj);
63         lv_obj_scroll_by(obj, 0, bottom_before - bottom_after, LV_ANIM_OFF);
64         LV_LOG_USER("deleted top num: %"PRId32, top_num);
65     }
66 
67     if(top_num != top_num_original) {
68         lv_label_set_text_fmt(high_label, "current largest\nloaded value:\n%"PRId32, top_num);
69     }
70     if(bottom_num != bottom_num_original) {
71         lv_label_set_text_fmt(low_label, "current smallest\nloaded value:\n%"PRId32, bottom_num);
72     }
73 
74     update_scroll_running = false;
75 }
76 
scroll_cb(lv_event_t * e)77 static void scroll_cb(lv_event_t * e)
78 {
79     lv_obj_t * obj = lv_event_get_target_obj(e);
80     update_scroll(obj);
81 }
82 
checkbox_cb(lv_event_t * e)83 static void checkbox_cb(lv_event_t * e)
84 {
85     lv_obj_t * checkbox = lv_event_get_target_obj(e);
86     lv_obj_t * obj = lv_event_get_user_data(e);
87     bool checked = lv_obj_has_state(checkbox, LV_STATE_CHECKED);
88     lv_obj_set_style_opa(obj, checked ? LV_OPA_COVER : LV_OPA_TRANSP, LV_PART_SCROLLBAR);
89 }
90 
91 /**
92  * Dynamically load widgets while scrolling
93  */
lv_example_scroll_7(void)94 void lv_example_scroll_7(void)
95 {
96     lv_obj_t * scr = lv_screen_active();
97     lv_obj_t * obj = lv_obj_create(scr);
98     lv_obj_set_size(obj, 160, 220);
99     lv_obj_align(obj, LV_ALIGN_RIGHT_MID, -10, 0);
100     lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
101     lv_obj_set_style_opa(obj, LV_OPA_TRANSP, LV_PART_SCROLLBAR);
102 
103     high_label = lv_label_create(scr);
104     lv_label_set_text_static(high_label, "current largest\nloaded value:");
105     lv_obj_align(high_label, LV_ALIGN_TOP_LEFT, 10, 10);
106 
107     lv_obj_t * checkbox = lv_checkbox_create(scr);
108     lv_checkbox_set_text_static(checkbox, "show\nscrollbar");
109     lv_obj_align(checkbox, LV_ALIGN_LEFT_MID, 10, 0);
110     lv_obj_add_event_cb(checkbox, checkbox_cb, LV_EVENT_VALUE_CHANGED, obj);
111 
112     low_label = lv_label_create(scr);
113     lv_label_set_text_static(low_label, "current smallest\nloaded value:");
114     lv_obj_align(low_label, LV_ALIGN_BOTTOM_LEFT, 10, -10);
115 
116     load_item(obj, 3);
117     /* These counters hold the the highest/lowest number currently loaded. */
118     top_num = 3;
119     bottom_num = 3;
120 
121     lv_obj_update_layout(obj);
122     update_scroll(obj);
123     lv_obj_add_event_cb(obj, scroll_cb, LV_EVENT_SCROLL, NULL);
124 }
125 
126 #endif
127