add some code
This commit is contained in:
43
managed_components/lvgl__lvgl/examples/scroll/index.rst
Normal file
43
managed_components/lvgl__lvgl/examples/scroll/index.rst
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
Nested scrolling
|
||||
----------------
|
||||
|
||||
.. lv_example:: scroll/lv_example_scroll_1
|
||||
:language: c
|
||||
|
||||
Snapping
|
||||
--------
|
||||
.. lv_example:: scroll/lv_example_scroll_2
|
||||
:language: c
|
||||
|
||||
Floating button
|
||||
----------------
|
||||
.. lv_example:: scroll/lv_example_scroll_3
|
||||
:language: c
|
||||
|
||||
Styling the scrollbars
|
||||
----------------------
|
||||
.. lv_example:: scroll/lv_example_scroll_4
|
||||
:language: c
|
||||
|
||||
Right to left scrolling
|
||||
-----------------------
|
||||
.. lv_example:: scroll/lv_example_scroll_5
|
||||
:language: c
|
||||
|
||||
Translate on scroll
|
||||
-------------------
|
||||
.. lv_example:: scroll/lv_example_scroll_6
|
||||
:language: c
|
||||
|
||||
Infinite scrolling
|
||||
------------------
|
||||
.. lv_example:: scroll/lv_example_scroll_7
|
||||
:language: c
|
||||
|
||||
circular scrolling
|
||||
------------------
|
||||
.. lv_example:: scroll/lv_example_scroll_8
|
||||
:language: c
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @file lv_example_scroll.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EXAMPLE_SCROLL_H
|
||||
#define LV_EXAMPLE_SCROLL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_example_scroll_1(void);
|
||||
void lv_example_scroll_2(void);
|
||||
void lv_example_scroll_3(void);
|
||||
void lv_example_scroll_4(void);
|
||||
void lv_example_scroll_5(void);
|
||||
void lv_example_scroll_6(void);
|
||||
void lv_example_scroll_7(void);
|
||||
void lv_example_scroll_8(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_EXAMPLE_SCROLL_H*/
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES
|
||||
|
||||
static lv_obj_t * panel;
|
||||
static lv_obj_t * save_button;
|
||||
static lv_obj_t * restore_button;
|
||||
static int saved_scroll_x;
|
||||
static int saved_scroll_y;
|
||||
|
||||
static void scroll_update_cb(lv_event_t * e);
|
||||
static void button_event_cb(lv_event_t * e);
|
||||
|
||||
static void scroll_update_cb(lv_event_t * e)
|
||||
{
|
||||
LV_UNUSED(e);
|
||||
|
||||
LV_LOG("scroll info: x:%3" LV_PRId32", y:%3" LV_PRId32", top:%3" LV_PRId32", "
|
||||
"bottom:%3" LV_PRId32", left:%3" LV_PRId32", right:%3" LV_PRId32"\n",
|
||||
lv_obj_get_scroll_x(panel),
|
||||
lv_obj_get_scroll_y(panel),
|
||||
lv_obj_get_scroll_top(panel),
|
||||
lv_obj_get_scroll_bottom(panel),
|
||||
lv_obj_get_scroll_left(panel),
|
||||
lv_obj_get_scroll_right(panel)
|
||||
);
|
||||
}
|
||||
|
||||
static void button_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * obj = lv_event_get_target_obj(e);
|
||||
|
||||
if(obj == save_button) {
|
||||
saved_scroll_x = lv_obj_get_scroll_x(panel);
|
||||
saved_scroll_y = lv_obj_get_scroll_y(panel);
|
||||
}
|
||||
else {
|
||||
lv_obj_scroll_to(panel, saved_scroll_x, saved_scroll_y, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Demonstrate how scrolling appears automatically
|
||||
*/
|
||||
void lv_example_scroll_1(void)
|
||||
{
|
||||
/*Create an object with the new style*/
|
||||
lv_obj_t * scr;
|
||||
scr = lv_screen_active();
|
||||
panel = lv_obj_create(scr);
|
||||
lv_obj_set_size(panel, 200, 200);
|
||||
lv_obj_align(panel, LV_ALIGN_CENTER, 44, 0);
|
||||
|
||||
lv_obj_t * child;
|
||||
lv_obj_t * label;
|
||||
|
||||
child = lv_obj_create(panel);
|
||||
lv_obj_set_pos(child, 0, 0);
|
||||
lv_obj_set_size(child, 70, 70);
|
||||
label = lv_label_create(child);
|
||||
lv_label_set_text(label, "Zero");
|
||||
lv_obj_center(label);
|
||||
|
||||
child = lv_obj_create(panel);
|
||||
lv_obj_set_pos(child, 160, 80);
|
||||
lv_obj_set_size(child, 80, 80);
|
||||
|
||||
lv_obj_t * child2 = lv_button_create(child);
|
||||
lv_obj_set_size(child2, 100, 50);
|
||||
|
||||
label = lv_label_create(child2);
|
||||
lv_label_set_text(label, "Right");
|
||||
lv_obj_center(label);
|
||||
|
||||
child = lv_obj_create(panel);
|
||||
lv_obj_set_pos(child, 40, 160);
|
||||
lv_obj_set_size(child, 100, 70);
|
||||
label = lv_label_create(child);
|
||||
lv_label_set_text(label, "Bottom");
|
||||
lv_obj_center(label);
|
||||
|
||||
/* When LV_OBJ_FLAG_SCROLL_ELASTIC is cleared, scrolling does not go past edge bounaries. */
|
||||
/* lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLL_ELASTIC); */
|
||||
|
||||
/* Call `scroll_update_cb` while panel is being scrolled. */
|
||||
lv_obj_add_event_cb(panel, scroll_update_cb, LV_EVENT_SCROLL, NULL);
|
||||
|
||||
/* Set up buttons that save and restore scroll position. */
|
||||
save_button = lv_button_create(scr);
|
||||
restore_button = lv_button_create(scr);
|
||||
lv_obj_t * lbl;
|
||||
lbl = lv_label_create(save_button);
|
||||
lv_label_set_text_static(lbl, "Save");
|
||||
lbl = lv_label_create(restore_button);
|
||||
lv_label_set_text_static(lbl, "Restore");
|
||||
lv_obj_align_to(save_button, panel, LV_ALIGN_OUT_LEFT_MID, -10, -20);
|
||||
lv_obj_align_to(restore_button, panel, LV_ALIGN_OUT_LEFT_MID, -10, 20);
|
||||
lv_obj_add_event_cb(save_button, button_event_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_event_cb(restore_button, button_event_cb, LV_EVENT_CLICKED, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
|
||||
|
||||
static void sw_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * sw = lv_event_get_target_obj(e);
|
||||
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
lv_obj_t * list = (lv_obj_t *) lv_event_get_user_data(e);
|
||||
|
||||
if(lv_obj_has_state(sw, LV_STATE_CHECKED)) lv_obj_add_flag(list, LV_OBJ_FLAG_SCROLL_ONE);
|
||||
else lv_obj_remove_flag(list, LV_OBJ_FLAG_SCROLL_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an example to scroll snap
|
||||
*/
|
||||
void lv_example_scroll_2(void)
|
||||
{
|
||||
lv_obj_t * panel = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(panel, 280, 120);
|
||||
lv_obj_set_scroll_snap_x(panel, LV_SCROLL_SNAP_CENTER);
|
||||
lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 20);
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < 10; i++) {
|
||||
lv_obj_t * btn = lv_button_create(panel);
|
||||
lv_obj_set_size(btn, 150, lv_pct(100));
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn);
|
||||
if(i == 3) {
|
||||
lv_label_set_text_fmt(label, "Panel %" LV_PRIu32"\nno snap", i);
|
||||
lv_obj_remove_flag(btn, LV_OBJ_FLAG_SNAPPABLE);
|
||||
}
|
||||
else {
|
||||
lv_label_set_text_fmt(label, "Panel %" LV_PRIu32, i);
|
||||
}
|
||||
|
||||
lv_obj_center(label);
|
||||
}
|
||||
lv_obj_update_snap(panel, LV_ANIM_ON);
|
||||
|
||||
#if LV_USE_SWITCH
|
||||
/*Switch between "One scroll" and "Normal scroll" mode*/
|
||||
lv_obj_t * sw = lv_switch_create(lv_screen_active());
|
||||
lv_obj_align(sw, LV_ALIGN_TOP_RIGHT, -20, 10);
|
||||
lv_obj_add_event_cb(sw, sw_event_cb, LV_EVENT_ALL, panel);
|
||||
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(label, "One scroll");
|
||||
lv_obj_align_to(label, sw, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_LIST
|
||||
|
||||
static uint32_t btn_cnt = 1;
|
||||
|
||||
static void float_button_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * float_btn = lv_event_get_target_obj(e);
|
||||
|
||||
if(code == LV_EVENT_CLICKED) {
|
||||
lv_obj_t * list = (lv_obj_t *) lv_event_get_user_data(e);
|
||||
char buf[32];
|
||||
lv_snprintf(buf, sizeof(buf), "Track %d", (int)btn_cnt);
|
||||
lv_obj_t * list_btn = lv_list_add_button(list, LV_SYMBOL_AUDIO, buf);
|
||||
btn_cnt++;
|
||||
|
||||
lv_obj_move_foreground(float_btn);
|
||||
|
||||
lv_obj_scroll_to_view(list_btn, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list with a floating button
|
||||
*/
|
||||
void lv_example_scroll_3(void)
|
||||
{
|
||||
lv_obj_t * list = lv_list_create(lv_screen_active());
|
||||
lv_obj_set_size(list, 280, 220);
|
||||
lv_obj_center(list);
|
||||
|
||||
for(btn_cnt = 1; btn_cnt <= 2; btn_cnt++) {
|
||||
char buf[32];
|
||||
lv_snprintf(buf, sizeof(buf), "Track %d", (int)btn_cnt);
|
||||
lv_list_add_button(list, LV_SYMBOL_AUDIO, buf);
|
||||
}
|
||||
|
||||
lv_obj_t * float_btn = lv_button_create(list);
|
||||
lv_obj_set_size(float_btn, 50, 50);
|
||||
lv_obj_add_flag(float_btn, LV_OBJ_FLAG_FLOATING);
|
||||
lv_obj_align(float_btn, LV_ALIGN_BOTTOM_RIGHT, 0, -lv_obj_get_style_pad_right(list, LV_PART_MAIN));
|
||||
lv_obj_add_event_cb(float_btn, float_button_event_cb, LV_EVENT_ALL, list);
|
||||
lv_obj_set_style_radius(float_btn, LV_RADIUS_CIRCLE, 0);
|
||||
lv_obj_set_style_bg_image_src(float_btn, LV_SYMBOL_PLUS, 0);
|
||||
lv_obj_set_style_text_font(float_btn, lv_theme_get_font_large(float_btn), 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_LIST
|
||||
|
||||
/**
|
||||
* Styling the scrollbars
|
||||
*/
|
||||
void lv_example_scroll_4(void)
|
||||
{
|
||||
lv_obj_t * obj = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(obj, 200, 100);
|
||||
lv_obj_center(obj);
|
||||
|
||||
lv_obj_t * label = lv_label_create(obj);
|
||||
lv_label_set_text(label,
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
|
||||
"Etiam dictum, tortor vestibulum lacinia laoreet, mi neque consectetur neque, vel mattis odio dolor egestas ligula. \n"
|
||||
"Sed vestibulum sapien nulla, id convallis ex porttitor nec. \n"
|
||||
"Duis et massa eu libero accumsan faucibus a in arcu. \n"
|
||||
"Ut pulvinar odio lorem, vel tempus turpis condimentum quis. Nam consectetur condimentum sem in auctor. \n"
|
||||
"Sed nisl augue, venenatis in blandit et, gravida ac tortor. \n"
|
||||
"Etiam dapibus elementum suscipit. \n"
|
||||
"Proin mollis sollicitudin convallis. \n"
|
||||
"Integer dapibus tempus arcu nec viverra. \n"
|
||||
"Donec molestie nulla enim, eu interdum velit placerat quis. \n"
|
||||
"Donec id efficitur risus, at molestie turpis. \n"
|
||||
"Suspendisse vestibulum consectetur nunc ut commodo. \n"
|
||||
"Fusce molestie rhoncus nisi sit amet tincidunt. \n"
|
||||
"Suspendisse a nunc ut magna ornare volutpat.");
|
||||
|
||||
/*Remove the style of scrollbar to have clean start*/
|
||||
lv_obj_remove_style(obj, NULL, LV_PART_SCROLLBAR | LV_STATE_ANY);
|
||||
|
||||
/*Create a transition the animate the some properties on state change*/
|
||||
static const lv_style_prop_t props[] = {LV_STYLE_BG_OPA, LV_STYLE_WIDTH, 0};
|
||||
static lv_style_transition_dsc_t trans;
|
||||
lv_style_transition_dsc_init(&trans, props, lv_anim_path_linear, 200, 0, NULL);
|
||||
|
||||
/*Create a style for the scrollbars*/
|
||||
static lv_style_t style;
|
||||
lv_style_init(&style);
|
||||
lv_style_set_width(&style, 4); /*Width of the scrollbar*/
|
||||
lv_style_set_length(&style, 20); /*Length of the scrollbar*/
|
||||
lv_style_set_pad_right(&style, 5); /*Space from the parallel side*/
|
||||
lv_style_set_pad_top(&style, 5); /*Space from the perpendicular side*/
|
||||
|
||||
lv_style_set_radius(&style, 2);
|
||||
lv_style_set_bg_opa(&style, LV_OPA_70);
|
||||
lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_BLUE));
|
||||
lv_style_set_border_color(&style, lv_palette_darken(LV_PALETTE_BLUE, 3));
|
||||
lv_style_set_border_width(&style, 2);
|
||||
lv_style_set_shadow_width(&style, 8);
|
||||
lv_style_set_shadow_spread(&style, 2);
|
||||
lv_style_set_shadow_color(&style, lv_palette_darken(LV_PALETTE_BLUE, 1));
|
||||
|
||||
lv_style_set_transition(&style, &trans);
|
||||
|
||||
/*Make the scrollbars wider and use 100% opacity when scrolled*/
|
||||
static lv_style_t style_scrolled;
|
||||
lv_style_init(&style_scrolled);
|
||||
lv_style_set_width(&style_scrolled, 8);
|
||||
lv_style_set_bg_opa(&style_scrolled, LV_OPA_COVER);
|
||||
|
||||
lv_obj_add_style(obj, &style, LV_PART_SCROLLBAR);
|
||||
lv_obj_add_style(obj, &style_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_FONT_DEJAVU_16_PERSIAN_HEBREW
|
||||
|
||||
/**
|
||||
* Scrolling with Right To Left base direction
|
||||
*/
|
||||
void lv_example_scroll_5(void)
|
||||
{
|
||||
lv_obj_t * obj = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_style_base_dir(obj, LV_BASE_DIR_RTL, 0);
|
||||
lv_obj_set_size(obj, 200, 100);
|
||||
lv_obj_center(obj);
|
||||
|
||||
lv_obj_t * label = lv_label_create(obj);
|
||||
lv_label_set_text(label,
|
||||
"میکروکُنترولر (به انگلیسی: Microcontroller) گونهای ریزپردازنده است که دارای حافظهٔ دسترسی تصادفی (RAM) و حافظهٔ فقطخواندنی (ROM)، تایمر، پورتهای ورودی و خروجی (I/O) و درگاه ترتیبی (Serial Port پورت سریال)، درون خود تراشه است، و میتواند به تنهایی ابزارهای دیگر را کنترل کند. به عبارت دیگر یک میکروکنترلر، مدار مجتمع کوچکی است که از یک CPU کوچک و اجزای دیگری مانند تایمر، درگاههای ورودی و خروجی آنالوگ و دیجیتال و حافظه تشکیل شدهاست.");
|
||||
lv_obj_set_width(label, 400);
|
||||
lv_obj_set_style_text_font(label, &lv_font_dejavu_16_persian_hebrew, 0);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
|
||||
|
||||
static void scroll_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * cont = lv_event_get_target_obj(e);
|
||||
|
||||
lv_area_t cont_a;
|
||||
lv_obj_get_coords(cont, &cont_a);
|
||||
int32_t cont_y_center = cont_a.y1 + lv_area_get_height(&cont_a) / 2;
|
||||
|
||||
int32_t r = lv_obj_get_height(cont) * 7 / 10;
|
||||
int32_t i;
|
||||
int32_t child_cnt = (int32_t)lv_obj_get_child_count(cont);
|
||||
for(i = 0; i < child_cnt; i++) {
|
||||
lv_obj_t * child = lv_obj_get_child(cont, i);
|
||||
lv_area_t child_a;
|
||||
lv_obj_get_coords(child, &child_a);
|
||||
|
||||
int32_t child_y_center = child_a.y1 + lv_area_get_height(&child_a) / 2;
|
||||
|
||||
int32_t diff_y = child_y_center - cont_y_center;
|
||||
diff_y = LV_ABS(diff_y);
|
||||
|
||||
/*Get the x of diff_y on a circle.*/
|
||||
int32_t x;
|
||||
/*If diff_y is out of the circle use the last point of the circle (the radius)*/
|
||||
if(diff_y >= r) {
|
||||
x = r;
|
||||
}
|
||||
else {
|
||||
/*Use Pythagoras theorem to get x from radius and y*/
|
||||
uint32_t x_sqr = r * r - diff_y * diff_y;
|
||||
lv_sqrt_res_t res;
|
||||
lv_sqrt(x_sqr, &res, 0x8000); /*Use lvgl's built in sqrt root function*/
|
||||
x = r - res.i;
|
||||
}
|
||||
|
||||
/*Translate the item by the calculated X coordinate*/
|
||||
lv_obj_set_style_translate_x(child, x, 0);
|
||||
|
||||
/*Use some opacity with larger translations*/
|
||||
lv_opa_t opa = (lv_opa_t)lv_map(x, 0, r, LV_OPA_TRANSP, LV_OPA_COVER);
|
||||
lv_obj_set_style_opa(child, LV_OPA_COVER - opa, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the object as they scroll
|
||||
*/
|
||||
void lv_example_scroll_6(void)
|
||||
{
|
||||
lv_obj_t * cont = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(cont, 200, 200);
|
||||
lv_obj_center(cont);
|
||||
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_add_event_cb(cont, scroll_event_cb, LV_EVENT_SCROLL, NULL);
|
||||
lv_obj_set_style_radius(cont, LV_RADIUS_CIRCLE, 0);
|
||||
lv_obj_set_style_clip_corner(cont, true, 0);
|
||||
lv_obj_set_scroll_dir(cont, LV_DIR_VER);
|
||||
lv_obj_set_scroll_snap_y(cont, LV_SCROLL_SNAP_CENTER);
|
||||
lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < 20; i++) {
|
||||
lv_obj_t * btn = lv_button_create(cont);
|
||||
lv_obj_set_width(btn, lv_pct(100));
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn);
|
||||
lv_label_set_text_fmt(label, "Button %" LV_PRIu32, i);
|
||||
}
|
||||
|
||||
/*Update the buttons position manually for first*/
|
||||
lv_obj_send_event(cont, LV_EVENT_SCROLL, NULL);
|
||||
|
||||
/*Be sure the fist button is in the middle*/
|
||||
lv_obj_scroll_to_view(lv_obj_get_child(cont, 0), LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
|
||||
|
||||
static lv_obj_t * high_label;
|
||||
static lv_obj_t * low_label;
|
||||
static int32_t top_num;
|
||||
static int32_t bottom_num;
|
||||
static bool update_scroll_running = false;
|
||||
|
||||
static lv_obj_t * load_item(lv_obj_t * parent, int32_t num)
|
||||
{
|
||||
lv_obj_t * obj = (lv_obj_t *) lv_obj_create(parent);
|
||||
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_t * label = lv_label_create(obj);
|
||||
lv_label_set_text_fmt(label, "%" PRId32, num);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void update_scroll(lv_obj_t * obj)
|
||||
{
|
||||
/* do not re-enter this function when `lv_obj_scroll_by`
|
||||
* triggers this callback again.
|
||||
*/
|
||||
if(update_scroll_running) return;
|
||||
update_scroll_running = true;
|
||||
|
||||
int32_t top_num_original = top_num;
|
||||
int32_t bottom_num_original = bottom_num;
|
||||
|
||||
/* load items we're getting close to */
|
||||
while(bottom_num > -30 && lv_obj_get_scroll_bottom(obj) < 200) {
|
||||
bottom_num -= 1;
|
||||
load_item(obj, bottom_num);
|
||||
lv_obj_update_layout(obj);
|
||||
LV_LOG_USER("loaded bottom num: %" PRId32, bottom_num);
|
||||
}
|
||||
while(top_num < 30 && lv_obj_get_scroll_top(obj) < 200) {
|
||||
top_num += 1;
|
||||
int32_t bottom_before = lv_obj_get_scroll_bottom(obj);
|
||||
lv_obj_t * new_item = load_item(obj, top_num);
|
||||
lv_obj_move_to_index(new_item, 0);
|
||||
lv_obj_update_layout(obj);
|
||||
int32_t bottom_after = lv_obj_get_scroll_bottom(obj);
|
||||
lv_obj_scroll_by(obj, 0, bottom_before - bottom_after, LV_ANIM_OFF);
|
||||
LV_LOG_USER("loaded top num: %" PRId32, top_num);
|
||||
}
|
||||
|
||||
/* delete far-away items */
|
||||
while(lv_obj_get_scroll_bottom(obj) > 600) {
|
||||
bottom_num += 1;
|
||||
lv_obj_t * child = lv_obj_get_child(obj, -1);
|
||||
lv_obj_delete(child);
|
||||
lv_obj_update_layout(obj);
|
||||
LV_LOG_USER("deleted bottom num: %" PRId32, bottom_num);
|
||||
}
|
||||
while(lv_obj_get_scroll_top(obj) > 600) {
|
||||
top_num -= 1;
|
||||
int32_t bottom_before = lv_obj_get_scroll_bottom(obj);
|
||||
lv_obj_t * child = lv_obj_get_child(obj, 0);
|
||||
lv_obj_delete(child);
|
||||
lv_obj_update_layout(obj);
|
||||
int32_t bottom_after = lv_obj_get_scroll_bottom(obj);
|
||||
lv_obj_scroll_by(obj, 0, bottom_before - bottom_after, LV_ANIM_OFF);
|
||||
LV_LOG_USER("deleted top num: %" PRId32, top_num);
|
||||
}
|
||||
|
||||
if(top_num != top_num_original) {
|
||||
lv_label_set_text_fmt(high_label, "current largest\nloaded value:\n%" PRId32, top_num);
|
||||
}
|
||||
if(bottom_num != bottom_num_original) {
|
||||
lv_label_set_text_fmt(low_label, "current smallest\nloaded value:\n%" PRId32, bottom_num);
|
||||
}
|
||||
|
||||
update_scroll_running = false;
|
||||
}
|
||||
|
||||
static void scroll_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * obj = lv_event_get_target_obj(e);
|
||||
update_scroll(obj);
|
||||
}
|
||||
|
||||
static void checkbox_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * checkbox = lv_event_get_target_obj(e);
|
||||
lv_obj_t * obj = (lv_obj_t *) lv_event_get_user_data(e);
|
||||
bool checked = lv_obj_has_state(checkbox, LV_STATE_CHECKED);
|
||||
lv_obj_set_style_opa(obj, checked ? LV_OPA_COVER : LV_OPA_TRANSP, LV_PART_SCROLLBAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically load widgets while scrolling
|
||||
*/
|
||||
void lv_example_scroll_7(void)
|
||||
{
|
||||
lv_obj_t * scr = lv_screen_active();
|
||||
lv_obj_t * obj = lv_obj_create(scr);
|
||||
lv_obj_set_size(obj, 160, 220);
|
||||
lv_obj_align(obj, LV_ALIGN_RIGHT_MID, -10, 0);
|
||||
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_style_opa(obj, LV_OPA_TRANSP, LV_PART_SCROLLBAR);
|
||||
|
||||
high_label = lv_label_create(scr);
|
||||
lv_label_set_text_static(high_label, "current largest\nloaded value:");
|
||||
lv_obj_align(high_label, LV_ALIGN_TOP_LEFT, 10, 10);
|
||||
|
||||
lv_obj_t * checkbox = lv_checkbox_create(scr);
|
||||
lv_checkbox_set_text_static(checkbox, "show\nscrollbar");
|
||||
lv_obj_align(checkbox, LV_ALIGN_LEFT_MID, 10, 0);
|
||||
lv_obj_add_event_cb(checkbox, checkbox_cb, LV_EVENT_VALUE_CHANGED, obj);
|
||||
|
||||
low_label = lv_label_create(scr);
|
||||
lv_label_set_text_static(low_label, "current smallest\nloaded value:");
|
||||
lv_obj_align(low_label, LV_ALIGN_BOTTOM_LEFT, 10, -10);
|
||||
|
||||
load_item(obj, 3);
|
||||
/* These counters hold the the highest/lowest number currently loaded. */
|
||||
top_num = 3;
|
||||
bottom_num = 3;
|
||||
|
||||
lv_obj_update_layout(obj);
|
||||
update_scroll(obj);
|
||||
lv_obj_add_event_cb(obj, scroll_cb, LV_EVENT_SCROLL, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,146 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
|
||||
|
||||
|
||||
/*
|
||||
* Circular list implementation based on:
|
||||
* Reference: https://blog.csdn.net/TQW4321/article/details/145434819
|
||||
*/
|
||||
|
||||
/* Applies to both width (for row items) and height (for column items) */
|
||||
#define ITEM_SIZE 80
|
||||
|
||||
/* Function to calculate the total content width of the container */
|
||||
static int32_t get_content_width(lv_obj_t * cont)
|
||||
{
|
||||
int32_t w = 0;
|
||||
int32_t pad_column = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); // 列间距
|
||||
int32_t total = (int32_t)lv_obj_get_child_count(cont);
|
||||
|
||||
for(int32_t i = 0; i < total; i++) {
|
||||
w += lv_obj_get_width(lv_obj_get_child(cont, i));
|
||||
if(i < total - 1) w += pad_column;
|
||||
}
|
||||
return w + lv_obj_get_style_pad_left(cont, LV_PART_MAIN)
|
||||
+ lv_obj_get_style_pad_right(cont, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
/* Scroll event callback for row layout */
|
||||
static void cont_row_scroll_event_cb(lv_event_t * e)
|
||||
{
|
||||
static bool is_adjusting = false;
|
||||
lv_obj_t * cont = lv_event_get_current_target_obj(e);
|
||||
|
||||
if(!is_adjusting) {
|
||||
is_adjusting = true;
|
||||
int32_t scroll_x = lv_obj_get_scroll_x(cont);
|
||||
int32_t cont_w = lv_obj_get_width(cont);
|
||||
int32_t content_w = get_content_width(cont);
|
||||
|
||||
/* Use ITEM_SIZE as horizontal item width */
|
||||
const int32_t item_width = ITEM_SIZE;
|
||||
|
||||
if(scroll_x <= 0) {
|
||||
lv_obj_t * last_child = lv_obj_get_child(cont, (int32_t)(lv_obj_get_child_count(cont) - 1));
|
||||
lv_obj_move_to_index(last_child, 0);
|
||||
lv_obj_scroll_to_x(cont, scroll_x + item_width, LV_ANIM_OFF);
|
||||
}
|
||||
else if(scroll_x > content_w - cont_w) {
|
||||
lv_obj_t * first_child = lv_obj_get_child(cont, 0);
|
||||
lv_obj_move_to_index(first_child, (int32_t)(lv_obj_get_child_count(cont) - 1));
|
||||
lv_obj_scroll_to_x(cont, scroll_x - item_width, LV_ANIM_OFF);
|
||||
}
|
||||
is_adjusting = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to calculate the total content height of the container */
|
||||
static int32_t get_content_height(lv_obj_t * cont)
|
||||
{
|
||||
int32_t h = 0;
|
||||
int32_t pad_row = lv_obj_get_style_pad_row(cont, LV_PART_MAIN);
|
||||
int32_t total = (int32_t)lv_obj_get_child_count(cont);
|
||||
|
||||
for(int i = 0; i < total; i++) {
|
||||
h += lv_obj_get_height(lv_obj_get_child(cont, i));
|
||||
if(i < total - 1) h += pad_row;
|
||||
}
|
||||
return h + lv_obj_get_style_pad_top(cont, LV_PART_MAIN)
|
||||
+ lv_obj_get_style_pad_bottom(cont, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
/* Scroll event callback for column layout */
|
||||
static void cont_col_scroll_event_cb(lv_event_t * e)
|
||||
{
|
||||
static bool is_adjusting = false;
|
||||
lv_obj_t * cont = lv_event_get_current_target_obj(e);
|
||||
|
||||
if(!is_adjusting) {
|
||||
is_adjusting = true;
|
||||
int32_t scroll_y = lv_obj_get_scroll_y(cont);
|
||||
int32_t cont_h = lv_obj_get_height(cont);
|
||||
int32_t content_h = get_content_height(cont);
|
||||
|
||||
/* Use ITEM_SIZE as vertical item height */
|
||||
const int32_t item_height = ITEM_SIZE;
|
||||
|
||||
if(scroll_y <= 0) {
|
||||
lv_obj_t * last_child = lv_obj_get_child(cont, (int32_t)(lv_obj_get_child_count(cont) - 1));
|
||||
lv_obj_move_to_index(last_child, 0);
|
||||
lv_obj_scroll_to_y(cont, scroll_y + item_height, LV_ANIM_OFF);
|
||||
}
|
||||
else if(scroll_y > content_h - cont_h) {
|
||||
lv_obj_t * first_child = lv_obj_get_child(cont, 0);
|
||||
lv_obj_move_to_index(first_child, (int32_t)(lv_obj_get_child_count(cont) - 1));
|
||||
lv_obj_scroll_to_y(cont, scroll_y - item_height, LV_ANIM_OFF);
|
||||
}
|
||||
is_adjusting = false;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_example_scroll_8(void)
|
||||
{
|
||||
/* Create a scroll container with ROW flex direction */
|
||||
lv_obj_t * cont_row = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(cont_row, 300, 75);
|
||||
lv_obj_align(cont_row, LV_ALIGN_TOP_MID, 0, 5);
|
||||
lv_obj_set_flex_flow(cont_row, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_add_event_cb(cont_row, cont_row_scroll_event_cb, LV_EVENT_SCROLL, NULL);
|
||||
/* Hide scrollbar visuals */
|
||||
lv_obj_set_scrollbar_mode(cont_row, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
/* Create a scroll container with COLUMN flex direction */
|
||||
lv_obj_t * cont_col = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(cont_col, 200, 150);
|
||||
lv_obj_align_to(cont_col, cont_row, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
|
||||
lv_obj_set_flex_flow(cont_col, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_add_event_cb(cont_col, cont_col_scroll_event_cb, LV_EVENT_SCROLL, NULL);
|
||||
/* Hide scrollbar visuals */
|
||||
lv_obj_set_scrollbar_mode(cont_col, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
/* If the number of items is less than 3, scrolling may not be needed or may cause unexpected behavior. */
|
||||
uint32_t i;
|
||||
for(i = 0; i < 10; i++) {
|
||||
lv_obj_t * obj;
|
||||
lv_obj_t * label;
|
||||
|
||||
/*Add items to the row*/
|
||||
obj = lv_button_create(cont_row);
|
||||
lv_obj_set_size(obj, ITEM_SIZE, LV_PCT(100));
|
||||
|
||||
label = lv_label_create(obj);
|
||||
lv_label_set_text_fmt(label, "Item %" LV_PRIu32, i + 1);
|
||||
lv_obj_center(label);
|
||||
|
||||
/*Add items to the column*/
|
||||
obj = lv_button_create(cont_col);
|
||||
lv_obj_set_size(obj, LV_PCT(100), ITEM_SIZE);
|
||||
|
||||
label = lv_label_create(obj);
|
||||
lv_label_set_text_fmt(label, "Item %" LV_PRIu32, i + 1);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user