1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 #include "../../lvgl_private.h"
4 
5 #include "unity/unity.h"
6 
test_obj_property_fail_on_invalid_id(void)7 void test_obj_property_fail_on_invalid_id(void)
8 {
9 #if LV_USE_OBJ_PROPERTY
10     lv_obj_t * obj = lv_obj_create(lv_screen_active());
11     lv_property_t prop = { };
12 
13     prop.id = LV_PROPERTY_ID_INVALID;
14     TEST_ASSERT_EQUAL_INT(LV_RESULT_INVALID, lv_obj_set_property(obj, &prop));
15 
16     prop.id = LV_PROPERTY_ID_BUILTIN_LAST; /* No widget use this ID */
17     TEST_ASSERT_EQUAL_INT(LV_RESULT_INVALID, lv_obj_set_property(obj, &prop));
18 
19     prop.id = LV_PROPERTY_OBJ_PARENT + 1; /* Not a valid ID for obj */
20     TEST_ASSERT_EQUAL_INT(LV_RESULT_INVALID, lv_obj_set_property(obj, &prop));
21 
22     prop.id = LV_PROPERTY_IMAGE_OFFSET_X; /* Not an ID for obj but for image */
23     TEST_ASSERT_EQUAL_INT(LV_RESULT_INVALID, lv_obj_set_property(obj, &prop));
24 
25     prop.id = LV_PROPERTY_OBJ_PARENT; /* Valid ID */
26     prop.ptr = lv_screen_active();
27     TEST_ASSERT_EQUAL_INT(LV_RESULT_OK, lv_obj_set_property(obj, &prop));
28 #endif
29 }
30 
test_obj_property_set_get_should_match(void)31 void test_obj_property_set_get_should_match(void)
32 {
33 #if LV_USE_OBJ_PROPERTY
34     lv_obj_t * obj = lv_obj_create(lv_screen_active());
35     lv_obj_t * root = lv_obj_create(lv_screen_active());
36     lv_property_t prop = { };
37     lv_color_t color = {.red = 0x11, .green = 0x22, .blue = 0x33};
38 
39     /* Style property should work */
40     /* int type */
41     prop.id = LV_PROPERTY_STYLE_X;
42     prop.num = 0xaabb;
43     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
44     TEST_ASSERT_EQUAL_UINT32(0xaabb, lv_obj_get_style_x(obj, 0));
45     TEST_ASSERT_EQUAL_UINT32(0xaabb, lv_obj_get_property(obj, LV_PROPERTY_STYLE_X).num);
46 
47     /* color type */
48     prop.id = LV_PROPERTY_STYLE_BG_COLOR;
49     prop.color = color;
50     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
51     TEST_ASSERT_EQUAL_COLOR(color, lv_obj_get_style_bg_color(obj, LV_PART_MAIN));
52     TEST_ASSERT_EQUAL_COLOR(color, lv_obj_get_property(obj, LV_PROPERTY_STYLE_BG_COLOR).color);
53 
54     /* pointer type */
55     prop.id = LV_PROPERTY_STYLE_TEXT_FONT;
56     prop.ptr = &lv_font_montserrat_26;
57     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
58     TEST_ASSERT_EQUAL_PTR(&lv_font_montserrat_26, lv_obj_get_style_text_font(obj, LV_PART_MAIN));
59     TEST_ASSERT_EQUAL_PTR(&lv_font_montserrat_26, lv_obj_get_property(obj, LV_PROPERTY_STYLE_TEXT_FONT).ptr);
60 
61     /* Object flags */
62     prop.id = LV_PROPERTY_OBJ_FLAG_HIDDEN ;
63     prop.num = 1;
64     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
65     TEST_ASSERT_TRUE(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN));
66     TEST_ASSERT_TRUE(lv_obj_get_property(obj, LV_PROPERTY_OBJ_FLAG_HIDDEN).num);
67 
68     prop.id = LV_PROPERTY_OBJ_FLAG_CLICKABLE;
69     prop.num = 0;
70     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
71     TEST_ASSERT_FALSE(lv_obj_has_flag(obj, LV_OBJ_FLAG_CLICKABLE));
72     TEST_ASSERT_FALSE(lv_obj_get_property(obj, LV_PROPERTY_OBJ_FLAG_CLICKABLE).num);
73 
74     /* Obj property */
75     prop.id = LV_PROPERTY_OBJ_PARENT;
76     prop.ptr = root;
77     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
78     TEST_ASSERT_EQUAL_PTR(root, lv_obj_get_parent(obj));
79     TEST_ASSERT_EQUAL_PTR(root, lv_obj_get_property(obj, LV_PROPERTY_OBJ_PARENT).ptr);
80 
81     /* Derived widget could use same property */
82     lv_obj_t * img = lv_image_create(obj);
83     prop.id = LV_PROPERTY_OBJ_PARENT;
84     prop.ptr = root;
85     TEST_ASSERT_TRUE(lv_obj_set_property(img, &prop) == LV_RESULT_OK);
86     TEST_ASSERT_EQUAL_PTR(root, lv_obj_get_parent(img));
87     TEST_ASSERT_EQUAL_PTR(root, lv_obj_get_property(img, LV_PROPERTY_OBJ_PARENT).ptr);
88 
89     /* Image properties */
90     prop.id = LV_PROPERTY_IMAGE_OFFSET_X;
91     prop.num = 0x1234;
92     TEST_ASSERT_TRUE(lv_obj_set_property(img, &prop) == LV_RESULT_OK);
93     TEST_ASSERT_EQUAL_UINT16(0x1234, lv_image_get_offset_x(img));
94     TEST_ASSERT_EQUAL_UINT16(0x1234, lv_obj_get_property(img, LV_PROPERTY_IMAGE_OFFSET_X).num);
95 #endif
96 }
97 
test_obj_property_style_selector(void)98 void test_obj_property_style_selector(void)
99 {
100 #if LV_USE_OBJ_PROPERTY
101     lv_obj_t * obj = lv_obj_create(lv_screen_active());
102     lv_property_t prop = { };
103 
104     /* Style property with default selector(0) should work */
105     prop.id = LV_PROPERTY_STYLE_X;
106     prop.num = 0xaabb;  /* `num` shares same memory with `prop.style.value.num` */
107     /* selector is initialed to zero when prop is defined. */
108     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
109     TEST_ASSERT_EQUAL_UINT32(0xaabb, lv_obj_get_style_x(obj, 0));
110     TEST_ASSERT_EQUAL_UINT32(0xaabb, lv_obj_get_style_property(obj, LV_PROPERTY_STYLE_X, 0).num);
111 
112     lv_style_selector_t selector = LV_PART_MAIN | LV_STATE_PRESSED;
113     prop.id = LV_PROPERTY_STYLE_X;
114     prop.num = 0x1122;
115     prop.selector = selector;
116     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
117     TEST_ASSERT_EQUAL_UINT32(0x1122, lv_obj_get_style_x(obj, selector));
118     TEST_ASSERT_EQUAL_UINT32(0x1122, lv_obj_get_style_property(obj, LV_PROPERTY_STYLE_X, selector).num);
119 #endif
120 }
121 
test_obj_property_flag(void)122 void test_obj_property_flag(void)
123 {
124 #if LV_USE_OBJ_PROPERTY
125     const struct {
126         uint32_t flag;
127         uint32_t id;
128     } properties[] = {
129         { LV_OBJ_FLAG_HIDDEN,                    LV_PROPERTY_OBJ_FLAG_HIDDEN },
130         { LV_OBJ_FLAG_CLICKABLE,                 LV_PROPERTY_OBJ_FLAG_CLICKABLE },
131         { LV_OBJ_FLAG_CLICK_FOCUSABLE,           LV_PROPERTY_OBJ_FLAG_CLICK_FOCUSABLE },
132         { LV_OBJ_FLAG_CHECKABLE,                 LV_PROPERTY_OBJ_FLAG_CHECKABLE },
133         { LV_OBJ_FLAG_SCROLLABLE,                LV_PROPERTY_OBJ_FLAG_SCROLLABLE },
134         { LV_OBJ_FLAG_SCROLL_ELASTIC,            LV_PROPERTY_OBJ_FLAG_SCROLL_ELASTIC },
135         { LV_OBJ_FLAG_SCROLL_MOMENTUM,           LV_PROPERTY_OBJ_FLAG_SCROLL_MOMENTUM },
136         { LV_OBJ_FLAG_SCROLL_ONE,                LV_PROPERTY_OBJ_FLAG_SCROLL_ONE },
137         { LV_OBJ_FLAG_SCROLL_CHAIN_HOR,          LV_PROPERTY_OBJ_FLAG_SCROLL_CHAIN_HOR },
138         { LV_OBJ_FLAG_SCROLL_CHAIN_VER,          LV_PROPERTY_OBJ_FLAG_SCROLL_CHAIN_VER },
139         { LV_OBJ_FLAG_SCROLL_ON_FOCUS,           LV_PROPERTY_OBJ_FLAG_SCROLL_ON_FOCUS },
140         { LV_OBJ_FLAG_SCROLL_WITH_ARROW,         LV_PROPERTY_OBJ_FLAG_SCROLL_WITH_ARROW },
141         { LV_OBJ_FLAG_SNAPPABLE,                 LV_PROPERTY_OBJ_FLAG_SNAPPABLE },
142         { LV_OBJ_FLAG_PRESS_LOCK,                LV_PROPERTY_OBJ_FLAG_PRESS_LOCK },
143         { LV_OBJ_FLAG_EVENT_BUBBLE,              LV_PROPERTY_OBJ_FLAG_EVENT_BUBBLE },
144         { LV_OBJ_FLAG_GESTURE_BUBBLE,            LV_PROPERTY_OBJ_FLAG_GESTURE_BUBBLE },
145         { LV_OBJ_FLAG_ADV_HITTEST,               LV_PROPERTY_OBJ_FLAG_ADV_HITTEST },
146         { LV_OBJ_FLAG_IGNORE_LAYOUT,             LV_PROPERTY_OBJ_FLAG_IGNORE_LAYOUT },
147         { LV_OBJ_FLAG_FLOATING,                  LV_PROPERTY_OBJ_FLAG_FLOATING },
148         { LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS,     LV_PROPERTY_OBJ_FLAG_SEND_DRAW_TASK_EVENTS },
149         { LV_OBJ_FLAG_OVERFLOW_VISIBLE,          LV_PROPERTY_OBJ_FLAG_OVERFLOW_VISIBLE },
150         { LV_OBJ_FLAG_FLEX_IN_NEW_TRACK,         LV_PROPERTY_OBJ_FLAG_FLEX_IN_NEW_TRACK },
151         { LV_OBJ_FLAG_LAYOUT_1,                  LV_PROPERTY_OBJ_FLAG_LAYOUT_1 },
152         { LV_OBJ_FLAG_LAYOUT_2,                  LV_PROPERTY_OBJ_FLAG_LAYOUT_2 },
153         { LV_OBJ_FLAG_WIDGET_1,                  LV_PROPERTY_OBJ_FLAG_WIDGET_1 },
154         { LV_OBJ_FLAG_WIDGET_2,                  LV_PROPERTY_OBJ_FLAG_WIDGET_2 },
155         { LV_OBJ_FLAG_USER_1,                    LV_PROPERTY_OBJ_FLAG_USER_1 },
156         { LV_OBJ_FLAG_USER_2,                    LV_PROPERTY_OBJ_FLAG_USER_2 },
157         { LV_OBJ_FLAG_USER_3,                    LV_PROPERTY_OBJ_FLAG_USER_3 },
158         { LV_OBJ_FLAG_USER_4,                    LV_PROPERTY_OBJ_FLAG_USER_4 },
159     };
160 
161     lv_obj_t * obj = lv_obj_create(lv_screen_active());
162     obj->flags = 0;
163     for(unsigned long i = 0; i < sizeof(properties) / sizeof(properties[0]); i++) {
164 
165         TEST_ASSERT_FALSE(lv_obj_get_property(obj, properties[i].id).num);
166         lv_obj_add_flag(obj, properties[i].flag);
167         TEST_ASSERT_TRUE(lv_obj_get_property(obj, properties[i].id).num);
168 
169         lv_obj_remove_flag(obj, properties[i].flag);
170         TEST_ASSERT_FALSE(lv_obj_get_property(obj, properties[i].id).num);
171 
172         lv_property_t prop = { };
173         prop.id = properties[i].id;
174         prop.num = 1;
175         TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
176         TEST_ASSERT_TRUE(lv_obj_get_property(obj, properties[i].id).num);
177         TEST_ASSERT_TRUE(lv_obj_has_flag(obj, properties[i].flag));
178 
179         prop.id = properties[i].id;
180         prop.num = 0;
181         TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
182         TEST_ASSERT_FALSE(lv_obj_get_property(obj, properties[i].id).num);
183         TEST_ASSERT_FALSE(lv_obj_has_flag(obj, properties[i].flag));
184     }
185 #endif
186 }
187 
test_obj_property_state(void)188 void test_obj_property_state(void)
189 {
190 #if LV_USE_OBJ_PROPERTY
191     const struct {
192         uint32_t state;
193         uint32_t id;
194     } states[] = {
195         { LV_STATE_CHECKED,     LV_PROPERTY_OBJ_STATE_CHECKED },
196         { LV_STATE_FOCUSED,     LV_PROPERTY_OBJ_STATE_FOCUSED },
197         { LV_STATE_FOCUS_KEY,   LV_PROPERTY_OBJ_STATE_FOCUS_KEY },
198         { LV_STATE_EDITED,      LV_PROPERTY_OBJ_STATE_EDITED },
199         { LV_STATE_HOVERED,     LV_PROPERTY_OBJ_STATE_HOVERED },
200         { LV_STATE_PRESSED,     LV_PROPERTY_OBJ_STATE_PRESSED },
201         { LV_STATE_SCROLLED,    LV_PROPERTY_OBJ_STATE_SCROLLED },
202         { LV_STATE_DISABLED,    LV_PROPERTY_OBJ_STATE_DISABLED },
203         { LV_STATE_USER_1,      LV_PROPERTY_OBJ_STATE_USER_1 },
204         { LV_STATE_USER_2,      LV_PROPERTY_OBJ_STATE_USER_2 },
205         { LV_STATE_USER_3,      LV_PROPERTY_OBJ_STATE_USER_3 },
206         { LV_STATE_USER_4,      LV_PROPERTY_OBJ_STATE_USER_4 },
207     };
208 
209     lv_obj_t * obj = lv_obj_create(lv_screen_active());
210     obj->state = 0;
211     for(unsigned long i = 0; i < sizeof(states) / sizeof(states[0]); i++) {
212         TEST_ASSERT_FALSE(lv_obj_get_property(obj, states[i].id).num);
213         lv_obj_add_state(obj, states[i].state);
214         printf("state: %d, value: %d\n", states[i].state, lv_obj_get_property(obj, states[i].id).num);
215         TEST_ASSERT_TRUE(lv_obj_get_property(obj, states[i].id).num);
216 
217         lv_obj_remove_state(obj, states[i].state);
218         TEST_ASSERT_FALSE(lv_obj_get_property(obj, states[i].id).num);
219 
220         lv_property_t prop = { };
221         prop.id = states[i].id;
222         prop.num = 1;
223         TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
224         TEST_ASSERT_TRUE(lv_obj_get_property(obj, states[i].id).num);
225         TEST_ASSERT_TRUE(lv_obj_get_state(obj) & states[i].state);
226 
227         prop.id = states[i].id;
228         prop.num = 0;
229         TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
230         TEST_ASSERT_FALSE(lv_obj_get_property(obj, states[i].id).num);
231         TEST_ASSERT_FALSE(lv_obj_get_state(obj) & states[i].state);
232     }
233 #endif
234 }
235 
test_obj_property_type_point(void)236 void test_obj_property_type_point(void)
237 {
238 #if LV_USE_OBJ_PROPERTY
239     lv_obj_t * obj = lv_image_create(lv_screen_active());
240     lv_property_t prop = { };
241 
242     prop.id = LV_PROPERTY_IMAGE_PIVOT;
243     prop.point.x = 0x1234;
244     prop.point.y = 0x5678;
245 
246     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
247     lv_property_t prop_get = lv_obj_get_property(obj, LV_PROPERTY_IMAGE_PIVOT);
248     TEST_ASSERT_EQUAL_UINT16(0x1234, prop_get.point.x);
249     TEST_ASSERT_EQUAL_UINT16(0x5678, prop_get.point.y);
250 #endif
251 }
252 
test_obj_property_name(void)253 void test_obj_property_name(void)
254 {
255 #if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME
256     lv_obj_t * obj = lv_obj_create(lv_screen_active());
257 
258     /*Style name*/
259     /*If widget property name conflicts with style name, property name comes first.*/
260     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_X, lv_obj_property_get_id(obj, "x"));
261     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_STYLE_OPA, lv_obj_property_get_id(obj, "opa"));
262     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_STYLE_BG_MAIN_STOP, lv_obj_property_get_id(obj, "bg_main_stop"));
263 
264     /*Widget property*/
265     obj = lv_image_create(lv_screen_active());
266     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_IMAGE_ANTIALIAS, lv_obj_property_get_id(obj, "antialias"));
267     /*Base class property*/
268     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_PARENT, lv_obj_property_get_id(obj, "parent"));
269 
270     /*OBJ flags*/
271     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_FLAG_CLICKABLE, lv_obj_property_get_id(obj, "flag_clickable"));
272 #endif
273 }
274 
test_obj_class_property(void)275 void test_obj_class_property(void)
276 {
277 #if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME
278     /* An image obj has align property */
279     lv_obj_t * img = lv_image_create(lv_screen_active());
280     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_ALIGN, lv_obj_property_get_id(img, "align"));
281 
282     /* obj class has align property but image doesn't. */
283     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_ALIGN, lv_obj_class_property_get_id(&lv_obj_class, "align"));
284     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_ID_INVALID, lv_obj_class_property_get_id(&lv_image_class, "align"));
285 
286     /* style can also have property name that conflicts with obj */
287     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_STYLE_X, lv_style_property_get_id("x"));
288     TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_X, lv_obj_property_get_id(img, "x"));
289 #endif
290 }
291 
test_label_properties(void)292 void test_label_properties(void)
293 {
294 #if LV_USE_OBJ_PROPERTY
295     lv_obj_t * obj = lv_label_create(lv_screen_active());
296     lv_property_t prop = { };
297 
298     prop.id = LV_PROPERTY_LABEL_TEXT;
299     prop.ptr = "Hello world";
300     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
301     TEST_ASSERT_EQUAL_STRING("Hello world", lv_label_get_text(obj));
302     TEST_ASSERT_EQUAL_STRING("Hello world", lv_obj_get_property(obj, LV_PROPERTY_LABEL_TEXT).ptr);
303 
304     prop.id = LV_PROPERTY_LABEL_LONG_MODE;
305     prop.num = LV_LABEL_LONG_MODE_SCROLL;
306     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
307     TEST_ASSERT_EQUAL_INT(LV_LABEL_LONG_MODE_SCROLL, lv_label_get_long_mode(obj));
308     TEST_ASSERT_EQUAL_INT(LV_LABEL_LONG_MODE_SCROLL, lv_obj_get_property(obj, LV_PROPERTY_LABEL_LONG_MODE).num);
309 
310 #if LV_LABEL_TEXT_SELECTION
311     prop.id = LV_PROPERTY_LABEL_TEXT_SELECTION_START;
312     prop.num = 2;
313     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
314     TEST_ASSERT_EQUAL_INT(2, lv_label_get_text_selection_start(obj));
315     TEST_ASSERT_EQUAL_INT(2, lv_obj_get_property(obj, LV_PROPERTY_LABEL_TEXT_SELECTION_START).num);
316 
317     prop.id = LV_PROPERTY_LABEL_TEXT_SELECTION_END;
318     prop.num = 5;
319     TEST_ASSERT_TRUE(lv_obj_set_property(obj, &prop) == LV_RESULT_OK);
320     TEST_ASSERT_EQUAL_INT(5, lv_label_get_text_selection_end(obj));
321     TEST_ASSERT_EQUAL_INT(5, lv_obj_get_property(obj, LV_PROPERTY_LABEL_TEXT_SELECTION_END).num);
322 #endif
323 #endif
324 }
325 
326 #endif
327