Repository: lvgl/lvgl (C)

Issue:
lv_obj_set_property() function not work correctly when using style properties.
### LVGL version

v9.0.0

### What happened?

The macro #define LV_PROPERTY_ID(clz, name, type, index)    LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << LV_PROPERTY_TYPE_SHIFT)
defines a property ID. But it does not store the real "index", it adds the property id start value to the index.
For example, the index of LV_STYLE_X is  8,  however the LV_PROPERTY_STYLE_X stores LV_STYLE_X + LV_PROPERTY_STYLE_START = 9. The problem will occur when set this property by using lv_obj_set_local_style_prop(), the second argument is the index of the style property.  
I think the code should be 
lv_obj_set_local_style_prop(obj, index - LV_PROPERTY_STYLE_START, value->style, value->selector);
instead of 
lv_obj_set_local_style_prop(obj, index, value->style, value->selector);

Anyone can help to check this ? 


### How to reproduce?

_No response_


Discussion: I think I have covered the case here.

https://github.com/lvgl/lvgl/blob/daa7fefb3a4bd058f1c5b5166871085876d0ada4/tests/src/test_cases/widgets/test_obj_property.c#L38-L44

The index value for style property, is the value from `enum _lv_style_prop_t`

See lv_style_properties.h

```c
enum {
    LV_PROPERTY_ID(STYLE, ALIGN,                    LV_PROPERTY_TYPE_INT,        LV_STYLE_ALIGN),
    LV_PROPERTY_ID(STYLE, ANIM,                     LV_PROPERTY_TYPE_INT,        LV_STYLE_ANIM),
...
```
Sorry. After check the test code, the prop.id is wrong.

You are right. The style enum is offset by 1.
> Sorry. After check the test code, the prop.id is wrong.
> 
> You are right. The style enum is offset by 1.

prop.id = LV_STYLE_X;  // this works. 
prop.id = LV_PROPERTY_STYLE_X; // this doesn't work.

It looks your test case is not correct.

the STYLE property already starts from 1, so when making the PROPERTY_STYLE_X, we don't need to add the STYLE PROPERTY START ID.  

If we need to add the STYLE PROPERTY START ID to identify it is a style property, we need to substract the STYLE PROPERTY START ID when using it. 

Since I'm not familiar with the style subsystem design, could you help to check which solution is the best for this case ?  

I drafted a fix, could you please check if it works for you?
> I drafted a fix, could you please check if it works for you?

It works. Thank you.



Fix (patch):
diff --git a/src/core/lv_obj_property.c b/src/core/lv_obj_property.c
index 4a60e0c5d2ad..4c24de997797 100644
--- a/src/core/lv_obj_property.c
+++ b/src/core/lv_obj_property.c
@@ -59,7 +59,7 @@ lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value)
     LV_ASSERT(obj && value);
 
     uint32_t index = LV_PROPERTY_ID_INDEX(value->id);
-    if(value->id == LV_PROPERTY_ID_INVALID || index < LV_PROPERTY_STYLE_START || index >= LV_PROPERTY_ID_BUILTIN_LAST) {
+    if(value->id == LV_PROPERTY_ID_INVALID || index >= LV_PROPERTY_ID_BUILTIN_LAST) {
         LV_LOG_WARN("Invalid property id set to %p", obj);
         return LV_RESULT_INVALID;
     }
@@ -90,7 +90,7 @@ lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id)
     lv_property_t value;
 
     uint32_t index = LV_PROPERTY_ID_INDEX(id);
-    if(id == LV_PROPERTY_ID_INVALID || index < LV_PROPERTY_STYLE_START || index >= LV_PROPERTY_ID_BUILTIN_LAST) {
+    if(id == LV_PROPERTY_ID_INVALID || index >= LV_PROPERTY_ID_BUILTIN_LAST) {
         LV_LOG_WARN("Invalid property id to get from %p", obj);
         value.id = LV_PROPERTY_ID_INVALID;
         value.num = 0;
@@ -114,8 +114,9 @@ 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)
 {
     lv_property_t value;
+    uint32_t index = LV_PROPERTY_ID_INDEX(id);
 
-    if(id == LV_PROPERTY_ID_INVALID || id >= LV_PROPERTY_ID_START) {
+    if(index == LV_PROPERTY_ID_INVALID || index >= LV_PROPERTY_ID_START) {
         LV_LOG_WARN("invalid style property id %d", id);
         value.id = LV_PROPERTY_ID_INVALID;
         value.num = 0;
diff --git a/src/core/lv_obj_property.h b/src/core/lv_obj_property.h
index 778a0a35cda1..5642892d5b57 100644
--- a/src/core/lv_obj_property.h
+++ b/src/core/lv_obj_property.h
@@ -56,15 +56,15 @@ enum {
     LV_PROPERTY_ID_INVALID      = 0,
 
     /*ID 0x01 to 0xff are style ID, check lv_style_prop_t*/
-    LV_PROPERTY_STYLE_START     = 0x01,
+    LV_PROPERTY_STYLE_START     = 0x00,
 
-    LV_PROPERTY_ID_START        = 0x100, /*ID little than 0xff is style ID*/
+    LV_PROPERTY_ID_START        = 0x0100, /*ID smaller than 0xff is style ID*/
     /*Define the property ID for every widget here. */
-    LV_PROPERTY_OBJ_START       = 0x100, /* lv_obj.c */
-    LV_PROPERTY_IMAGE_START     = 0x200, /* lv_image.c */
+    LV_PROPERTY_OBJ_START       = 0x0100, /* lv_obj.c */
+    LV_PROPERTY_IMAGE_START     = 0x0200, /* lv_image.c */
 
     /*Special ID, use it to extend ID and make sure it's unique and compile time determinant*/
-    LV_PROPERTY_ID_BUILTIN_LAST = 0x10000000,
+    LV_PROPERTY_ID_BUILTIN_LAST = 0xffff, /*ID of 0x10000 ~ 0xfffffff is reserved for user*/
 
     /*Special ID used by lvgl to intercept all setter/getter call.*/
     LV_PROPERTY_ID_ANY          = 0x7ffffffe,