diff --git a/src/layouts/flex/lv_flex.c b/src/layouts/flex/lv_flex.c index 2af3bf35a..9c875f53b 100644 --- a/src/layouts/flex/lv_flex.c +++ b/src/layouts/flex/lv_flex.c @@ -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; diff --git a/tests/ref_imgs/flex_wrap_grow_min_width.png b/tests/ref_imgs/flex_wrap_grow_min_width.png new file mode 100644 index 000000000..182b9acab Binary files /dev/null and b/tests/ref_imgs/flex_wrap_grow_min_width.png differ diff --git a/tests/ref_imgs_vg_lite/flex_wrap_grow_min_width.png b/tests/ref_imgs_vg_lite/flex_wrap_grow_min_width.png new file mode 100644 index 000000000..41a74c9ee Binary files /dev/null and b/tests/ref_imgs_vg_lite/flex_wrap_grow_min_width.png differ diff --git a/tests/src/test_cases/test_align_flex.c b/tests/src/test_cases/test_align_flex.c index feb6cf8a6..6a8632393 100644 --- a/tests/src/test_cases/test_align_flex.c +++ b/tests/src/test_cases/test_align_flex.c @@ -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