2 * Copyright (c) 2022 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <gfx/context.h>
30 #include <gfx/coord.h>
32 #include <pcut/pcut.h>
34 #include <ui/control.h>
35 #include <ui/slider.h>
36 #include <ui/resource.h>
37 #include "../private/slider.h"
41 PCUT_TEST_SUITE(slider
);
43 static errno_t
testgc_set_clip_rect(void *, gfx_rect_t
*);
44 static errno_t
testgc_set_color(void *, gfx_color_t
*);
45 static errno_t
testgc_fill_rect(void *, gfx_rect_t
*);
46 static errno_t
testgc_update(void *);
47 static errno_t
testgc_bitmap_create(void *, gfx_bitmap_params_t
*,
48 gfx_bitmap_alloc_t
*, void **);
49 static errno_t
testgc_bitmap_destroy(void *);
50 static errno_t
testgc_bitmap_render(void *, gfx_rect_t
*, gfx_coord2_t
*);
51 static errno_t
testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t
*);
53 static gfx_context_ops_t ops
= {
54 .set_clip_rect
= testgc_set_clip_rect
,
55 .set_color
= testgc_set_color
,
56 .fill_rect
= testgc_fill_rect
,
57 .update
= testgc_update
,
58 .bitmap_create
= testgc_bitmap_create
,
59 .bitmap_destroy
= testgc_bitmap_destroy
,
60 .bitmap_render
= testgc_bitmap_render
,
61 .bitmap_get_alloc
= testgc_bitmap_get_alloc
64 static void test_slider_moved(ui_slider_t
*, void *, gfx_coord_t
);
66 static ui_slider_cb_t test_slider_cb
= {
67 .moved
= test_slider_moved
70 static ui_slider_cb_t dummy_slider_cb
= {
76 gfx_bitmap_params_t bm_params
;
86 gfx_bitmap_alloc_t alloc
;
95 /** Create and destroy slider */
96 PCUT_TEST(create_destroy
)
98 ui_slider_t
*slider
= NULL
;
101 rc
= ui_slider_create(NULL
, &slider
);
102 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
103 PCUT_ASSERT_NOT_NULL(slider
);
105 ui_slider_destroy(slider
);
108 /** ui_slider_destroy() can take NULL argument (no-op) */
109 PCUT_TEST(destroy_null
)
111 ui_slider_destroy(NULL
);
114 /** ui_slider_ctl() returns control that has a working virtual destructor */
118 ui_control_t
*control
;
121 rc
= ui_slider_create(NULL
, &slider
);
122 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
124 control
= ui_slider_ctl(slider
);
125 PCUT_ASSERT_NOT_NULL(control
);
127 ui_control_destroy(control
);
130 /** Set slider rectangle sets internal field */
137 rc
= ui_slider_create(NULL
, &slider
);
138 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
145 ui_slider_set_rect(slider
, &rect
);
146 PCUT_ASSERT_INT_EQUALS(rect
.p0
.x
, slider
->rect
.p0
.x
);
147 PCUT_ASSERT_INT_EQUALS(rect
.p0
.y
, slider
->rect
.p0
.y
);
148 PCUT_ASSERT_INT_EQUALS(rect
.p1
.x
, slider
->rect
.p1
.x
);
149 PCUT_ASSERT_INT_EQUALS(rect
.p1
.y
, slider
->rect
.p1
.y
);
151 ui_slider_destroy(slider
);
154 /** Paint slider in graphics mode */
158 gfx_context_t
*gc
= NULL
;
160 ui_resource_t
*resource
= NULL
;
163 memset(&tgc
, 0, sizeof(tgc
));
164 rc
= gfx_context_new(&ops
, &tgc
, &gc
);
165 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
167 rc
= ui_resource_create(gc
, false, &resource
);
168 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
169 PCUT_ASSERT_NOT_NULL(resource
);
171 rc
= ui_slider_create(resource
, &slider
);
172 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
174 rc
= ui_slider_paint_gfx(slider
);
175 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
177 ui_slider_destroy(slider
);
178 ui_resource_destroy(resource
);
180 rc
= gfx_context_delete(gc
);
181 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
184 /** Paint slider in text mode */
185 PCUT_TEST(paint_text
)
188 gfx_context_t
*gc
= NULL
;
190 ui_resource_t
*resource
= NULL
;
193 memset(&tgc
, 0, sizeof(tgc
));
194 rc
= gfx_context_new(&ops
, &tgc
, &gc
);
195 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
197 rc
= ui_resource_create(gc
, false, &resource
);
198 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
199 PCUT_ASSERT_NOT_NULL(resource
);
201 rc
= ui_slider_create(resource
, &slider
);
202 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
204 rc
= ui_slider_paint_text(slider
);
205 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
207 ui_slider_destroy(slider
);
208 ui_resource_destroy(resource
);
210 rc
= gfx_context_delete(gc
);
211 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
214 /** Test ui_slider_moved() */
221 rc
= ui_slider_create(NULL
, &slider
);
222 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
224 /* Moved with no callbacks set */
225 ui_slider_moved(slider
, 42);
227 /* Moved with callback not implementing moved */
228 ui_slider_set_cb(slider
, &dummy_slider_cb
, NULL
);
229 ui_slider_moved(slider
, 42);
231 /* Moved with real callback set */
234 ui_slider_set_cb(slider
, &test_slider_cb
, &resp
);
235 ui_slider_moved(slider
, 42);
236 PCUT_ASSERT_TRUE(resp
.moved
);
237 PCUT_ASSERT_INT_EQUALS(42, resp
.pos
);
239 ui_slider_destroy(slider
);
242 /** Press and release slider */
243 PCUT_TEST(press_release
)
246 gfx_context_t
*gc
= NULL
;
248 ui_resource_t
*resource
= NULL
;
254 memset(&tgc
, 0, sizeof(tgc
));
255 rc
= gfx_context_new(&ops
, &tgc
, &gc
);
256 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
258 rc
= ui_resource_create(gc
, false, &resource
);
259 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
260 PCUT_ASSERT_NOT_NULL(resource
);
262 rc
= ui_slider_create(resource
, &slider
);
263 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
269 ui_slider_set_rect(slider
, &rect
);
272 ui_slider_set_cb(slider
, &test_slider_cb
, &resp
);
274 PCUT_ASSERT_FALSE(slider
->held
);
279 ui_slider_press(slider
, &pos
);
280 PCUT_ASSERT_TRUE(slider
->held
);
281 PCUT_ASSERT_FALSE(resp
.moved
);
286 ui_slider_release(slider
, &pos
);
287 PCUT_ASSERT_FALSE(slider
->held
);
288 PCUT_ASSERT_TRUE(resp
.moved
);
289 PCUT_ASSERT_INT_EQUALS(10, slider
->pos
);
291 ui_slider_destroy(slider
);
292 ui_resource_destroy(resource
);
294 rc
= gfx_context_delete(gc
);
295 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
298 /** Press, update and release slider */
299 PCUT_TEST(press_uodate_release
)
302 gfx_context_t
*gc
= NULL
;
304 ui_resource_t
*resource
= NULL
;
310 memset(&tgc
, 0, sizeof(tgc
));
311 rc
= gfx_context_new(&ops
, &tgc
, &gc
);
312 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
314 rc
= ui_resource_create(gc
, false, &resource
);
315 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
316 PCUT_ASSERT_NOT_NULL(resource
);
318 rc
= ui_slider_create(resource
, &slider
);
319 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
325 ui_slider_set_rect(slider
, &rect
);
328 ui_slider_set_cb(slider
, &test_slider_cb
, &resp
);
330 PCUT_ASSERT_FALSE(slider
->held
);
335 ui_slider_press(slider
, &pos
);
336 PCUT_ASSERT_TRUE(slider
->held
);
337 PCUT_ASSERT_FALSE(resp
.moved
);
342 ui_slider_update(slider
, &pos
);
343 PCUT_ASSERT_TRUE(slider
->held
);
344 PCUT_ASSERT_TRUE(resp
.moved
);
345 PCUT_ASSERT_INT_EQUALS(10, slider
->pos
);
350 ui_slider_release(slider
, &pos
);
351 PCUT_ASSERT_FALSE(slider
->held
);
352 PCUT_ASSERT_TRUE(resp
.moved
);
353 PCUT_ASSERT_INT_EQUALS(20, slider
->pos
);
355 ui_slider_destroy(slider
);
356 ui_resource_destroy(resource
);
358 rc
= gfx_context_delete(gc
);
359 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
362 /** ui_pos_event() correctly translates POS_PRESS/POS_RELEASE */
363 PCUT_TEST(pos_event_press_release
)
366 gfx_context_t
*gc
= NULL
;
368 ui_resource_t
*resource
= NULL
;
374 memset(&tgc
, 0, sizeof(tgc
));
375 rc
= gfx_context_new(&ops
, &tgc
, &gc
);
376 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
378 rc
= ui_resource_create(gc
, false, &resource
);
379 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
380 PCUT_ASSERT_NOT_NULL(resource
);
382 rc
= ui_slider_create(resource
, &slider
);
383 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
385 PCUT_ASSERT_FALSE(slider
->held
);
391 ui_slider_set_rect(slider
, &rect
);
393 /* Press outside is not claimed and does nothing */
394 event
.type
= POS_PRESS
;
397 claim
= ui_slider_pos_event(slider
, &event
);
398 PCUT_ASSERT_FALSE(slider
->held
);
399 PCUT_ASSERT_EQUALS(ui_unclaimed
, claim
);
401 /* Press inside is claimed and depresses slider */
402 event
.type
= POS_PRESS
;
405 claim
= ui_slider_pos_event(slider
, &event
);
406 PCUT_ASSERT_TRUE(slider
->held
);
407 PCUT_ASSERT_EQUALS(ui_claimed
, claim
);
409 /* Release outside (or anywhere) is claimed and relases slider */
410 event
.type
= POS_RELEASE
;
413 claim
= ui_slider_pos_event(slider
, &event
);
414 PCUT_ASSERT_FALSE(slider
->held
);
415 PCUT_ASSERT_EQUALS(ui_claimed
, claim
);
417 ui_slider_destroy(slider
);
418 ui_resource_destroy(resource
);
420 rc
= gfx_context_delete(gc
);
421 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
424 /** ui_slider_length() correctly determines slider length */
428 gfx_context_t
*gc
= NULL
;
430 ui_resource_t
*resource
= NULL
;
435 memset(&tgc
, 0, sizeof(tgc
));
436 rc
= gfx_context_new(&ops
, &tgc
, &gc
);
437 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
439 rc
= ui_resource_create(gc
, false, &resource
);
440 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
441 PCUT_ASSERT_NOT_NULL(resource
);
443 rc
= ui_slider_create(resource
, &slider
);
444 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
446 PCUT_ASSERT_FALSE(slider
->held
);
452 ui_slider_set_rect(slider
, &rect
);
454 length
= ui_slider_length(slider
);
455 PCUT_ASSERT_INT_EQUALS(110 - 10 - 15, length
);
457 ui_slider_destroy(slider
);
458 ui_resource_destroy(resource
);
460 rc
= gfx_context_delete(gc
);
461 PCUT_ASSERT_ERRNO_VAL(EOK
, rc
);
464 static errno_t
testgc_set_clip_rect(void *arg
, gfx_rect_t
*rect
)
471 static errno_t
testgc_set_color(void *arg
, gfx_color_t
*color
)
478 static errno_t
testgc_fill_rect(void *arg
, gfx_rect_t
*rect
)
485 static errno_t
testgc_update(void *arg
)
491 static errno_t
testgc_bitmap_create(void *arg
, gfx_bitmap_params_t
*params
,
492 gfx_bitmap_alloc_t
*alloc
, void **rbm
)
494 test_gc_t
*tgc
= (test_gc_t
*) arg
;
495 testgc_bitmap_t
*tbm
;
497 tbm
= calloc(1, sizeof(testgc_bitmap_t
));
502 tbm
->alloc
.pitch
= (params
->rect
.p1
.x
- params
->rect
.p0
.x
) *
505 tbm
->alloc
.pixels
= calloc(sizeof(uint32_t),
506 (params
->rect
.p1
.x
- params
->rect
.p0
.x
) *
507 (params
->rect
.p1
.y
- params
->rect
.p0
.y
));
509 if (tbm
->alloc
.pixels
== NULL
) {
518 tgc
->bm_created
= true;
519 tgc
->bm_params
= *params
;
520 tgc
->bm_pixels
= tbm
->alloc
.pixels
;
525 static errno_t
testgc_bitmap_destroy(void *bm
)
527 testgc_bitmap_t
*tbm
= (testgc_bitmap_t
*)bm
;
529 free(tbm
->alloc
.pixels
);
530 tbm
->tgc
->bm_destroyed
= true;
535 static errno_t
testgc_bitmap_render(void *bm
, gfx_rect_t
*srect
,
538 testgc_bitmap_t
*tbm
= (testgc_bitmap_t
*)bm
;
539 tbm
->tgc
->bm_rendered
= true;
540 tbm
->tgc
->bm_srect
= *srect
;
541 tbm
->tgc
->bm_offs
= *offs
;
545 static errno_t
testgc_bitmap_get_alloc(void *bm
, gfx_bitmap_alloc_t
*alloc
)
547 testgc_bitmap_t
*tbm
= (testgc_bitmap_t
*)bm
;
549 tbm
->tgc
->bm_got_alloc
= true;
553 static void test_slider_moved(ui_slider_t
*slider
, void *arg
, gfx_coord_t pos
)
555 test_cb_resp_t
*resp
= (test_cb_resp_t
*) arg
;