fix(obj): fix crash with LV_SIZE_CONTENT parent and % positioned child (#7041)

This commit is contained in:
Attila Kiss
2024-11-12 06:26:04 +01:00
committed by GitHub
parent d3a685943c
commit 31226b9b95
2 changed files with 63 additions and 2 deletions

View File

@@ -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);

View File

@@ -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