diff --git a/scripts/properties.py b/scripts/properties.py index 790127c41..807e10388 100755 --- a/scripts/properties.py +++ b/scripts/properties.py @@ -45,7 +45,7 @@ def find_headers(directory): def read_widget_properties(directory): def match_properties(file_path): - pattern = r'^\s*LV_PROPERTY_ID\((\w+),\s*(\w+),\s*(\w+),\s*(\d+)\)' + pattern = r'^\s*LV_PROPERTY_ID2?\((\w+),\s*(\w+),\s*(\w+)(,\s*(\w+))?,\s*(\d+)\)' with open(file_path, 'r') as file: for line in file.readlines(): match = re.match(pattern, line) diff --git a/src/core/lv_obj_property.c b/src/core/lv_obj_property.c index 405b00674..7f45e6c7f 100644 --- a/src/core/lv_obj_property.c +++ b/src/core/lv_obj_property.c @@ -19,24 +19,72 @@ * DEFINES *********************/ +#define HANDLE_PROPERTY_TYPE(type, field) \ + if(!set) { \ + value->field = ((lv_property_get_##type##_t)(prop->getter))(obj); \ + } else { \ + switch(LV_PROPERTY_ID_TYPE2(prop->id)) { \ + case LV_PROPERTY_ID_INVALID: \ + ((lv_property_set_##type##_t)(prop->setter))(obj, value->field); \ + break; \ + case LV_PROPERTY_TYPE_INT: \ + ((lv_property_set_##type##_integer_t)(prop->setter))(obj, value->arg1.field, value->arg2.num); \ + break; \ + case LV_PROPERTY_TYPE_BOOL: \ + ((lv_property_set_##type##_boolean_t)(prop->setter))(obj, value->arg1.field, value->arg2.enable); \ + break; \ + case LV_PROPERTY_TYPE_PRECISE: \ + ((lv_property_set_##type##_precise_t)(prop->setter))(obj, value->arg1.field, value->arg2.precise); \ + break; \ + case LV_PROPERTY_TYPE_COLOR: \ + ((lv_property_set_##type##_color_t)(prop->setter))(obj, value->arg1.field, value->arg2.color); \ + break; \ + case LV_PROPERTY_TYPE_POINTER: \ + case LV_PROPERTY_TYPE_IMGSRC: \ + case LV_PROPERTY_TYPE_TEXT: \ + case LV_PROPERTY_TYPE_OBJ: \ + case LV_PROPERTY_TYPE_DISPLAY: \ + case LV_PROPERTY_TYPE_FONT: \ + ((lv_property_set_##type##_pointer_t)(prop->setter))(obj, value->arg1.field, value->arg2.ptr); \ + break; \ + } \ + } + + /********************** * TYPEDEFS **********************/ -typedef void (*lv_property_set_int_t)(lv_obj_t *, int32_t); -typedef void (*lv_property_set_bool_t)(lv_obj_t *, bool); -typedef void (*lv_property_set_precise_t)(lv_obj_t *, lv_value_precise_t); -typedef void (*lv_property_set_color_t)(lv_obj_t *, lv_color_t); +typedef int32_t integer; +typedef bool boolean; +typedef lv_value_precise_t precise; +typedef lv_color_t color; +typedef const void * pointer; + +#define DEFINE_PROPERTY_SETTER_TYPES(type) \ + typedef void (*lv_property_set_##type##_t)(lv_obj_t *, type); \ + typedef void (*lv_property_set_##type##_integer_t)(lv_obj_t *, type, int32_t); \ + typedef void (*lv_property_set_##type##_boolean_t)(lv_obj_t *, type, bool); \ + typedef void (*lv_property_set_##type##_precise_t)(lv_obj_t *, type, lv_value_precise_t); \ + typedef void (*lv_property_set_##type##_color_t)(lv_obj_t *, type, lv_color_t); \ + typedef void (*lv_property_set_##type##_pointer_t)(lv_obj_t *, type, const void *) + +DEFINE_PROPERTY_SETTER_TYPES(integer); +DEFINE_PROPERTY_SETTER_TYPES(boolean); +DEFINE_PROPERTY_SETTER_TYPES(precise); +DEFINE_PROPERTY_SETTER_TYPES(color); +DEFINE_PROPERTY_SETTER_TYPES(pointer); + typedef void (*lv_property_set_point_t)(lv_obj_t *, lv_point_t *); -typedef void (*lv_property_set_pointer_t)(lv_obj_t *, const void *); typedef lv_result_t (*lv_property_setter_t)(lv_obj_t *, lv_prop_id_t, const lv_property_t *); -typedef int32_t (*lv_property_get_int_t)(const lv_obj_t *); -typedef bool (*lv_property_get_bool_t)(const lv_obj_t *); +typedef integer(*lv_property_get_integer_t)(const lv_obj_t *); +typedef bool (*lv_property_get_boolean_t)(const lv_obj_t *); typedef lv_value_precise_t (*lv_property_get_precise_t)(const lv_obj_t *); typedef lv_color_t (*lv_property_get_color_t)(const lv_obj_t *); -typedef lv_point_t (*lv_property_get_point_t)(lv_obj_t *); typedef void * (*lv_property_get_pointer_t)(const lv_obj_t *); +typedef lv_point_t (*lv_property_get_point_t)(lv_obj_t *); + typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_property_t *); /********************** @@ -240,41 +288,30 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * if(!set) value->id = prop->id; switch(LV_PROPERTY_ID_TYPE(prop->id)) { - case LV_PROPERTY_TYPE_INT: { - if(set)((lv_property_set_int_t)(prop->setter))(obj, value->num); - else value->num = ((lv_property_get_int_t)(prop->getter))(obj); - break; - } - case LV_PROPERTY_TYPE_BOOL: { - if(set)((lv_property_set_bool_t)(prop->setter))(obj, value->enable); - else value->enable = ((lv_property_get_bool_t)(prop->getter))(obj); - break; - } - - case LV_PROPERTY_TYPE_PRECISE: { - if(set)((lv_property_set_precise_t)(prop->setter))(obj, value->precise); - else value->precise = ((lv_property_get_precise_t)(prop->getter))(obj); - break; - } - case LV_PROPERTY_TYPE_COLOR: { - if(set)((lv_property_set_color_t)prop->setter)(obj, value->color); - else value->color = ((lv_property_get_color_t)(prop->getter))(obj); - break; - } - case LV_PROPERTY_TYPE_POINT: { - lv_point_t * point = &value->point; - if(set)((lv_property_set_point_t)(prop->setter))(obj, point); - else *point = ((lv_property_get_point_t)(prop->getter))(obj); - break; - } + case LV_PROPERTY_TYPE_INT: + HANDLE_PROPERTY_TYPE(integer, num); + break; + case LV_PROPERTY_TYPE_BOOL: + HANDLE_PROPERTY_TYPE(boolean, enable); + break; + case LV_PROPERTY_TYPE_PRECISE: + HANDLE_PROPERTY_TYPE(precise, precise); + break; + case LV_PROPERTY_TYPE_COLOR: + HANDLE_PROPERTY_TYPE(color, color); + break; case LV_PROPERTY_TYPE_POINTER: case LV_PROPERTY_TYPE_IMGSRC: case LV_PROPERTY_TYPE_TEXT: case LV_PROPERTY_TYPE_OBJ: case LV_PROPERTY_TYPE_DISPLAY: - case LV_PROPERTY_TYPE_FONT: { - if(set)((lv_property_set_pointer_t)(prop->setter))(obj, value->ptr); - else value->ptr = ((lv_property_get_pointer_t)(prop->getter))(obj); + case LV_PROPERTY_TYPE_FONT: + HANDLE_PROPERTY_TYPE(pointer, ptr); + break; + case LV_PROPERTY_TYPE_POINT: { + lv_point_t * point = &value->point; + if(set)((lv_property_set_point_t)(prop->setter))(obj, point); + else *point = ((lv_property_get_point_t)(prop->getter))(obj); break; } default: { diff --git a/src/core/lv_obj_property.h b/src/core/lv_obj_property.h index 2053a5c21..09d04743b 100644 --- a/src/core/lv_obj_property.h +++ b/src/core/lv_obj_property.h @@ -37,9 +37,12 @@ extern "C" { #define LV_PROPERTY_TYPE_BOOL 11 /*int32_t type*/ #define LV_PROPERTY_TYPE_SHIFT 28 -#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << LV_PROPERTY_TYPE_SHIFT) +#define LV_PROPERTY_TYPE2_SHIFT 24 +#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << LV_PROPERTY_TYPE_SHIFT) +#define LV_PROPERTY_ID2(clz, name, type, type2, index) LV_PROPERTY_ID(clz, name, type, index) | ((type2) << LV_PROPERTY_TYPE2_SHIFT) #define LV_PROPERTY_ID_TYPE(id) ((id) >> LV_PROPERTY_TYPE_SHIFT) +#define LV_PROPERTY_ID_TYPE2(id) ((id) >> LV_PROPERTY_TYPE_SHIFT) #define LV_PROPERTY_ID_INDEX(id) ((id) & 0xfffffff) /*Set properties from an array of lv_property_t*/ @@ -68,6 +71,8 @@ enum { LV_PROPERTY_TEXTAREA_START = 0x0500, /* lv_textarea.c */ LV_PROPERTY_ROLLER_START = 0x0600, /* lv_roller.c */ LV_PROPERTY_DROPDOWN_START = 0x0700, /* lv_dropdown.c */ + LV_PROPERTY_SLIDER_START = 0x0800, /* lv_slider.c */ + LV_PROPERTY_ANIMIMAGE_START = 0x0900, /* lv_animimage.c */ /*Special ID, use it to extend ID and make sure it's unique and compile time determinant*/ LV_PROPERTY_ID_BUILTIN_LAST = 0xffff, /*ID of 0x10000 ~ 0xfffffff is reserved for user*/ @@ -84,11 +89,13 @@ typedef struct { lv_prop_id_t id; union { int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers)*/ + uint32_t num_u; bool enable; /**< booleans*/ const void * ptr; /**< Constant pointers (font, cone text, etc)*/ lv_color_t color; /**< Colors*/ lv_value_precise_t precise; /**< float or int for precise value*/ - lv_point_t point; /**< Point*/ + lv_point_t point; /**< Point, contains two int32_t.*/ + struct { /** * Note that place struct member `style` at first place is intended. @@ -113,6 +120,21 @@ typedef struct { lv_style_value_t style; /**< Make sure it's the first element in struct. */ uint32_t selector; /**< Style selector, lv_part_t | lv_state_t */ }; + + /** + * For some property like slider range, it contains two simple(4byte) value + * so we can use `arg1.num` and `arg2.num` to set the argument. + */ + struct { + union { + int32_t num; + uint32_t num_u; + bool enable; + const void * ptr; + lv_color_t color; + lv_value_precise_t precise; + } arg1, arg2; + }; }; } lv_property_t; diff --git a/src/widgets/roller/lv_roller.c b/src/widgets/roller/lv_roller.c index c826656e5..d242050ab 100644 --- a/src/widgets/roller/lv_roller.c +++ b/src/widgets/roller/lv_roller.c @@ -59,12 +59,12 @@ static void transform_vect_recursive(lv_obj_t * roller, lv_point_t * vect); static const lv_property_ops_t properties[] = { { .id = LV_PROPERTY_ROLLER_OPTIONS, - .setter = NULL, + .setter = lv_roller_set_options, .getter = lv_roller_get_options, }, { .id = LV_PROPERTY_ROLLER_SELECTED, - .setter = NULL, + .setter = lv_roller_set_selected, .getter = lv_roller_get_selected, }, { diff --git a/src/widgets/roller/lv_roller.h b/src/widgets/roller/lv_roller.h index 9a28dcf29..4c8cb3bda 100644 --- a/src/widgets/roller/lv_roller.h +++ b/src/widgets/roller/lv_roller.h @@ -40,9 +40,9 @@ typedef enum { #if LV_USE_OBJ_PROPERTY enum { - LV_PROPERTY_ID(ROLLER, OPTIONS, LV_PROPERTY_TYPE_TEXT, 0), - LV_PROPERTY_ID(ROLLER, SELECTED, LV_PROPERTY_TYPE_INT, 1), - LV_PROPERTY_ID(ROLLER, VISIBLE_ROW_COUNT, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID2(ROLLER, OPTIONS, LV_PROPERTY_TYPE_TEXT, LV_PROPERTY_TYPE_INT, 0), + LV_PROPERTY_ID2(ROLLER, SELECTED, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(ROLLER, VISIBLE_ROW_COUNT, LV_PROPERTY_TYPE_INT, 2), LV_PROPERTY_ROLLER_END, }; #endif diff --git a/tests/src/test_cases/widgets/test_roller.c b/tests/src/test_cases/widgets/test_roller.c index e04f0e57e..956ec9813 100644 --- a/tests/src/test_cases/widgets/test_roller.c +++ b/tests/src/test_cases/widgets/test_roller.c @@ -356,14 +356,16 @@ void test_roller_properties(void) lv_property_t prop = { }; prop.id = LV_PROPERTY_ROLLER_OPTIONS; - prop.ptr = "One\nTwo\nThree"; - lv_roller_set_options(obj, prop.ptr, LV_ROLLER_MODE_NORMAL); + prop.arg1.ptr = "One\nTwo\nThree"; + prop.arg2.num = LV_ROLLER_MODE_NORMAL; + TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK); TEST_ASSERT_EQUAL_STRING("One\nTwo\nThree", lv_roller_get_options(obj)); TEST_ASSERT_EQUAL_STRING("One\nTwo\nThree", lv_obj_get_property(obj, LV_PROPERTY_ROLLER_OPTIONS).ptr); prop.id = LV_PROPERTY_ROLLER_SELECTED; - prop.num = 1; - lv_roller_set_selected(obj, 1, LV_ANIM_OFF); + prop.arg1.num = 1; + prop.arg2.enable = LV_ANIM_ON; + TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK); TEST_ASSERT_EQUAL_INT(1, lv_roller_get_selected(obj)); TEST_ASSERT_EQUAL_INT(1, lv_obj_get_property(obj, LV_PROPERTY_ROLLER_SELECTED).num); #endif