mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 04:37:55 +08:00
fix(objid): free old id before assign new one (#6697)
Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
This commit is contained in:
@@ -33,6 +33,7 @@ Below APIs needed to be implemented and linked to lvgl.
|
||||
|
||||
.. code:: c
|
||||
|
||||
void lv_obj_set_id(lv_obj_t * obj, void * id);
|
||||
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
void lv_obj_free_id(lv_obj_t * obj);
|
||||
const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len);
|
||||
|
||||
+1
-7
@@ -433,19 +433,13 @@ void lv_obj_null_on_delete(lv_obj_t ** obj_ptr)
|
||||
}
|
||||
|
||||
#if LV_USE_OBJ_ID
|
||||
void lv_obj_set_id(lv_obj_t * obj, void * id)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
obj->id = id;
|
||||
}
|
||||
|
||||
void * lv_obj_get_id(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
return obj->id;
|
||||
}
|
||||
|
||||
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id)
|
||||
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id)
|
||||
{
|
||||
if(obj == NULL) obj = lv_display_get_screen_active(NULL);
|
||||
if(obj == NULL) return NULL;
|
||||
|
||||
+5
-5
@@ -407,14 +407,14 @@ void * lv_obj_get_id(const lv_obj_t * obj);
|
||||
* @param id the id of the child object
|
||||
* @return pointer to the child object or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id);
|
||||
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id);
|
||||
|
||||
/**
|
||||
* Assign id to object if not previously assigned.
|
||||
* This function gets called automatically when LV_OBJ_ID_AUTO_ASSIGN is enabled.
|
||||
*
|
||||
* Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method to generate object ID.
|
||||
* Otherwise, these functions including `lv_obj_[assign|free|stringify]_id` and
|
||||
* Otherwise, these functions including `lv_obj_[set|assign|free|stringify]_id` and
|
||||
* `lv_obj_id_compare`should be implemented externally.
|
||||
*
|
||||
* @param class_p the class this obj belongs to. Note obj->class_p is the class currently being constructed.
|
||||
@@ -423,8 +423,8 @@ lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id);
|
||||
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Free resources allocated by `lv_obj_assign_id`.
|
||||
* This function gets called automatically when object is deleted.
|
||||
* Free resources allocated by `lv_obj_assign_id` or `lv_obj_set_id`.
|
||||
* This function is also called automatically when object is deleted.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_free_id(lv_obj_t * obj);
|
||||
@@ -439,7 +439,7 @@ void lv_obj_free_id(lv_obj_t * obj);
|
||||
* @param id2: the second id
|
||||
* @return 0 if they are equal, non-zero otherwise.
|
||||
*/
|
||||
int lv_obj_id_compare(void * id1, void * id2);
|
||||
int lv_obj_id_compare(const void * id1, const void * id2);
|
||||
|
||||
/**
|
||||
* Format an object's id into a string.
|
||||
|
||||
@@ -79,9 +79,17 @@ void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
obj->id = (void *)(lv_uintptr_t)id;
|
||||
}
|
||||
|
||||
void lv_obj_set_id(lv_obj_t * obj, void * id)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
if(obj->id) lv_obj_free_id(obj);
|
||||
obj->id = id;
|
||||
}
|
||||
|
||||
void lv_obj_free_id(lv_obj_t * obj)
|
||||
{
|
||||
LV_UNUSED(obj);
|
||||
obj->id = NULL;
|
||||
}
|
||||
|
||||
const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len)
|
||||
@@ -106,7 +114,7 @@ void lv_objid_builtin_destroy(void)
|
||||
global->objid_count = 0;
|
||||
}
|
||||
|
||||
int lv_obj_id_compare(void * id1, void * id2)
|
||||
int lv_obj_id_compare(const void * id1, const void * id2)
|
||||
{
|
||||
return id1 == id2 ? 0 : 1;
|
||||
}
|
||||
|
||||
+43
-15
@@ -133,28 +133,56 @@ lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_
|
||||
return value;
|
||||
}
|
||||
|
||||
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name)
|
||||
lv_prop_id_t lv_style_property_get_id(const char * name)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY_NAME
|
||||
const lv_obj_class_t * clz;
|
||||
const lv_property_name_t * names;
|
||||
lv_property_name_t * found;
|
||||
|
||||
for(clz = obj->class_p; clz; clz = clz->base_class) {
|
||||
names = clz->property_names;
|
||||
if(names == NULL) {
|
||||
/* try base class*/
|
||||
continue;
|
||||
}
|
||||
|
||||
found = lv_utils_bsearch(name, names, clz->names_count, sizeof(lv_property_name_t), property_name_compare);
|
||||
if(found) return found->id;
|
||||
}
|
||||
|
||||
/*Check style property*/
|
||||
found = lv_utils_bsearch(name, lv_style_property_names, sizeof(lv_style_property_names) / sizeof(lv_property_name_t),
|
||||
sizeof(lv_property_name_t), property_name_compare);
|
||||
if(found) return found->id;
|
||||
#else
|
||||
LV_UNUSED(name);
|
||||
#endif
|
||||
return LV_PROPERTY_ID_INVALID;
|
||||
}
|
||||
|
||||
lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY_NAME
|
||||
const lv_property_name_t * names;
|
||||
lv_property_name_t * found;
|
||||
|
||||
names = clz->property_names;
|
||||
if(names == NULL) {
|
||||
/* try base class*/
|
||||
return LV_PROPERTY_ID_INVALID;
|
||||
}
|
||||
|
||||
found = lv_utils_bsearch(name, names, clz->names_count, sizeof(lv_property_name_t), property_name_compare);
|
||||
if(found) return found->id;
|
||||
#else
|
||||
LV_UNUSED(obj);
|
||||
LV_UNUSED(name);
|
||||
LV_UNUSED(property_name_compare);
|
||||
#endif
|
||||
return LV_PROPERTY_ID_INVALID;
|
||||
}
|
||||
|
||||
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY_NAME
|
||||
const lv_obj_class_t * clz;
|
||||
lv_prop_id_t id;
|
||||
|
||||
for(clz = obj->class_p; clz; clz = clz->base_class) {
|
||||
id = lv_obj_class_property_get_id(clz, name);
|
||||
if(id != LV_PROPERTY_ID_INVALID) return id;
|
||||
}
|
||||
|
||||
/*Check style property*/
|
||||
id = lv_style_property_get_id(name);
|
||||
if(id != LV_PROPERTY_ID_INVALID) return id;
|
||||
#else
|
||||
LV_UNUSED(obj);
|
||||
LV_UNUSED(name);
|
||||
|
||||
@@ -98,14 +98,14 @@ typedef struct {
|
||||
* E.g.
|
||||
*
|
||||
* static const lv_property_t obj_pos_x = {
|
||||
* .id = LV_STYLE_X,
|
||||
* .id = LV_PROPERTY_STYLE_X,
|
||||
* .num = 123,
|
||||
* .selector = LV_STATE_PRESSED,
|
||||
* }
|
||||
*
|
||||
* instead of:
|
||||
* static const lv_property_t obj_pos_x = {
|
||||
* .id = LV_STYLE_X,
|
||||
* .id = LV_PROPERTY_STYLE_X,
|
||||
* .style.num = 123, // note this line.
|
||||
* .selector = LV_STATE_PRESSED,
|
||||
* }
|
||||
@@ -171,13 +171,28 @@ lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id);
|
||||
lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector);
|
||||
|
||||
/**
|
||||
* Get the property ID by name. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
|
||||
* Get the property ID by name recursively to base classes. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
|
||||
* @param obj pointer to an object that has specified property or base class has.
|
||||
* @param name property name
|
||||
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
|
||||
*/
|
||||
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name);
|
||||
|
||||
/**
|
||||
* Get the property ID by name without check base class recursively. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
|
||||
* @param clz pointer to an object class that has specified property or base class has.
|
||||
* @param name property name
|
||||
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
|
||||
*/
|
||||
lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name);
|
||||
|
||||
/**
|
||||
* Get the style property ID by name. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
|
||||
* @param name property name
|
||||
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
|
||||
*/
|
||||
lv_prop_id_t lv_style_property_get_id(const char * name);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -272,6 +272,23 @@ void test_obj_property_name(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_obj_class_property(void)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME
|
||||
/* An image obj has align property */
|
||||
lv_obj_t * img = lv_image_create(lv_screen_active());
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_ALIGN, lv_obj_property_get_id(img, "align"));
|
||||
|
||||
/* obj class has align property but image doesn't. */
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_ALIGN, lv_obj_class_property_get_id(&lv_obj_class, "align"));
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_ID_INVALID, lv_obj_class_property_get_id(&lv_image_class, "align"));
|
||||
|
||||
/* style can also have property name that conflicts with obj */
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_STYLE_X, lv_style_property_get_id("x"));
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_X, lv_obj_property_get_id(img, "x"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_label_properties(void)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
|
||||
Reference in New Issue
Block a user