source: mainline/uspace/lib/ui/test/slider.c@ 943f032

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 943f032 was 943f032, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Slider text mode

  • Property mode set to 100644
File size: 13.1 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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.
27 */
28
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"
38
39PCUT_INIT;
40
41PCUT_TEST_SUITE(slider);
42
43static errno_t testgc_set_clip_rect(void *, gfx_rect_t *);
44static errno_t testgc_set_color(void *, gfx_color_t *);
45static errno_t testgc_fill_rect(void *, gfx_rect_t *);
46static errno_t testgc_update(void *);
47static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
48 gfx_bitmap_alloc_t *, void **);
49static errno_t testgc_bitmap_destroy(void *);
50static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
51static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
52
53static 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
62};
63
64static void test_slider_moved(ui_slider_t *, void *, gfx_coord_t);
65
66static ui_slider_cb_t test_slider_cb = {
67 .moved = test_slider_moved
68};
69
70static ui_slider_cb_t dummy_slider_cb = {
71};
72
73typedef 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;
83
84typedef struct {
85 test_gc_t *tgc;
86 gfx_bitmap_alloc_t alloc;
87 bool myalloc;
88} testgc_bitmap_t;
89
90typedef struct {
91 bool moved;
92 gfx_coord_t pos;
93} test_cb_resp_t;
94
95/** Create and destroy slider */
96PCUT_TEST(create_destroy)
97{
98 ui_slider_t *slider = NULL;
99 errno_t rc;
100
101 rc = ui_slider_create(NULL, "Hello", &slider);
102 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
103 PCUT_ASSERT_NOT_NULL(slider);
104
105 ui_slider_destroy(slider);
106}
107
108/** ui_slider_destroy() can take NULL argument (no-op) */
109PCUT_TEST(destroy_null)
110{
111 ui_slider_destroy(NULL);
112}
113
114/** ui_slider_ctl() returns control that has a working virtual destructor */
115PCUT_TEST(ctl)
116{
117 ui_slider_t *slider;
118 ui_control_t *control;
119 errno_t rc;
120
121 rc = ui_slider_create(NULL, "Hello", &slider);
122 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
123
124 control = ui_slider_ctl(slider);
125 PCUT_ASSERT_NOT_NULL(control);
126
127 ui_control_destroy(control);
128}
129
130/** Set slider rectangle sets internal field */
131PCUT_TEST(set_rect)
132{
133 ui_slider_t *slider;
134 gfx_rect_t rect;
135 errno_t rc;
136
137 rc = ui_slider_create(NULL, "Hello", &slider);
138 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
139
140 rect.p0.x = 1;
141 rect.p0.y = 2;
142 rect.p1.x = 3;
143 rect.p1.y = 4;
144
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);
150
151 ui_slider_destroy(slider);
152}
153
154/** Paint slider in graphics mode */
155PCUT_TEST(paint_gfx)
156{
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;
162
163 memset(&tgc, 0, sizeof(tgc));
164 rc = gfx_context_new(&ops, &tgc, &gc);
165 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
166
167 rc = ui_resource_create(gc, false, &resource);
168 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
169 PCUT_ASSERT_NOT_NULL(resource);
170
171 rc = ui_slider_create(resource, "Hello", &slider);
172 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
173
174 rc = ui_slider_paint_gfx(slider);
175 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
176
177 ui_slider_destroy(slider);
178 ui_resource_destroy(resource);
179
180 rc = gfx_context_delete(gc);
181 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
182}
183
184/** Paint slider in text mode */
185PCUT_TEST(paint_text)
186{
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;
192
193 memset(&tgc, 0, sizeof(tgc));
194 rc = gfx_context_new(&ops, &tgc, &gc);
195 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
196
197 rc = ui_resource_create(gc, false, &resource);
198 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
199 PCUT_ASSERT_NOT_NULL(resource);
200
201 rc = ui_slider_create(resource, "Hello", &slider);
202 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
203
204 rc = ui_slider_paint_text(slider);
205 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
206
207 ui_slider_destroy(slider);
208 ui_resource_destroy(resource);
209
210 rc = gfx_context_delete(gc);
211 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
212}
213
214/** Test ui_slider_moved() */
215PCUT_TEST(moved)
216{
217 errno_t rc;
218 ui_slider_t *slider;
219 test_cb_resp_t resp;
220
221 rc = ui_slider_create(NULL, "Hello", &slider);
222 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
223
224 /* Moved with no callbacks set */
225 ui_slider_moved(slider, 42);
226
227 /* Moved with callback not implementing clicked */
228 ui_slider_set_cb(slider, &dummy_slider_cb, NULL);
229 ui_slider_moved(slider, 42);
230
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);
238
239 ui_slider_destroy(slider);
240}
241
242/** Press and release slider */
243PCUT_TEST(press_release)
244{
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;
253
254 memset(&tgc, 0, sizeof(tgc));
255 rc = gfx_context_new(&ops, &tgc, &gc);
256 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
257
258 rc = ui_resource_create(gc, false, &resource);
259 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
260 PCUT_ASSERT_NOT_NULL(resource);
261
262 rc = ui_slider_create(resource, "Hello", &slider);
263 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
264
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);
270
271 resp.moved = false;
272 ui_slider_set_cb(slider, &test_slider_cb, &resp);
273
274 PCUT_ASSERT_FALSE(slider->held);
275
276 pos.x = 11;
277 pos.y = 22;
278
279 ui_slider_press(slider, &pos);
280 PCUT_ASSERT_TRUE(slider->held);
281 PCUT_ASSERT_FALSE(resp.moved);
282
283 pos.x = 21;
284 pos.y = 32;
285
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);
290
291 ui_slider_destroy(slider);
292 ui_resource_destroy(resource);
293
294 rc = gfx_context_delete(gc);
295 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
296}
297
298/** Press, update and release slider */
299PCUT_TEST(press_uodate_release)
300{
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;
309
310 memset(&tgc, 0, sizeof(tgc));
311 rc = gfx_context_new(&ops, &tgc, &gc);
312 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
313
314 rc = ui_resource_create(gc, false, &resource);
315 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
316 PCUT_ASSERT_NOT_NULL(resource);
317
318 rc = ui_slider_create(resource, "Hello", &slider);
319 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
320
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);
326
327 resp.moved = false;
328 ui_slider_set_cb(slider, &test_slider_cb, &resp);
329
330 PCUT_ASSERT_FALSE(slider->held);
331
332 pos.x = 11;
333 pos.y = 22;
334
335 ui_slider_press(slider, &pos);
336 PCUT_ASSERT_TRUE(slider->held);
337 PCUT_ASSERT_FALSE(resp.moved);
338
339 pos.x = 21;
340 pos.y = 32;
341
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);
346
347 pos.x = 31;
348 pos.y = 42;
349
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);
354
355 ui_slider_destroy(slider);
356 ui_resource_destroy(resource);
357
358 rc = gfx_context_delete(gc);
359 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
360}
361
362/** ui_pos_event() correctly translates POS_PRESS/POS_RELEASE */
363PCUT_TEST(pos_event_press_release)
364{
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;
373
374 memset(&tgc, 0, sizeof(tgc));
375 rc = gfx_context_new(&ops, &tgc, &gc);
376 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
377
378 rc = ui_resource_create(gc, false, &resource);
379 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
380 PCUT_ASSERT_NOT_NULL(resource);
381
382 rc = ui_slider_create(resource, "Hello", &slider);
383 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
384
385 PCUT_ASSERT_FALSE(slider->held);
386
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);
392
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);
400
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);
408
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);
416
417 ui_slider_destroy(slider);
418 ui_resource_destroy(resource);
419
420 rc = gfx_context_delete(gc);
421 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
422}
423
424/** ui_slider_length() correctly determines slider length */
425PCUT_TEST(length)
426{
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;
434
435 memset(&tgc, 0, sizeof(tgc));
436 rc = gfx_context_new(&ops, &tgc, &gc);
437 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
438
439 rc = ui_resource_create(gc, false, &resource);
440 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
441 PCUT_ASSERT_NOT_NULL(resource);
442
443 rc = ui_slider_create(resource, "Hello", &slider);
444 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
445
446 PCUT_ASSERT_FALSE(slider->held);
447
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);
453
454 length = ui_slider_length(slider);
455 PCUT_ASSERT_INT_EQUALS(110 - 10 - 15, length);
456
457 ui_slider_destroy(slider);
458 ui_resource_destroy(resource);
459
460 rc = gfx_context_delete(gc);
461 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
462}
463
464static errno_t testgc_set_clip_rect(void *arg, gfx_rect_t *rect)
465{
466 (void) arg;
467 (void) rect;
468 return EOK;
469}
470
471static errno_t testgc_set_color(void *arg, gfx_color_t *color)
472{
473 (void) arg;
474 (void) color;
475 return EOK;
476}
477
478static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
479{
480 (void) arg;
481 (void) rect;
482 return EOK;
483}
484
485static errno_t testgc_update(void *arg)
486{
487 (void) arg;
488 return EOK;
489}
490
491static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
492 gfx_bitmap_alloc_t *alloc, void **rbm)
493{
494 test_gc_t *tgc = (test_gc_t *) arg;
495 testgc_bitmap_t *tbm;
496
497 tbm = calloc(1, sizeof(testgc_bitmap_t));
498 if (tbm == NULL)
499 return ENOMEM;
500
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;
512 }
513 } else {
514 tbm->alloc = *alloc;
515 }
516
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;
523}
524
525static errno_t testgc_bitmap_destroy(void *bm)
526{
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;
533}
534
535static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
536 gfx_coord2_t *offs)
537{
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;
543}
544
545static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
546{
547 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
548 *alloc = tbm->alloc;
549 tbm->tgc->bm_got_alloc = true;
550 return EOK;
551}
552
553static void test_slider_moved(ui_slider_t *slider, void *arg, gfx_coord_t pos)
554{
555 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
556
557 resp->moved = true;
558 resp->pos = pos;
559}
560
561PCUT_EXPORT(slider);
Note: See TracBrowser for help on using the repository browser.