diff --git a/src/core/lv_obj_pos.c b/src/core/lv_obj_pos.c index 398be7bee..e564f5913 100644 --- a/src/core/lv_obj_pos.c +++ b/src/core/lv_obj_pos.c @@ -626,8 +626,15 @@ void lv_obj_refr_pos(lv_obj_t * obj) /*Handle percentage value*/ int32_t pw = lv_obj_get_content_width(parent); int32_t ph = lv_obj_get_content_height(parent); - if(LV_COORD_IS_PCT(x)) x = (pw * LV_COORD_GET_PCT(x)) / 100; - if(LV_COORD_IS_PCT(y)) y = (ph * LV_COORD_GET_PCT(y)) / 100; + if(LV_COORD_IS_PCT(x)) { + if(lv_obj_get_style_width(parent, 0) == LV_SIZE_CONTENT) x = 0; /*Avoid circular dependency*/ + else x = (pw * LV_COORD_GET_PCT(x)) / 100; + } + + if(LV_COORD_IS_PCT(y)) { + if(lv_obj_get_style_height(parent, 0) == LV_SIZE_CONTENT) y = 0; /*Avoid circular dependency*/ + y = (ph * LV_COORD_GET_PCT(y)) / 100; + } /*Handle percentage value of translate*/ int32_t tr_x = lv_obj_get_style_translate_x(obj, LV_PART_MAIN); diff --git a/tests/src/test_cases/widgets/test_obj_pos.c b/tests/src/test_cases/widgets/test_obj_pos.c new file mode 100644 index 000000000..f7f2f8155 --- /dev/null +++ b/tests/src/test_cases/widgets/test_obj_pos.c @@ -0,0 +1,54 @@ +#if LV_BUILD_TEST +#include "../lvgl.h" +#include "../../lvgl_private.h" + +#include "unity/unity.h" + +void setUp(void) +{ + /* Function run before every test */ +} + +void tearDown(void) +{ + /* Function run after every test */ + lv_obj_clean(lv_screen_active()); +} + +/** + * See https://github.com/lvgl/lvgl/issues/6837 + */ +void test_content_parent_pct_child_pos_1(void) +{ + lv_obj_t * parent = lv_obj_create(lv_scr_act()); + lv_obj_set_pos(parent, 20, 20); + lv_obj_set_size(parent, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(parent, 10, 0); + + lv_obj_t * child1 = lv_obj_create(parent); + lv_obj_set_pos(child1, 100, 50); + lv_obj_set_size(child1, 100, 100); + + lv_obj_t * child2 = lv_obj_create(parent); + + /*Simple case*/ + lv_obj_set_size(child2, 50, 50); + lv_obj_set_pos(child2, 0, 0); + lv_obj_update_layout(child2); + TEST_ASSERT_EQUAL_INT32(0, lv_obj_get_x(child2)); + TEST_ASSERT_EQUAL_INT32(0, lv_obj_get_y(child2)); + + /*Simple case*/ + lv_obj_set_pos(child2, 30, 200); + lv_obj_update_layout(child2); + TEST_ASSERT_EQUAL_INT32(30, lv_obj_get_x(child2)); + TEST_ASSERT_EQUAL_INT32(200, lv_obj_get_y(child2)); + + /*x and y should be 0 to avoid circural dependency*/ + lv_obj_set_pos(child2, LV_PCT(10), LV_PCT(50)); + lv_obj_update_layout(child2); + TEST_ASSERT_EQUAL_INT32(0, lv_obj_get_x(child2)); + TEST_ASSERT_EQUAL_INT32(0, lv_obj_get_y(child2)); +} + +#endif