fix(flex): make min-width, grow, and wrap work together (#7168)

This commit is contained in:
Gabor Kiss-Vamosi 2024-11-21 11:10:36 +01:00 committed by GitHub
parent d5759a0926
commit 98d87021df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 50 additions and 6 deletions

View File

@ -252,7 +252,7 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id
t->grow_dsc = NULL;
int32_t item_id = item_start_id;
int32_t grow_min_size_sum = 0;
lv_obj_t * item = lv_obj_get_child(cont, item_id);
while(item) {
if(item_id != item_start_id && lv_obj_has_flag(item, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK)) break;
@ -260,13 +260,28 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id
if(!lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) {
uint8_t grow_value = lv_obj_get_style_flex_grow(item, LV_PART_MAIN);
if(grow_value) {
int32_t min_size = f->row ? lv_obj_get_style_min_width(item, LV_PART_MAIN)
: lv_obj_get_style_min_height(item, LV_PART_MAIN);
int32_t req_size = min_size;
if(item_id != item_start_id) req_size += item_gap; /*No gap before the first item*/
/*Wrap if can't fit*/
if(f->wrap && t->track_fix_main_size + grow_min_size_sum + req_size > max_main_size) break;
grow_min_size_sum += req_size;
if(item_id != item_start_id) {
t->track_fix_main_size += item_gap; /*The gap is always taken from the space*/
}
t->grow_item_cnt++;
t->track_fix_main_size += item_gap;
if(t->grow_dsc_calc) {
grow_dsc_t * new_dsc = lv_realloc(t->grow_dsc, sizeof(grow_dsc_t) * (t->grow_item_cnt));
LV_ASSERT_MALLOC(new_dsc);
if(new_dsc == NULL) return item_id;
new_dsc[t->grow_item_cnt - 1].item = item;
new_dsc[t->grow_item_cnt - 1].min_size = f->row ? lv_obj_get_style_min_width(item, LV_PART_MAIN)
: lv_obj_get_style_min_height(item, LV_PART_MAIN);
@ -274,13 +289,16 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id
: lv_obj_get_style_max_height(item, LV_PART_MAIN);
new_dsc[t->grow_item_cnt - 1].grow_value = grow_value;
new_dsc[t->grow_item_cnt - 1].clamped = 0;
t->grow_dsc = new_dsc;
}
}
else {
int32_t item_size = get_main_size(item);
if(f->wrap && t->track_fix_main_size + item_size > max_main_size) break;
t->track_fix_main_size += item_size + item_gap;
int32_t req_size = item_size;
if(item_id != item_start_id) req_size += item_gap; /*No gap before the first item*/
if(f->wrap && t->track_fix_main_size + grow_min_size_sum + req_size > max_main_size) break;
t->track_fix_main_size += req_size;
}
t->track_cross_size = LV_MAX(get_cross_size(item), t->track_cross_size);
@ -292,8 +310,6 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id
item = lv_obj_get_child(cont, item_id);
}
if(t->track_fix_main_size > 0) t->track_fix_main_size -= item_gap; /*There is no gap after the last item*/
/*If there is at least one "grow item" the track takes the full space*/
t->track_main_size = t->grow_item_cnt ? max_main_size : t->track_fix_main_size;

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -78,4 +78,32 @@ void test_align(void)
lv_obj_clean(active_screen);
}
/*See https://github.com/lvgl/lvgl/issues/7035*/
void test_wrap_grow_min_width(void)
{
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_ROW_WRAP);
lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_EVENLY);
for(int i = 0; i < 14; i++) {
lv_obj_t * obj = lv_obj_create(lv_screen_active());
lv_obj_set_style_min_width(obj, 100, 0);
lv_obj_set_style_pad_all(obj, 0, 0);
lv_obj_set_height(obj, 70 + (i % 3) * 20);
uint8_t grow = (i % 3);
lv_obj_set_flex_grow(obj, grow);
if(i == 9) {
lv_obj_add_flag(obj, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
}
lv_obj_t * label = lv_label_create(obj);
lv_label_set_text_fmt(label, "grow:%d%s", grow, i == 9 ? "\nnew track" : "");
lv_obj_center(label);
}
TEST_ASSERT_EQUAL_SCREENSHOT("flex_wrap_grow_min_width.png");
}
#endif