1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 #include "../../lvgl_private.h"
4
5 #include "unity/unity.h"
6 #include "lv_test_indev.h"
7
8 /* This function runs before each test */
9 void setUp(void);
10
11 void test_arc_creation_successful(void);
12 void test_arc_should_truncate_to_max_range_when_new_value_exceeds_it(void);
13 void test_arc_should_truncate_to_min_range_when_new_value_is_inferior(void);
14 void test_arc_should_update_value_after_updating_range(void);
15 void test_arc_should_update_angles_when_changing_to_symmetrical_mode(void);
16 void test_arc_should_update_angles_when_changing_to_symmetrical_mode_value_more_than_middle_range(void);
17 void test_arc_angles_when_reversed(void);
18
19 static lv_obj_t * active_screen = NULL;
20 static lv_obj_t * arc = NULL;
21 static lv_obj_t * arc2 = NULL;
22 static uint32_t event_cnt;
23 static uint32_t event_cnt2;
24
25 static void dummy_event_cb(lv_event_t * e);
26 static void dummy_event_cb2(lv_event_t * e);
27
setUp(void)28 void setUp(void)
29 {
30 active_screen = lv_screen_active();
31 }
32
tearDown(void)33 void tearDown(void)
34 {
35 lv_obj_clean(active_screen);
36 lv_obj_set_style_layout(active_screen, LV_LAYOUT_NONE, 0);
37 }
38
test_arc_creation_successful(void)39 void test_arc_creation_successful(void)
40 {
41 arc = lv_arc_create(active_screen);
42
43 TEST_ASSERT_NOT_NULL(arc);
44 }
45
test_arc_basic_render(void)46 void test_arc_basic_render(void)
47 {
48 arc = lv_arc_create(active_screen);
49 lv_obj_set_size(arc, 100, 100);
50 lv_obj_center(arc);
51 lv_arc_set_value(arc, 70);
52
53 TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_1.png");
54 }
55
test_arc_rgb565a8_image(void)56 void test_arc_rgb565a8_image(void)
57 {
58 #if LV_BIN_DECODER_RAM_LOAD
59 /*RGB565A8 image rendering requires special handling*/
60 arc = lv_arc_create(active_screen);
61 lv_obj_set_size(arc, 100, 100);
62 lv_obj_center(arc);
63 lv_arc_set_value(arc, 70);
64 lv_obj_set_style_arc_width(arc, 30, 0);
65 lv_obj_set_style_arc_width(arc, 30, LV_PART_INDICATOR);
66 lv_obj_set_style_arc_image_src(arc, "A:src/test_files/binimages/cogwheel.RGB565A8.bin", LV_PART_INDICATOR);
67 lv_obj_set_style_arc_opa(arc, 150, LV_PART_INDICATOR);
68 lv_obj_set_style_bg_opa(arc, 0, LV_PART_KNOB);
69
70 TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_2.png");
71 #endif
72 }
73
test_arc_should_truncate_to_max_range_when_new_value_exceeds_it(void)74 void test_arc_should_truncate_to_max_range_when_new_value_exceeds_it(void)
75 {
76 /* Default max range is 100 */
77 int16_t value_after_truncation = 100;
78
79 arc = lv_arc_create(active_screen);
80
81 lv_arc_set_value(arc, 200);
82
83 TEST_ASSERT_EQUAL_INT16(value_after_truncation, lv_arc_get_value(arc));
84 }
85
test_arc_should_truncate_to_min_range_when_new_value_is_inferior(void)86 void test_arc_should_truncate_to_min_range_when_new_value_is_inferior(void)
87 {
88 /* Default min range is 100 */
89 int16_t value_after_truncation = 0;
90
91 arc = lv_arc_create(active_screen);
92
93 lv_arc_set_value(arc, 0);
94
95 TEST_ASSERT_EQUAL_INT16(value_after_truncation, lv_arc_get_value(arc));
96 }
97
test_arc_should_update_value_after_updating_range(void)98 void test_arc_should_update_value_after_updating_range(void)
99 {
100 int16_t value_after_updating_max_range = 50;
101 int16_t value_after_updating_min_range = 30;
102
103 arc = lv_arc_create(active_screen);
104
105 lv_arc_set_value(arc, 80);
106 lv_arc_set_range(arc, 1, 50);
107
108 TEST_ASSERT_EQUAL_INT16(value_after_updating_max_range, lv_arc_get_value(arc));
109
110 lv_arc_set_value(arc, 10);
111 lv_arc_set_range(arc, 30, 50);
112
113 TEST_ASSERT_EQUAL_INT16(value_after_updating_min_range, lv_arc_get_value(arc));
114 }
115
test_arc_should_update_angles_when_changing_to_symmetrical_mode(void)116 void test_arc_should_update_angles_when_changing_to_symmetrical_mode(void)
117 {
118 int16_t expected_angle_start = 135;
119 int16_t expected_angle_end = 270;
120
121 /* start angle is 135, end angle is 45 at creation */
122 arc = lv_arc_create(active_screen);
123 lv_arc_set_mode(arc, LV_ARC_MODE_SYMMETRICAL);
124
125 TEST_ASSERT_EQUAL_INT16(expected_angle_start, lv_arc_get_angle_start(arc));
126 TEST_ASSERT_EQUAL_INT16(expected_angle_end, lv_arc_get_angle_end(arc));
127 }
128
test_arc_should_update_angles_when_changing_to_symmetrical_mode_value_more_than_middle_range(void)129 void test_arc_should_update_angles_when_changing_to_symmetrical_mode_value_more_than_middle_range(void)
130 {
131 int16_t expected_angle_start = 270;
132 int16_t expected_angle_end = 45;
133
134 /* start angle is 135, end angle is 45 at creation */
135 arc = lv_arc_create(active_screen);
136 lv_arc_set_value(arc, 100);
137 lv_arc_set_mode(arc, LV_ARC_MODE_SYMMETRICAL);
138
139 TEST_ASSERT_EQUAL_INT16(expected_angle_start, lv_arc_get_angle_start(arc));
140 TEST_ASSERT_EQUAL_INT16(expected_angle_end, lv_arc_get_angle_end(arc));
141 }
142
143 /* See #2522 for more information */
test_arc_angles_when_reversed(void)144 void test_arc_angles_when_reversed(void)
145 {
146 uint16_t expected_start_angle = 54;
147 uint16_t expected_end_angle = 90;
148 int16_t expected_value = 40;
149
150 lv_obj_t * arcBlack;
151 arcBlack = lv_arc_create(lv_screen_active());
152
153 lv_arc_set_mode(arcBlack, LV_ARC_MODE_REVERSE);
154
155 lv_arc_set_bg_angles(arcBlack, 0, 90);
156
157 lv_arc_set_value(arcBlack, expected_value);
158
159 TEST_ASSERT_EQUAL_UINT16(expected_start_angle, lv_arc_get_angle_start(arcBlack));
160 TEST_ASSERT_EQUAL_UINT16(expected_end_angle, lv_arc_get_angle_end(arcBlack));
161 TEST_ASSERT_EQUAL_INT16(expected_value, lv_arc_get_value(arcBlack));
162 }
163
test_arc_click_area_with_adv_hittest(void)164 void test_arc_click_area_with_adv_hittest(void)
165 {
166 arc = lv_arc_create(lv_screen_active());
167 lv_obj_set_size(arc, 100, 100);
168 lv_obj_set_style_arc_width(arc, 10, 0);
169 lv_obj_add_flag(arc, LV_OBJ_FLAG_ADV_HITTEST);
170 lv_obj_add_event_cb(arc, dummy_event_cb, LV_EVENT_PRESSED, NULL);
171 lv_obj_set_ext_click_area(arc, 5);
172
173 /*No click detected at the middle*/
174 event_cnt = 0;
175 lv_test_mouse_click_at(50, 50);
176 TEST_ASSERT_EQUAL_UINT32(0, event_cnt);
177
178 /*No click close to the radius - bg_arc - ext_click_area*/
179 event_cnt = 0;
180 lv_test_mouse_click_at(83, 50);
181 TEST_ASSERT_EQUAL_UINT32(0, event_cnt);
182
183 /*Click on the radius - bg_arc - ext_click_area*/
184 event_cnt = 0;
185 lv_test_mouse_click_at(86, 50);
186 TEST_ASSERT_GREATER_THAN(0, event_cnt);
187
188 /*Click on the radius + ext_click_area*/
189 event_cnt = 0;
190 lv_test_mouse_click_at(104, 50);
191 TEST_ASSERT_GREATER_THAN(0, event_cnt);
192
193 /*No click beyond to the radius + ext_click_area*/
194 event_cnt = 0;
195 lv_test_mouse_click_at(106, 50);
196 TEST_ASSERT_EQUAL_UINT32(0, event_cnt);
197 }
198
199 /* Check value doesn't go to max when clicking on the other side of the arc */
test_arc_click_sustained_from_start_to_end_does_not_set_value_to_max(void)200 void test_arc_click_sustained_from_start_to_end_does_not_set_value_to_max(void)
201 {
202 arc = lv_arc_create(lv_screen_active());
203 lv_arc_set_value(arc, 0);
204
205 lv_obj_set_size(arc, 100, 100);
206 lv_obj_center(arc);
207 lv_obj_add_event_cb(arc, dummy_event_cb, LV_EVENT_PRESSED, NULL);
208 event_cnt = 0;
209
210 /* Click close to start angle */
211 event_cnt = 0;
212 lv_test_mouse_release();
213 lv_test_indev_wait(50);
214 lv_test_mouse_move_to(376, 285);
215 lv_test_mouse_press();
216 lv_test_indev_wait(500);
217 lv_test_mouse_release();
218 lv_test_indev_wait(50);
219
220 TEST_ASSERT_EQUAL_UINT32(1, event_cnt);
221 TEST_ASSERT_EQUAL_INT32(lv_arc_get_min_value(arc), lv_arc_get_value(arc));
222
223 /* Click close to end angle */
224 event_cnt = 0;
225
226 lv_test_mouse_release();
227 lv_test_indev_wait(50);
228 lv_test_mouse_move_to(376, 285);
229 lv_test_mouse_press();
230 lv_test_indev_wait(500);
231 lv_test_mouse_move_to(415, 281);
232 lv_test_indev_wait(500);
233 lv_test_mouse_release();
234 lv_test_indev_wait(50);
235
236 TEST_ASSERT_EQUAL_UINT32(1, event_cnt);
237 TEST_ASSERT_EQUAL_INT32(lv_arc_get_min_value(arc), lv_arc_get_value(arc));
238
239 TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_3.png");
240 }
241
test_two_overlapping_arcs_can_be_interacted_independently(void)242 void test_two_overlapping_arcs_can_be_interacted_independently(void)
243 {
244 arc = lv_arc_create(lv_screen_active());
245 arc2 = lv_arc_create(lv_screen_active());
246
247 lv_arc_set_value(arc, 0);
248 lv_arc_set_value(arc2, 0);
249 lv_obj_set_size(arc, 100, 100);
250 lv_obj_set_size(arc2, 100, 100);
251 lv_arc_set_bg_angles(arc, 20, 160);
252 lv_arc_set_bg_angles(arc2, 200, 340);
253 lv_obj_add_flag(arc, LV_OBJ_FLAG_ADV_HITTEST);
254 lv_obj_add_flag(arc2, LV_OBJ_FLAG_ADV_HITTEST);
255 lv_arc_set_value(arc, 10);
256 lv_arc_set_value(arc2, 10);
257 lv_arc_set_rotation(arc, 355);
258 lv_arc_set_rotation(arc2, 355);
259 lv_obj_center(arc);
260 lv_obj_center(arc2);
261
262 // Add event callback to both arcs
263 lv_obj_add_event_cb(arc, dummy_event_cb, LV_EVENT_PRESSED, NULL);
264 lv_obj_add_event_cb(arc2, dummy_event_cb2, LV_EVENT_PRESSED, NULL);
265
266 // Reset event counters
267 event_cnt = 0;
268 event_cnt2 = 0;
269
270 // Click on the position of the first arc (center)
271 lv_test_mouse_release();
272 lv_test_indev_wait(50);
273 lv_test_mouse_move_to(400, 195);
274 lv_test_mouse_press();
275 lv_test_indev_wait(500);
276 lv_test_mouse_release();
277 lv_test_indev_wait(50);
278
279 // Verify that the event callback was called for the first arc
280 TEST_ASSERT_EQUAL_UINT32(0, event_cnt);
281 TEST_ASSERT_EQUAL_UINT32(1, event_cnt2);
282
283 // click on the position of the second arc (center)
284 lv_test_mouse_release();
285 lv_test_indev_wait(50);
286 lv_test_mouse_move_to(400, 285);
287 lv_test_mouse_press();
288 lv_test_indev_wait(500);
289 lv_test_mouse_release();
290 lv_test_indev_wait(50);
291
292 // Verify that the event callback was called for the second arc
293 TEST_ASSERT_EQUAL_UINT32(1, event_cnt);
294 TEST_ASSERT_EQUAL_UINT32(1, event_cnt2);
295
296 // Verify that the screen remains as expected after the interactions
297 TEST_ASSERT_EQUAL_SCREENSHOT("widgets/overlapping_arcs_test.png");
298 }
299
300
dummy_event_cb(lv_event_t * e)301 static void dummy_event_cb(lv_event_t * e)
302 {
303 LV_UNUSED(e);
304 event_cnt++;
305 }
306
dummy_event_cb2(lv_event_t * e)307 static void dummy_event_cb2(lv_event_t * e)
308 {
309 LV_UNUSED(e);
310 event_cnt2++;
311 }
312
313 #endif
314