Handle Enter/Escape keys in message dialog.
[helenos.git] / uspace / lib / ui / test / slider.c
blobeada3f3b076578dbc311e252a313efbd1aeba37e
1 /*
2 * Copyright (c) 2022 Jiri Svoboda
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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>
31 #include <mem.h>
32 #include <pcut/pcut.h>
33 #include <stdbool.h>
34 #include <ui/control.h>
35 #include <ui/slider.h>
36 #include <ui/resource.h>
37 #include "../private/slider.h"
39 PCUT_INIT;
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 = {
73 typedef struct {
74 bool bm_created;
75 bool bm_destroyed;
76 gfx_bitmap_params_t bm_params;
77 void *bm_pixels;
78 gfx_rect_t bm_srect;
79 gfx_coord2_t bm_offs;
80 bool bm_rendered;
81 bool bm_got_alloc;
82 } test_gc_t;
84 typedef struct {
85 test_gc_t *tgc;
86 gfx_bitmap_alloc_t alloc;
87 bool myalloc;
88 } testgc_bitmap_t;
90 typedef struct {
91 bool moved;
92 gfx_coord_t pos;
93 } test_cb_resp_t;
95 /** Create and destroy slider */
96 PCUT_TEST(create_destroy)
98 ui_slider_t *slider = NULL;
99 errno_t rc;
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 */
115 PCUT_TEST(ctl)
117 ui_slider_t *slider;
118 ui_control_t *control;
119 errno_t rc;
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 */
131 PCUT_TEST(set_rect)
133 ui_slider_t *slider;
134 gfx_rect_t rect;
135 errno_t rc;
137 rc = ui_slider_create(NULL, &slider);
138 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
140 rect.p0.x = 1;
141 rect.p0.y = 2;
142 rect.p1.x = 3;
143 rect.p1.y = 4;
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 */
155 PCUT_TEST(paint_gfx)
157 errno_t rc;
158 gfx_context_t *gc = NULL;
159 test_gc_t tgc;
160 ui_resource_t *resource = NULL;
161 ui_slider_t *slider;
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)
187 errno_t rc;
188 gfx_context_t *gc = NULL;
189 test_gc_t tgc;
190 ui_resource_t *resource = NULL;
191 ui_slider_t *slider;
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() */
215 PCUT_TEST(moved)
217 errno_t rc;
218 ui_slider_t *slider;
219 test_cb_resp_t resp;
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 */
232 resp.moved = false;
233 resp.pos = 0;
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)
245 errno_t rc;
246 gfx_context_t *gc = NULL;
247 test_gc_t tgc;
248 ui_resource_t *resource = NULL;
249 gfx_coord2_t pos;
250 gfx_rect_t rect;
251 ui_slider_t *slider;
252 test_cb_resp_t resp;
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);
265 rect.p0.x = 10;
266 rect.p0.y = 20;
267 rect.p1.x = 110;
268 rect.p1.y = 120;
269 ui_slider_set_rect(slider, &rect);
271 resp.moved = false;
272 ui_slider_set_cb(slider, &test_slider_cb, &resp);
274 PCUT_ASSERT_FALSE(slider->held);
276 pos.x = 11;
277 pos.y = 22;
279 ui_slider_press(slider, &pos);
280 PCUT_ASSERT_TRUE(slider->held);
281 PCUT_ASSERT_FALSE(resp.moved);
283 pos.x = 21;
284 pos.y = 32;
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)
301 errno_t rc;
302 gfx_context_t *gc = NULL;
303 test_gc_t tgc;
304 ui_resource_t *resource = NULL;
305 gfx_coord2_t pos;
306 gfx_rect_t rect;
307 ui_slider_t *slider;
308 test_cb_resp_t resp;
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);
321 rect.p0.x = 10;
322 rect.p0.y = 20;
323 rect.p1.x = 110;
324 rect.p1.y = 120;
325 ui_slider_set_rect(slider, &rect);
327 resp.moved = false;
328 ui_slider_set_cb(slider, &test_slider_cb, &resp);
330 PCUT_ASSERT_FALSE(slider->held);
332 pos.x = 11;
333 pos.y = 22;
335 ui_slider_press(slider, &pos);
336 PCUT_ASSERT_TRUE(slider->held);
337 PCUT_ASSERT_FALSE(resp.moved);
339 pos.x = 21;
340 pos.y = 32;
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);
347 pos.x = 31;
348 pos.y = 42;
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)
365 errno_t rc;
366 gfx_context_t *gc = NULL;
367 test_gc_t tgc;
368 ui_resource_t *resource = NULL;
369 ui_slider_t *slider;
370 ui_evclaim_t claim;
371 pos_event_t event;
372 gfx_rect_t rect;
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);
387 rect.p0.x = 10;
388 rect.p0.y = 20;
389 rect.p1.x = 30;
390 rect.p1.y = 40;
391 ui_slider_set_rect(slider, &rect);
393 /* Press outside is not claimed and does nothing */
394 event.type = POS_PRESS;
395 event.hpos = 1;
396 event.vpos = 2;
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;
403 event.hpos = 11;
404 event.vpos = 22;
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;
411 event.hpos = 41;
412 event.vpos = 32;
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 */
425 PCUT_TEST(length)
427 errno_t rc;
428 gfx_context_t *gc = NULL;
429 test_gc_t tgc;
430 ui_resource_t *resource = NULL;
431 ui_slider_t *slider;
432 gfx_coord_t length;
433 gfx_rect_t rect;
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);
448 rect.p0.x = 10;
449 rect.p0.y = 20;
450 rect.p1.x = 110;
451 rect.p1.y = 120;
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)
466 (void) arg;
467 (void) rect;
468 return EOK;
471 static errno_t testgc_set_color(void *arg, gfx_color_t *color)
473 (void) arg;
474 (void) color;
475 return EOK;
478 static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
480 (void) arg;
481 (void) rect;
482 return EOK;
485 static errno_t testgc_update(void *arg)
487 (void) arg;
488 return EOK;
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));
498 if (tbm == NULL)
499 return ENOMEM;
501 if (alloc == NULL) {
502 tbm->alloc.pitch = (params->rect.p1.x - params->rect.p0.x) *
503 sizeof(uint32_t);
504 tbm->alloc.off0 = 0;
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));
508 tbm->myalloc = true;
509 if (tbm->alloc.pixels == NULL) {
510 free(tbm);
511 return ENOMEM;
513 } else {
514 tbm->alloc = *alloc;
517 tbm->tgc = tgc;
518 tgc->bm_created = true;
519 tgc->bm_params = *params;
520 tgc->bm_pixels = tbm->alloc.pixels;
521 *rbm = (void *)tbm;
522 return EOK;
525 static errno_t testgc_bitmap_destroy(void *bm)
527 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
528 if (tbm->myalloc)
529 free(tbm->alloc.pixels);
530 tbm->tgc->bm_destroyed = true;
531 free(tbm);
532 return EOK;
535 static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
536 gfx_coord2_t *offs)
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;
542 return EOK;
545 static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
547 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
548 *alloc = tbm->alloc;
549 tbm->tgc->bm_got_alloc = true;
550 return EOK;
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;
557 resp->moved = true;
558 resp->pos = pos;
561 PCUT_EXPORT(slider);