diff --git a/Kconfig b/Kconfig index 9343321fb7..b718b22a8e 100644 --- a/Kconfig +++ b/Kconfig @@ -1119,6 +1119,10 @@ menu "LVGL configuration" bool "Enable Auto play" depends on LV_USE_DEMO_MUSIC default n + + config LV_USE_DEMO_FLEX_LAYOUT + bool "Flex layout previewer" + default n endmenu endmenu diff --git a/demos/flex_layout/lv_demo_flex_layout.h b/demos/flex_layout/lv_demo_flex_layout.h new file mode 100644 index 0000000000..228dc40165 --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout.h @@ -0,0 +1,38 @@ +/** + * @file lv_demo_flex_layout.h + * + */ + +#ifndef LV_DEMO_FLEX_LAYOUT_H +#define LV_DEMO_FLEX_LAYOUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void lv_demo_flex_layout(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DEMO_FLEX_LAYOUT_H*/ diff --git a/demos/flex_layout/lv_demo_flex_layout_ctrl_pad.c b/demos/flex_layout/lv_demo_flex_layout_ctrl_pad.c new file mode 100644 index 0000000000..6e5e90f388 --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout_ctrl_pad.c @@ -0,0 +1,168 @@ +/** + * @file lv_demo_flex_layout_ctrl_pad.h + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_flex_layout_main.h" + +#if LV_USE_DEMO_FLEX_LAYOUT && LV_USE_USER_DATA + +/********************* + * DEFINES + *********************/ + +#define SPINBOX_UPDATE_STYLE_VALUE(item) \ + do { \ + lv_obj_t* sbox = ui->ctrl_pad.tab.layout.spinbox_##item; \ + lv_coord_t val = lv_obj_get_style_##item(obj, LV_PART_MAIN); \ + lv_spinbox_set_value(sbox, val); \ + } while(0) + +#define SPINBOX_EVENT_ATTACH(item) \ + lv_obj_add_event_cb(ui->ctrl_pad.tab.layout.spinbox_##item, ctrl_pad_spinbox_event_handler, LV_EVENT_VALUE_CHANGED, ui); + + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void ctrl_pad_spinbox_event_handler(lv_event_t * e); +static void ctrl_pad_checkbox_event_handler(lv_event_t * e); +static void ctrl_pad_btn_event_attach(view_t * ui); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void ctrl_pad_attach(view_t * ui) +{ + ctrl_pad_btn_event_attach(ui); + flex_loader_attach(ui); + + SPINBOX_EVENT_ATTACH(width); + SPINBOX_EVENT_ATTACH(height); + SPINBOX_EVENT_ATTACH(pad_top); + SPINBOX_EVENT_ATTACH(pad_bottom); + SPINBOX_EVENT_ATTACH(pad_left); + SPINBOX_EVENT_ATTACH(pad_right); + SPINBOX_EVENT_ATTACH(pad_column); + SPINBOX_EVENT_ATTACH(pad_row); + SPINBOX_EVENT_ATTACH(flex_grow); + + lv_obj_add_event_cb( + ui->ctrl_pad.tab.flex.checkbox_scrl, + ctrl_pad_checkbox_event_handler, + LV_EVENT_VALUE_CHANGED, + ui + ); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void ctrl_pad_btn_remove_event_handler(lv_event_t * e) +{ + view_t * ui = lv_event_get_user_data(e); + if(ui->obj_cur) { + if(ui->obj_cur == ui->root) { + lv_obj_clean(ui->root); + } + else { + lv_obj_del(ui->obj_cur); + ui->obj_cur = NULL; + } + } +} + +void ctrl_pad_obj_update(lv_obj_t * obj, view_t * ui) +{ + lv_obj_t * spinbox = ui->ctrl_pad.tab.layout.spinbox_width; + lv_coord_t value = lv_obj_get_width(obj); + lv_spinbox_set_value(spinbox, value); + + spinbox = ui->ctrl_pad.tab.layout.spinbox_height; + value = lv_obj_get_height(obj); + lv_spinbox_set_value(spinbox, value); + + SPINBOX_UPDATE_STYLE_VALUE(pad_top); + SPINBOX_UPDATE_STYLE_VALUE(pad_bottom); + SPINBOX_UPDATE_STYLE_VALUE(pad_left); + SPINBOX_UPDATE_STYLE_VALUE(pad_right); + SPINBOX_UPDATE_STYLE_VALUE(pad_column); + SPINBOX_UPDATE_STYLE_VALUE(pad_row); + SPINBOX_UPDATE_STYLE_VALUE(flex_grow); + + lv_obj_t * checkbox = ui->ctrl_pad.tab.flex.checkbox_scrl; + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE)) { + lv_obj_add_state(checkbox, LV_STATE_CHECKED); + } + else { + lv_obj_clear_state(checkbox, LV_STATE_CHECKED); + } +} + +static void ctrl_pad_spinbox_event_handler(lv_event_t * e) +{ + view_t * ui = lv_event_get_user_data(e); + lv_obj_t * spinbox = lv_event_get_target(e); + lv_style_prop_t prop = (lv_style_prop_t)(lv_uintptr_t)lv_obj_get_user_data(spinbox); + + lv_style_value_t v = { + .num = (int32_t)lv_spinbox_get_value(spinbox) + }; + + if(ui->obj_cur) { + lv_obj_set_local_style_prop(ui->obj_cur, prop, v, LV_PART_MAIN); + } +} + +static void ctrl_pad_btn_add_event_handler(lv_event_t * e) +{ + view_t * ui = lv_event_get_user_data(e); + obj_child_node_create(ui->obj_cur, ui); +} + +static void ctrl_pad_checkbox_event_handler(lv_event_t * e) +{ + view_t * ui = lv_event_get_user_data(e); + if(ui->obj_cur) { + bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED); + checked ? lv_obj_add_flag(ui->obj_cur, LV_OBJ_FLAG_SCROLLABLE) : lv_obj_clear_flag(ui->obj_cur, LV_OBJ_FLAG_SCROLLABLE); + } +} + +static void ctrl_pad_btn_event_attach(view_t * ui) +{ + lv_obj_add_event_cb( + ui->ctrl_pad.btn.add, + ctrl_pad_btn_add_event_handler, + LV_EVENT_CLICKED, + ui + ); + + lv_obj_add_event_cb( + ui->ctrl_pad.btn.remove, + ctrl_pad_btn_remove_event_handler, + LV_EVENT_CLICKED, + ui + ); +} + +#endif diff --git a/demos/flex_layout/lv_demo_flex_layout_flex_loader.c b/demos/flex_layout/lv_demo_flex_layout_flex_loader.c new file mode 100644 index 0000000000..39eb687932 --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout_flex_loader.c @@ -0,0 +1,143 @@ +/** + * @file lv_demo_flex_layout_flex_loader.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_flex_layout_main.h" + +#if LV_USE_DEMO_FLEX_LAYOUT && LV_USE_USER_DATA + +/********************* + * DEFINES + *********************/ + +#define FLEX_ALIGN_EVENT_DEF(item) \ + static void flex_align_##item##_event_handler(lv_event_t* e) \ + { \ + view_t* ui = lv_event_get_user_data(e); \ + lv_obj_t* ddlist = lv_event_get_target(e); \ + uint16_t selected = lv_dropdown_get_selected(ddlist); \ + if (ui->obj_cur) { \ + lv_obj_set_style_flex_##item##_place(ui->obj_cur, \ + flex_align_map[selected], 0); \ + } \ + } + +#define FLEX_ALIGN_DDLIST_UPDATE_DEF(item) \ + do { \ + lv_flex_align_t flex_align = lv_obj_get_style_flex_##item##_place(obj, 0); \ + for (i = 0; i < ARRAY_SIZE(flex_align_map); i++) { \ + if (flex_align == flex_align_map[i]) { \ + lv_dropdown_set_selected(ui->ctrl_pad.tab.align.ddlist_align_##item, \ + i); \ + break; \ + } \ + } \ + } while(0) + +#define FLEX_ALIGN_EVENT_ATTACH(item) \ + do { \ + lv_obj_add_event_cb(ui->ctrl_pad.tab.align.ddlist_align_##item, \ + flex_align_##item##_event_handler, \ + LV_EVENT_VALUE_CHANGED, \ + ui \ + ); \ + } while(0) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void flex_flow_event_handler(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +static const lv_flex_flow_t flex_flow_map[] = { + LV_FLEX_FLOW_ROW, + LV_FLEX_FLOW_COLUMN, + LV_FLEX_FLOW_ROW_WRAP, + LV_FLEX_FLOW_ROW_REVERSE, + LV_FLEX_FLOW_ROW_WRAP_REVERSE, + LV_FLEX_FLOW_COLUMN_WRAP, + LV_FLEX_FLOW_COLUMN_REVERSE, + LV_FLEX_FLOW_COLUMN_WRAP_REVERSE +}; + +static const lv_flex_align_t flex_align_map[] = { + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_END, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_SPACE_EVENLY, + LV_FLEX_ALIGN_SPACE_AROUND, + LV_FLEX_ALIGN_SPACE_BETWEEN, +}; + +/********************** + * MACROS + **********************/ + +FLEX_ALIGN_EVENT_DEF(main) +FLEX_ALIGN_EVENT_DEF(cross) +FLEX_ALIGN_EVENT_DEF(track) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void flex_loader_attach(view_t * ui) +{ + lv_obj_add_event_cb( + ui->ctrl_pad.tab.flex.ddlist_flow, + flex_flow_event_handler, + LV_EVENT_VALUE_CHANGED, + ui + ); + + FLEX_ALIGN_EVENT_ATTACH(main); + FLEX_ALIGN_EVENT_ATTACH(cross); + FLEX_ALIGN_EVENT_ATTACH(track); +} + +void flex_loader_obj_update(lv_obj_t * obj, view_t * ui) +{ + lv_flex_flow_t flex_flow = lv_obj_get_style_flex_flow(obj, 0); + uint32_t i; + for(i = 0; i < ARRAY_SIZE(flex_flow_map); i++) { + if(flex_flow == flex_flow_map[i]) { + lv_dropdown_set_selected(ui->ctrl_pad.tab.flex.ddlist_flow, i); + break; + } + } + + FLEX_ALIGN_DDLIST_UPDATE_DEF(main); + FLEX_ALIGN_DDLIST_UPDATE_DEF(cross); + FLEX_ALIGN_DDLIST_UPDATE_DEF(track); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void flex_flow_event_handler(lv_event_t * e) +{ + view_t * ui = lv_event_get_user_data(e); + lv_obj_t * ddlist = lv_event_get_target(e); + uint16_t selected = lv_dropdown_get_selected(ddlist); + + if(ui->obj_cur) { + lv_obj_set_flex_flow(ui->obj_cur, flex_flow_map[selected]); + lv_obj_scroll_to(ui->obj_cur, 0, 0, LV_ANIM_ON); + } +} + +#endif diff --git a/demos/flex_layout/lv_demo_flex_layout_main.c b/demos/flex_layout/lv_demo_flex_layout_main.c new file mode 100644 index 0000000000..1bc282ae09 --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout_main.c @@ -0,0 +1,51 @@ +/** + * @file lv_demo_flex_layout_main.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_flex_layout_main.h" +#include "lv_demo_flex_layout.h" + +#if LV_USE_DEMO_FLEX_LAYOUT && LV_USE_USER_DATA + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +static view_t view; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_demo_flex_layout(void) +{ + view_create(lv_scr_act(), &view); + ctrl_pad_attach(&view); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif diff --git a/demos/flex_layout/lv_demo_flex_layout_main.h b/demos/flex_layout/lv_demo_flex_layout_main.h new file mode 100644 index 0000000000..e192ff3796 --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout_main.h @@ -0,0 +1,104 @@ +/** + * @file lv_demo_flex_layout_main.h + * + */ + +#ifndef LV_DEMO_FLEX_LAYOUT_MAIN_H +#define LV_DEMO_FLEX_LAYOUT_MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +/********************* + * DEFINES + *********************/ + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_obj_t * root; + lv_obj_t * obj_cur; + lv_style_t obj_def_style; + lv_style_t obj_checked_style; + + struct { + lv_obj_t * cont; + + struct { + lv_obj_t * view; + + struct { + lv_obj_t * tab; + lv_obj_t * ddlist_flow; + lv_obj_t * checkbox_scrl; + } flex; + + struct { + lv_obj_t * tab; + lv_obj_t * ddlist_align_main; + lv_obj_t * ddlist_align_cross; + lv_obj_t * ddlist_align_track; + } align; + + struct { + lv_obj_t * tab; + lv_obj_t * group_width_and_height; + lv_obj_t * spinbox_width; + lv_obj_t * spinbox_height; + lv_obj_t * group_width_and_height_min; + lv_obj_t * spinbox_min_width; + lv_obj_t * spinbox_min_height; + lv_obj_t * group_width_and_height_max; + lv_obj_t * spinbox_max_width; + lv_obj_t * spinbox_max_height; + lv_obj_t * spinbox_pad_top; + lv_obj_t * spinbox_pad_bottom; + lv_obj_t * spinbox_pad_left; + lv_obj_t * spinbox_pad_right; + lv_obj_t * spinbox_pad_column; + lv_obj_t * spinbox_pad_row; + lv_obj_t * spinbox_flex_grow; + } layout; + } tab; + + struct { + lv_obj_t * cont; + lv_obj_t * add; + lv_obj_t * remove; + } btn; + + } ctrl_pad; +} view_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void view_create(lv_obj_t * par, view_t * ui); +void view_ctrl_pad_create(lv_obj_t * par, view_t * ui); +lv_obj_t * obj_child_node_create(lv_obj_t * par, view_t * ui); + +void ctrl_pad_attach(view_t * ui); +void ctrl_pad_obj_update(lv_obj_t * obj, view_t * ui); +void flex_loader_obj_update(lv_obj_t * obj, view_t * ui); +void flex_loader_attach(view_t * ui); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DEMO_FLEX_LAYOUT_MAIN_H*/ diff --git a/demos/flex_layout/lv_demo_flex_layout_view.c b/demos/flex_layout/lv_demo_flex_layout_view.c new file mode 100644 index 0000000000..718174713a --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout_view.c @@ -0,0 +1,157 @@ +/** + * @file lv_demo_flex_layout_view.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_flex_layout_main.h" + +#if LV_USE_DEMO_FLEX_LAYOUT && LV_USE_USER_DATA + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_obj_t * btn_create(lv_obj_t * par, const char * str, lv_color_t color); +static void obj_child_node_def_style_init(lv_style_t * style); +static void obj_child_node_checked_style_init(lv_style_t * style); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void view_create(lv_obj_t * par, view_t * ui) +{ + /* layout */ + lv_obj_set_flex_flow(par, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align( + par, + LV_FLEX_ALIGN_SPACE_AROUND, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_SPACE_AROUND + ); + + /* style */ + obj_child_node_def_style_init(&ui->obj_def_style); + obj_child_node_checked_style_init(&ui->obj_checked_style); + + /* root */ + ui->root = obj_child_node_create(par, ui); + lv_obj_set_size(ui->root, lv_pct(50), lv_pct(80)); + + /* mian ctrl_pad */ + lv_obj_t * obj = lv_obj_create(par); + lv_obj_set_size(obj, lv_pct(40), lv_pct(80)); + lv_obj_set_style_pad_all(obj, 0, 0); + lv_obj_set_style_pad_gap(obj, 0, 0); + lv_obj_set_style_radius(obj, 10, 0); + lv_obj_set_style_clip_corner(obj, true, 0); + lv_obj_set_style_border_width(obj, 0, 0); + lv_obj_set_style_shadow_color(obj, lv_color_hex3(0xaaa), 0); + lv_obj_set_style_shadow_width(obj, 20, 0); + lv_obj_set_style_shadow_ofs_y(obj, 2, 0); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align( + obj, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER + ); + ui->ctrl_pad.cont = obj; + + /* tabview */ + view_ctrl_pad_create(ui->ctrl_pad.cont, ui); + + /* btn_cont */ + obj = lv_obj_create(ui->ctrl_pad.cont); + lv_obj_remove_style_all(obj); + lv_obj_set_style_border_width(obj, 2, 0); + lv_obj_set_style_border_color(obj, lv_palette_lighten(LV_PALETTE_GREY, 2), 0); + lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_TOP, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_ver(obj, 16, 0); + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align( + obj, + LV_FLEX_ALIGN_SPACE_AROUND, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER + ); + ui->ctrl_pad.btn.cont = obj; + ui->ctrl_pad.btn.add = btn_create(obj, "Add", lv_palette_main(LV_PALETTE_BLUE_GREY)); + ui->ctrl_pad.btn.remove = btn_create(obj, "Remove", lv_palette_main(LV_PALETTE_RED)); + + lv_event_send(ui->root, LV_EVENT_CLICKED, NULL); /*Make it active by default*/ + + /* fade effect */ + lv_obj_fade_in(ui->root, 600, 0); + lv_obj_fade_in(ui->ctrl_pad.cont, 600, 300); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_obj_t * btn_create(lv_obj_t * par, const char * str, lv_color_t color) +{ + lv_obj_t * btn = lv_btn_create(par); + lv_obj_set_width(btn, lv_pct(30)); + lv_obj_set_height(btn, 30); + lv_obj_set_style_border_width(btn, 0, LV_PART_MAIN); + lv_obj_set_style_bg_color(btn, color, LV_PART_MAIN); + lv_obj_set_style_radius(btn, 5, LV_PART_MAIN); + + lv_obj_t * label = lv_label_create(btn); + lv_label_set_text(label, str); + lv_obj_center(label); + + return btn; +} + +static void obj_child_node_def_style_init(lv_style_t * style) +{ + lv_style_init(style); + lv_style_set_size(style, LV_PCT(30), LV_PCT(30)); + lv_style_set_flex_flow(style, LV_FLEX_FLOW_ROW); + lv_style_set_layout(style, LV_LAYOUT_FLEX); + lv_style_set_radius(style, 0); +} + +static void obj_child_node_checked_style_init(lv_style_t * style) +{ + lv_style_init(style); + lv_style_set_border_color(style, lv_palette_main(LV_PALETTE_BLUE)); + lv_style_set_shadow_color(style, lv_palette_main(LV_PALETTE_GREY)); + lv_style_set_shadow_width(style, 20); + + static lv_style_transition_dsc_t tran; + static const lv_style_prop_t prop[] = { + LV_STYLE_SHADOW_OPA, + LV_STYLE_BORDER_COLOR, + LV_STYLE_PROP_INV + }; + lv_style_transition_dsc_init(&tran, prop, lv_anim_path_ease_out, 300, 0, NULL); + lv_style_set_transition(style, &tran); +} + +#endif diff --git a/demos/flex_layout/lv_demo_flex_layout_view_child_node.c b/demos/flex_layout/lv_demo_flex_layout_view_child_node.c new file mode 100644 index 0000000000..007ad98ab6 --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout_view_child_node.c @@ -0,0 +1,82 @@ +/** + * @file lv_demo_flex_layout_view_child_node.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_flex_layout_main.h" + +#if LV_USE_DEMO_FLEX_LAYOUT && LV_USE_USER_DATA + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void obj_child_node_event_handler(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * obj_child_node_create(lv_obj_t * par, view_t * ui) +{ + if(par == NULL) { + return NULL; + } + + uint32_t cnt = lv_obj_get_child_cnt(par); + + lv_obj_t * obj = lv_obj_create(par); + lv_obj_add_style(obj, &ui->obj_def_style, 0); + lv_obj_add_style(obj, &ui->obj_checked_style, LV_STATE_CHECKED); + + lv_obj_t * label = lv_label_create(obj); + lv_label_set_text_fmt(label, "%d", cnt); + lv_obj_add_flag(label, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_FLOATING); + lv_obj_center(label); + + lv_obj_add_event_cb(obj, obj_child_node_event_handler, LV_EVENT_CLICKED, ui); + + return obj; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void obj_child_node_event_handler(lv_event_t * e) +{ + view_t * ui = (view_t *)lv_event_get_user_data(e); + lv_obj_t * obj = lv_event_get_target(e); + + if(ui->obj_cur) { + lv_obj_clear_state(ui->obj_cur, LV_STATE_CHECKED); + } + + lv_obj_add_state(obj, LV_STATE_CHECKED); + + ui->obj_cur = obj; + flex_loader_obj_update(obj, ui); + ctrl_pad_obj_update(obj, ui); +} + +#endif diff --git a/demos/flex_layout/lv_demo_flex_layout_view_ctrl_pad.c b/demos/flex_layout/lv_demo_flex_layout_view_ctrl_pad.c new file mode 100644 index 0000000000..c9270ebc49 --- /dev/null +++ b/demos/flex_layout/lv_demo_flex_layout_view_ctrl_pad.c @@ -0,0 +1,312 @@ +/** + * @file lv_demo_flex_layout_view_ctrl_pad.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_flex_layout_main.h" + +#if LV_USE_DEMO_FLEX_LAYOUT && LV_USE_USER_DATA + +/********************* + * DEFINES + *********************/ + +#define DDLIST_ALIGN_CREATE_DEF(item) \ + do { \ + ui->ctrl_pad.tab.align.ddlist_align_##item = \ + ddlist_create(tab, \ + "Align "#item" place", \ + "start\n" \ + "end\n" \ + "center\n" \ + "space evenly\n" \ + "space around\n" \ + "space between"); \ + } while(0) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void tab_flex_create(lv_obj_t * tab, view_t * ui); +static void tab_align_create(lv_obj_t * tab, view_t * ui); +static void tab_layout_create(lv_obj_t * tab, view_t * ui); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void view_ctrl_pad_create(lv_obj_t * par, view_t * ui) +{ + lv_obj_t * tv = lv_tabview_create(par, LV_DIR_TOP, 50); + lv_obj_set_width(tv, lv_pct(100)); + lv_obj_set_flex_grow(tv, 1); + lv_obj_set_style_radius(tv, 0, 0); + lv_obj_set_style_bg_color(tv, lv_color_hex(0xffffff), 0); + + lv_obj_t * btns = lv_tabview_get_tab_btns(tv); + lv_obj_set_style_outline_width(btns, 0, LV_PART_ITEMS | LV_STATE_FOCUS_KEY); + lv_obj_set_style_outline_width(btns, 0, LV_STATE_FOCUS_KEY); + lv_obj_set_style_bg_color(btns, lv_color_white(), LV_PART_ITEMS | LV_STATE_CHECKED); + lv_obj_set_height(btns, 40); + + ui->ctrl_pad.tab.view = tv; + + ui->ctrl_pad.tab.flex.tab = lv_tabview_add_tab(tv, "Flex"); + ui->ctrl_pad.tab.align.tab = lv_tabview_add_tab(tv, "Align"); + ui->ctrl_pad.tab.layout.tab = lv_tabview_add_tab(tv, "Layout"); + + tab_flex_create(ui->ctrl_pad.tab.flex.tab, ui); + tab_align_create(ui->ctrl_pad.tab.align.tab, ui); + tab_layout_create(ui->ctrl_pad.tab.layout.tab, ui); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_obj_t * ddlist_create(lv_obj_t * par, const char * name, const char * options) +{ + lv_obj_t * cont = lv_obj_create(par); + lv_obj_remove_style_all(cont); + lv_obj_set_size(cont, lv_pct(80), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + + lv_obj_t * label = lv_label_create(cont); + lv_label_set_text(label, name); + + lv_obj_t * ddlist = lv_dropdown_create(cont); + lv_obj_set_width(ddlist, lv_pct(100)); + lv_dropdown_set_options_static(ddlist, options); + return ddlist; +} + +static void tab_flex_create(lv_obj_t * tab, view_t * ui) +{ + lv_obj_set_flex_flow(tab, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align( + tab, + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER + ); + + ui->ctrl_pad.tab.flex.ddlist_flow = ddlist_create( + tab, + "Flow", + "Row\n" + "Column\n" + "Row wrap\n" + "Row reverse\n" + "Row wrap reverse\n" + "Column wrap\n" + "Column reverse\n" + "Column wrap reverse" + ); + + lv_obj_t * cb = lv_checkbox_create(tab); + lv_checkbox_set_text(cb, "Scrollable"); + ui->ctrl_pad.tab.flex.checkbox_scrl = cb; +} + +static void tab_align_create(lv_obj_t * tab, view_t * ui) +{ + lv_obj_set_flex_flow(tab, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align( + tab, + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER + ); + + DDLIST_ALIGN_CREATE_DEF(main); + DDLIST_ALIGN_CREATE_DEF(cross); + DDLIST_ALIGN_CREATE_DEF(track); +} + +static void btn_inc_event_handler(lv_event_t * e) +{ + lv_obj_t * spinbox = lv_event_get_user_data(e); + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_SHORT_CLICKED || code == LV_EVENT_LONG_PRESSED_REPEAT) { + lv_spinbox_increment(spinbox); + } +} + +static void btn_dec_event_handler(lv_event_t * e) +{ + lv_obj_t * spinbox = lv_event_get_user_data(e); + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_SHORT_CLICKED || code == LV_EVENT_LONG_PRESSED_REPEAT) { + lv_spinbox_decrement(spinbox); + } +} + +static lv_obj_t * spinbox_ctrl_create(lv_obj_t * par, lv_style_prop_t prop, lv_obj_t ** cont_) +{ + lv_obj_t * cont_main = par; + lv_obj_t * label; + + lv_obj_t * cont_spinbox = lv_obj_create(cont_main); + if(cont_) *cont_ = cont_spinbox; + lv_obj_remove_style_all(cont_spinbox); + lv_obj_set_height(cont_spinbox, LV_SIZE_CONTENT); + lv_obj_set_flex_grow(cont_spinbox, 1); + lv_obj_set_style_radius(cont_spinbox, 5, LV_PART_MAIN); + lv_obj_set_style_clip_corner(cont_spinbox, true, LV_PART_MAIN); + lv_obj_set_style_outline_width(cont_spinbox, 2, LV_PART_MAIN); + lv_obj_set_style_outline_color(cont_spinbox, lv_color_hex3(0xddd), LV_PART_MAIN); + + lv_obj_set_flex_flow(cont_spinbox, LV_FLEX_FLOW_ROW); + lv_obj_set_style_flex_main_place(cont_spinbox, LV_FLEX_ALIGN_CENTER, LV_PART_MAIN); + + static lv_style_t btn_style; + if(btn_style.prop_cnt < 1) { + lv_style_init(&btn_style); + lv_style_set_radius(&btn_style, 0); + lv_style_set_outline_width(&btn_style, 1); + lv_style_set_outline_pad(&btn_style, 1); + lv_style_set_outline_color(&btn_style, lv_color_hex3(0xddd)); + lv_style_set_shadow_width(&btn_style, 0); + lv_style_set_bg_color(&btn_style, lv_color_white()); + lv_style_set_text_color(&btn_style, lv_theme_get_color_primary(par)); + } + + lv_obj_t * btn_dec = lv_btn_create(cont_spinbox); + lv_obj_set_width(btn_dec, 30); + lv_obj_add_style(btn_dec, &btn_style, LV_PART_MAIN); + label = lv_label_create(btn_dec); + lv_label_set_text(label, "-"); + lv_obj_center(label); + + lv_obj_t * spinbox = lv_spinbox_create(cont_spinbox); + lv_obj_set_flex_grow(spinbox, 1); + lv_obj_set_style_shadow_width(spinbox, 0, LV_PART_MAIN); + lv_obj_set_style_border_width(spinbox, 0, LV_PART_MAIN); + lv_obj_set_style_outline_width(spinbox, 1, LV_PART_MAIN); + lv_obj_set_style_outline_pad(spinbox, 1, LV_PART_MAIN); + lv_obj_set_style_outline_color(spinbox, lv_color_hex3(0xddd), LV_PART_MAIN); + lv_obj_set_style_radius(spinbox, 0, LV_PART_MAIN); + lv_obj_set_user_data(spinbox, (void *)(lv_uintptr_t)prop); + lv_spinbox_set_range(spinbox, LV_COORD_MIN, LV_COORD_MAX); + lv_spinbox_set_digit_format(spinbox, 3, 0); + lv_spinbox_step_prev(spinbox); + + lv_obj_t * btn_inc = lv_btn_create(cont_spinbox); + lv_obj_set_width(btn_inc, 30); + lv_obj_add_style(btn_inc, &btn_style, LV_PART_MAIN); + label = lv_label_create(btn_inc); + lv_label_set_text(label, "+"); + lv_obj_center(label); + + lv_obj_add_event_cb(btn_inc, btn_inc_event_handler, LV_EVENT_ALL, spinbox); + lv_obj_add_event_cb(btn_dec, btn_dec_event_handler, LV_EVENT_ALL, spinbox); + + return spinbox; +} + +static void tab_layout_create(lv_obj_t * tab, view_t * ui) +{ + lv_obj_set_flex_flow(tab, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_gap(tab, 5, LV_PART_MAIN); + lv_obj_set_flex_align( + tab, + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER + ); + + static lv_style_t group_style; + lv_style_init(&group_style); + lv_style_set_pad_all(&group_style, 2); + lv_style_set_border_width(&group_style, 0); + lv_style_set_width(&group_style, LV_PCT(100)); + lv_style_set_height(&group_style, LV_SIZE_CONTENT); + + lv_obj_t * label = lv_label_create(tab); + lv_obj_set_style_pad_top(label, 10, LV_PART_MAIN); + lv_checkbox_set_text(label, "WIDTH x HEIGHT"); + + lv_obj_t * temp_group = lv_obj_create(tab); + ui->ctrl_pad.tab.layout.group_width_and_height = temp_group; + lv_obj_add_style(temp_group, &group_style, LV_PART_MAIN); + lv_obj_set_flex_flow(temp_group, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(temp_group, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + ui->ctrl_pad.tab.layout.spinbox_width = spinbox_ctrl_create(temp_group, LV_STYLE_WIDTH, NULL); + ui->ctrl_pad.tab.layout.spinbox_height = spinbox_ctrl_create(temp_group, LV_STYLE_HEIGHT, NULL); + + label = lv_label_create(tab); + lv_obj_set_style_pad_top(label, 10, LV_PART_MAIN); + lv_checkbox_set_text(label, "MIN-WIDTH x MIN-HEIGHT"); + + temp_group = lv_obj_create(tab); + ui->ctrl_pad.tab.layout.group_width_and_height_min = temp_group; + lv_obj_add_style(temp_group, &group_style, LV_PART_MAIN); + lv_obj_set_flex_flow(temp_group, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(temp_group, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + ui->ctrl_pad.tab.layout.spinbox_min_width = spinbox_ctrl_create(temp_group, LV_STYLE_MIN_WIDTH, NULL); + ui->ctrl_pad.tab.layout.spinbox_min_height = spinbox_ctrl_create(temp_group, LV_STYLE_MIN_HEIGHT, NULL); + + label = lv_label_create(tab); + lv_obj_set_style_pad_top(label, 10, LV_PART_MAIN); + lv_checkbox_set_text(label, "MAX-WIDTH x MAX-HEIGHT"); + + temp_group = lv_obj_create(tab); + ui->ctrl_pad.tab.layout.group_width_and_height_max = temp_group; + lv_obj_add_style(temp_group, &group_style, LV_PART_MAIN); + lv_obj_set_flex_flow(temp_group, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(temp_group, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + ui->ctrl_pad.tab.layout.spinbox_max_width = spinbox_ctrl_create(temp_group, LV_STYLE_MAX_WIDTH, NULL); + ui->ctrl_pad.tab.layout.spinbox_max_height = spinbox_ctrl_create(temp_group, LV_STYLE_MAX_HEIGHT, NULL); + + temp_group = lv_obj_create(tab); + ui->ctrl_pad.tab.layout.group_width_and_height_max = temp_group; + lv_obj_add_style(temp_group, &group_style, LV_PART_MAIN); + lv_obj_set_style_pad_top(temp_group, 20, LV_PART_MAIN); + lv_obj_set_flex_flow(temp_group, LV_FLEX_FLOW_ROW_WRAP); + lv_obj_set_flex_align(temp_group, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t * temp_cont; + ui->ctrl_pad.tab.layout.spinbox_pad_top = spinbox_ctrl_create(temp_group, LV_STYLE_PAD_TOP, &temp_cont); + lv_obj_set_style_width(ui->ctrl_pad.tab.layout.spinbox_pad_top, 30, LV_PART_MAIN); + lv_obj_set_flex_grow(temp_cont, 0); + ui->ctrl_pad.tab.layout.spinbox_pad_left = spinbox_ctrl_create(temp_group, LV_STYLE_PAD_LEFT, &temp_cont); + lv_obj_add_flag(temp_cont, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK); + label = lv_label_create(temp_group); + lv_checkbox_set_text(label, "PADDING"); + ui->ctrl_pad.tab.layout.spinbox_pad_right = spinbox_ctrl_create(temp_group, LV_STYLE_PAD_RIGHT, NULL); + ui->ctrl_pad.tab.layout.spinbox_pad_bottom = spinbox_ctrl_create(temp_group, LV_STYLE_PAD_BOTTOM, &temp_cont); + lv_obj_set_flex_grow(temp_cont, 0); + lv_obj_add_flag(temp_cont, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK); + + label = lv_label_create(tab); + lv_obj_set_style_pad_top(label, 20, LV_PART_MAIN); + lv_checkbox_set_text(label, "PAD: COL x ROW x GROW"); + + temp_group = lv_obj_create(tab); + ui->ctrl_pad.tab.layout.group_width_and_height_max = temp_group; + lv_obj_add_style(temp_group, &group_style, LV_PART_MAIN); + lv_obj_set_flex_flow(temp_group, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(temp_group, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + ui->ctrl_pad.tab.layout.spinbox_pad_column = spinbox_ctrl_create(temp_group, LV_STYLE_PAD_COLUMN, NULL); + ui->ctrl_pad.tab.layout.spinbox_pad_row = spinbox_ctrl_create(temp_group, LV_STYLE_PAD_ROW, NULL); + ui->ctrl_pad.tab.layout.spinbox_flex_grow = spinbox_ctrl_create(temp_group, LV_STYLE_FLEX_GROW, NULL); +} + +#endif diff --git a/demos/lv_demos.h b/demos/lv_demos.h index d2f0871293..2cc2338e29 100644 --- a/demos/lv_demos.h +++ b/demos/lv_demos.h @@ -35,6 +35,10 @@ extern "C" { #include "widgets/lv_demo_widgets.h" #endif +#if LV_USE_DEMO_FLEX_LAYOUT && LV_USE_USER_DATA +#include "flex_layout/lv_demo_flex_layout.h" +#endif + /********************* * DEFINES *********************/ diff --git a/lv_conf_template.h b/lv_conf_template.h index 115808d23b..af39230091 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -773,6 +773,9 @@ #define LV_DEMO_MUSIC_AUTO_PLAY 0 #endif +/*Flex layout demo*/ +#define LV_USE_DEMO_FLEX_LAYOUT 0 + /*--END OF LV_CONF_H--*/ #endif /*LV_CONF_H*/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index f43cd0066c..691d2a71af 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -2565,6 +2565,15 @@ #endif #endif +/*Flex layout demo*/ +#ifndef LV_USE_DEMO_FLEX_LAYOUT + #ifdef CONFIG_LV_USE_DEMO_FLEX_LAYOUT + #define LV_USE_DEMO_FLEX_LAYOUT CONFIG_LV_USE_DEMO_FLEX_LAYOUT + #else + #define LV_USE_DEMO_FLEX_LAYOUT 0 + #endif +#endif + /*----------------------------------