source: mainline/uspace/lib/ui/test/menu.c@ ed1a948

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ed1a948 was 46bd63c9, checked in by Jiri Svoboda <jiri@…>, 22 months ago

Split drop-down menu into two classes: drop-down and menu

Naming is clearly the hardest problem in computer science.

  • Property mode set to 100644
File size: 18.6 KB
RevLine 
[95a9cbc]1/*
[5d380b6]2 * Copyright (c) 2023 Jiri Svoboda
[95a9cbc]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 <str.h>
35#include <ui/control.h>
36#include <ui/menu.h>
37#include <ui/menubar.h>
[59768c7]38#include <ui/menuentry.h>
[95a9cbc]39#include <ui/ui.h>
[c68c18b9]40#include <ui/window.h>
[95a9cbc]41#include "../private/menu.h"
42#include "../private/menubar.h"
43
44PCUT_INIT;
45
46PCUT_TEST_SUITE(menu);
47
[46bd63c9]48typedef struct {
49 bool left_called;
50 bool right_called;
51 bool close_req_called;
52 bool press_accel_called;
53 ui_menu_t *menu;
54 sysarg_t idev_id;
55 char32_t c;
56} test_resp_t;
57
58static void testmenu_left(ui_menu_t *, void *, sysarg_t);
59static void testmenu_right(ui_menu_t *, void *, sysarg_t);
60static void testmenu_close_req(ui_menu_t *, void *);
61static void testmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
62
63ui_menu_cb_t testmenu_cb = {
64 .left = testmenu_left,
65 .right = testmenu_right,
66 .close_req = testmenu_close_req,
67 .press_accel = testmenu_press_accel
68};
69
70ui_menu_cb_t dummy_cb = {
71};
72
[95a9cbc]73/** Create and destroy menu */
74PCUT_TEST(create_destroy)
75{
76 ui_menu_t *menu = NULL;
77 errno_t rc;
78
[46bd63c9]79 rc = ui_menu_create(NULL, &menu);
[95a9cbc]80 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
81 PCUT_ASSERT_NOT_NULL(menu);
82
83 ui_menu_destroy(menu);
84}
85
86/** ui_menu_destroy() can take NULL argument (no-op) */
87PCUT_TEST(destroy_null)
88{
89 ui_menu_destroy(NULL);
90}
91
[46bd63c9]92/** ui_menu_set_cb() sets the internal fields */
93PCUT_TEST(set_cb)
[59768c7]94{
[46bd63c9]95 ui_menu_t *menu = NULL;
96 ui_menu_cb_t cb;
97 int obj;
[59768c7]98 errno_t rc;
99
[46bd63c9]100 rc = ui_menu_create(NULL, &menu);
[59768c7]101 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[46bd63c9]102 PCUT_ASSERT_NOT_NULL(menu);
[59768c7]103
[46bd63c9]104 ui_menu_set_cb(menu, &cb, (void *)&obj);
105 PCUT_ASSERT_EQUALS(&cb, menu->cb);
106 PCUT_ASSERT_EQUALS((void *)&obj, menu->arg);
[59768c7]107
[46bd63c9]108 ui_menu_destroy(menu);
[59768c7]109}
110
[46bd63c9]111/** Computing menu geometry */
112PCUT_TEST(get_geom)
[95a9cbc]113{
[c68c18b9]114 ui_t *ui = NULL;
115 ui_window_t *window = NULL;
116 ui_wnd_params_t params;
[95a9cbc]117 ui_menu_t *menu = NULL;
[46bd63c9]118 ui_menu_geom_t geom;
119 gfx_coord2_t pos;
[95a9cbc]120 errno_t rc;
121
[c68c18b9]122 rc = ui_create_disp(NULL, &ui);
[95a9cbc]123 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
124
[c68c18b9]125 ui_wnd_params_init(&params);
126 params.caption = "Hello";
[95a9cbc]127
[c68c18b9]128 rc = ui_window_create(ui, &params, &window);
[95a9cbc]129 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[c68c18b9]130 PCUT_ASSERT_NOT_NULL(window);
[95a9cbc]131
[46bd63c9]132 rc = ui_menu_create(window, &menu);
[95a9cbc]133 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
134 PCUT_ASSERT_NOT_NULL(menu);
135
[46bd63c9]136 pos.x = 0;
137 pos.y = 0;
138 ui_menu_get_geom(menu, &pos, &geom);
[95a9cbc]139
[46bd63c9]140 PCUT_ASSERT_INT_EQUALS(0, geom.outer_rect.p0.x);
141 PCUT_ASSERT_INT_EQUALS(0, geom.outer_rect.p0.y);
142 PCUT_ASSERT_INT_EQUALS(16, geom.outer_rect.p1.x);
143 PCUT_ASSERT_INT_EQUALS(8, geom.outer_rect.p1.y);
144 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p0.x);
145 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p0.y);
146 PCUT_ASSERT_INT_EQUALS(12, geom.entries_rect.p1.x);
147 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p1.y);
[95a9cbc]148
[46bd63c9]149 ui_menu_destroy(menu);
[c68c18b9]150 ui_window_destroy(window);
151 ui_destroy(ui);
[95a9cbc]152}
153
[46bd63c9]154/** ui_menu_get_res() gets the menu's resource */
155PCUT_TEST(get_res)
[95a9cbc]156{
[c68c18b9]157 ui_t *ui = NULL;
158 ui_window_t *window = NULL;
159 ui_wnd_params_t params;
[95a9cbc]160 ui_menu_t *menu = NULL;
[46bd63c9]161 ui_resource_t *res;
162 gfx_rect_t prect;
[95a9cbc]163 errno_t rc;
164
[c68c18b9]165 rc = ui_create_disp(NULL, &ui);
[95a9cbc]166 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
167
[c68c18b9]168 ui_wnd_params_init(&params);
169 params.caption = "Hello";
[95a9cbc]170
[c68c18b9]171 rc = ui_window_create(ui, &params, &window);
[95a9cbc]172 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[c68c18b9]173 PCUT_ASSERT_NOT_NULL(window);
[95a9cbc]174
[46bd63c9]175 rc = ui_menu_create(window, &menu);
[95a9cbc]176 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
177 PCUT_ASSERT_NOT_NULL(menu);
178
[46bd63c9]179 prect.p0.x = 0;
180 prect.p0.y = 0;
181 prect.p1.x = 0;
182 prect.p1.y = 0;
[95a9cbc]183
[46bd63c9]184 /* The menu must be open first */
185 rc = ui_menu_open(menu, &prect, 0);
186 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[95a9cbc]187
[46bd63c9]188 res = ui_menu_get_res(menu);
189 PCUT_ASSERT_NOT_NULL(res);
190
191 ui_menu_destroy(menu);
[95a9cbc]192
[c68c18b9]193 ui_window_destroy(window);
194 ui_destroy(ui);
[95a9cbc]195}
196
[59768c7]197/** Open and close menu with ui_menu_open() / ui_menu_close() */
198PCUT_TEST(open_close)
199{
200 ui_t *ui = NULL;
201 ui_window_t *window = NULL;
202 ui_wnd_params_t params;
203 ui_menu_t *menu = NULL;
204 gfx_rect_t prect;
205 errno_t rc;
206
207 rc = ui_create_disp(NULL, &ui);
208 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
209
210 ui_wnd_params_init(&params);
211 params.caption = "Hello";
212
213 rc = ui_window_create(ui, &params, &window);
214 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
215 PCUT_ASSERT_NOT_NULL(window);
216
[46bd63c9]217 rc = ui_menu_create(window, &menu);
[59768c7]218 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
219 PCUT_ASSERT_NOT_NULL(menu);
220
221 prect.p0.x = 0;
222 prect.p0.y = 0;
223 prect.p1.x = 0;
224 prect.p1.y = 0;
225
226 /* Open and close */
[5d380b6]227 rc = ui_menu_open(menu, &prect, 0);
[59768c7]228 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
229
230 ui_menu_close(menu);
231
[46bd63c9]232 ui_menu_destroy(menu);
[59768c7]233 ui_window_destroy(window);
234 ui_destroy(ui);
235}
236
237/** ui_menu_is_open() correctly returns menu state */
238PCUT_TEST(is_open)
239{
240 ui_t *ui = NULL;
241 ui_window_t *window = NULL;
242 ui_wnd_params_t params;
243 ui_menu_t *menu = NULL;
244 gfx_rect_t prect;
245 bool open;
246 errno_t rc;
247
248 rc = ui_create_disp(NULL, &ui);
249 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
250
251 ui_wnd_params_init(&params);
252 params.caption = "Hello";
253
254 rc = ui_window_create(ui, &params, &window);
255 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
256 PCUT_ASSERT_NOT_NULL(window);
257
[46bd63c9]258 rc = ui_menu_create(window, &menu);
[59768c7]259 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
260 PCUT_ASSERT_NOT_NULL(menu);
261
262 prect.p0.x = 0;
263 prect.p0.y = 0;
264 prect.p1.x = 0;
265 prect.p1.y = 0;
266
267 open = ui_menu_is_open(menu);
268 PCUT_ASSERT_FALSE(open);
269
[5d380b6]270 rc = ui_menu_open(menu, &prect, 0);
[59768c7]271 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
272
273 open = ui_menu_is_open(menu);
274 PCUT_ASSERT_TRUE(open);
275
276 ui_menu_close(menu);
277
278 open = ui_menu_is_open(menu);
279 PCUT_ASSERT_FALSE(open);
280
[46bd63c9]281 ui_menu_destroy(menu);
[59768c7]282 ui_window_destroy(window);
283 ui_destroy(ui);
284}
285
[ff6e91b]286/** Paint background in graphics mode */
287PCUT_TEST(paint_bg_gfx)
288{
289 ui_t *ui = NULL;
290 ui_window_t *window = NULL;
291 ui_wnd_params_t params;
292 ui_menu_t *menu = NULL;
293 gfx_rect_t prect;
294 gfx_coord2_t pos;
295 errno_t rc;
296
297 rc = ui_create_disp(NULL, &ui);
298 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
299
300 ui_wnd_params_init(&params);
301 params.caption = "Hello";
302
303 rc = ui_window_create(ui, &params, &window);
304 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
305 PCUT_ASSERT_NOT_NULL(window);
306
[46bd63c9]307 rc = ui_menu_create(window, &menu);
[ff6e91b]308 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
309 PCUT_ASSERT_NOT_NULL(menu);
310
311 prect.p0.x = 0;
312 prect.p0.y = 0;
313 prect.p1.x = 0;
314 prect.p1.y = 0;
315
316 /* Menu needs to be open to be able to paint it */
[5d380b6]317 rc = ui_menu_open(menu, &prect, 0);
[ff6e91b]318 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
319
320 pos.x = 0;
321 pos.y = 0;
322 rc = ui_menu_paint_bg_gfx(menu, &pos);
323 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
324
325 ui_window_destroy(window);
326 ui_destroy(ui);
327}
328
329/** Paint background in text mode */
330PCUT_TEST(paint_bg_text)
331{
332 ui_t *ui = NULL;
333 ui_window_t *window = NULL;
334 ui_wnd_params_t params;
335 ui_menu_t *menu = NULL;
336 gfx_rect_t prect;
337 gfx_coord2_t pos;
338 errno_t rc;
339
340 rc = ui_create_disp(NULL, &ui);
341 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
342
343 ui_wnd_params_init(&params);
344 params.caption = "Hello";
345
346 rc = ui_window_create(ui, &params, &window);
347 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
348 PCUT_ASSERT_NOT_NULL(window);
349
[46bd63c9]350 rc = ui_menu_create(window, &menu);
[ff6e91b]351 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
352 PCUT_ASSERT_NOT_NULL(menu);
353
354 prect.p0.x = 0;
355 prect.p0.y = 0;
356 prect.p1.x = 0;
357 prect.p1.y = 0;
358
359 /* Menu needs to be open to be able to paint it */
[5d380b6]360 rc = ui_menu_open(menu, &prect, 0);
[ff6e91b]361 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
362
363 pos.x = 0;
364 pos.y = 0;
365 rc = ui_menu_paint_bg_text(menu, &pos);
366 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
367
368 ui_window_destroy(window);
369 ui_destroy(ui);
370}
371
[95a9cbc]372/** Paint menu */
373PCUT_TEST(paint)
374{
[3c8c580]375 ui_t *ui = NULL;
[c68c18b9]376 ui_window_t *window = NULL;
377 ui_wnd_params_t params;
[95a9cbc]378 ui_menu_t *menu = NULL;
[3c8c580]379 gfx_rect_t prect;
[95a9cbc]380 gfx_coord2_t pos;
381 errno_t rc;
382
[3c8c580]383 rc = ui_create_disp(NULL, &ui);
[95a9cbc]384 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
385
[c68c18b9]386 ui_wnd_params_init(&params);
387 params.caption = "Hello";
388
389 rc = ui_window_create(ui, &params, &window);
[95a9cbc]390 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[c68c18b9]391 PCUT_ASSERT_NOT_NULL(window);
[95a9cbc]392
[46bd63c9]393 rc = ui_menu_create(window, &menu);
[95a9cbc]394 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
395 PCUT_ASSERT_NOT_NULL(menu);
396
[3c8c580]397 prect.p0.x = 0;
398 prect.p0.y = 0;
399 prect.p1.x = 0;
400 prect.p1.y = 0;
[95a9cbc]401
[3c8c580]402 /* Menu needs to be open to be able to paint it */
[5d380b6]403 rc = ui_menu_open(menu, &prect, 0);
[95a9cbc]404 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
405
406 pos.x = 0;
407 pos.y = 0;
[3c8c580]408 rc = ui_menu_paint(menu, &pos);
409 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[95a9cbc]410
[46bd63c9]411 ui_window_destroy(window);
412 ui_destroy(ui);
413}
414
415/** ui_menu_pos_event() inside menu is claimed */
416PCUT_TEST(pos_event_inside)
417{
418 ui_t *ui = NULL;
419 ui_window_t *window = NULL;
420 ui_wnd_params_t params;
421 ui_menu_t *menu = NULL;
422 ui_evclaim_t claimed;
423 gfx_coord2_t pos;
424 pos_event_t event;
425 errno_t rc;
426
427 rc = ui_create_disp(NULL, &ui);
428 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
429
430 ui_wnd_params_init(&params);
431 params.caption = "Hello";
432
433 rc = ui_window_create(ui, &params, &window);
434 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
435 PCUT_ASSERT_NOT_NULL(window);
436
437 rc = ui_menu_create(window, &menu);
438 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
439 PCUT_ASSERT_NOT_NULL(menu);
440
441 pos.x = 0;
442 pos.y = 0;
443 event.type = POS_PRESS;
444 event.hpos = 0;
445 event.vpos = 0;
446 claimed = ui_menu_pos_event(menu, &pos, &event);
447 PCUT_ASSERT_EQUALS(ui_claimed, claimed);
448
[c68c18b9]449 ui_window_destroy(window);
[3c8c580]450 ui_destroy(ui);
[95a9cbc]451}
452
[59768c7]453/** ui_menu_up() with empty menu does nothing */
454PCUT_TEST(up_empty)
455{
456 ui_t *ui = NULL;
457 ui_window_t *window = NULL;
458 ui_wnd_params_t params;
459 ui_menu_t *menu = NULL;
460 gfx_rect_t prect;
461 errno_t rc;
462
463 rc = ui_create_disp(NULL, &ui);
464 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
465
466 ui_wnd_params_init(&params);
467 params.caption = "Hello";
468
469 rc = ui_window_create(ui, &params, &window);
470 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
471 PCUT_ASSERT_NOT_NULL(window);
472
[46bd63c9]473 rc = ui_menu_create(window, &menu);
[59768c7]474 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
475 PCUT_ASSERT_NOT_NULL(menu);
476
477 prect.p0.x = 0;
478 prect.p0.y = 0;
479 prect.p1.x = 0;
480 prect.p1.y = 0;
481
482 /* Menu needs to be open to be able to move around it */
[5d380b6]483 rc = ui_menu_open(menu, &prect, 0);
[59768c7]484 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
485
486 ui_menu_up(menu);
487
488 ui_window_destroy(window);
489 ui_destroy(ui);
490}
491
492/** ui_menu_up() moves one entry up, skips separators, wraps around */
493PCUT_TEST(up)
494{
495 ui_t *ui = NULL;
496 ui_window_t *window = NULL;
497 ui_wnd_params_t params;
498 ui_menu_t *menu = NULL;
499 ui_menu_entry_t *mentry1 = NULL;
500 ui_menu_entry_t *mentry2 = NULL;
501 ui_menu_entry_t *mentry3 = NULL;
502 gfx_rect_t prect;
503 errno_t rc;
504
505 rc = ui_create_disp(NULL, &ui);
506 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
507
508 ui_wnd_params_init(&params);
509 params.caption = "Hello";
510
511 rc = ui_window_create(ui, &params, &window);
512 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
513 PCUT_ASSERT_NOT_NULL(window);
514
[46bd63c9]515 rc = ui_menu_create(window, &menu);
[59768c7]516 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
517 PCUT_ASSERT_NOT_NULL(menu);
518
519 rc = ui_menu_entry_create(menu, "Foo", "F1", &mentry1);
520 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
521 PCUT_ASSERT_NOT_NULL(mentry1);
522
523 rc = ui_menu_entry_sep_create(menu, &mentry2);
524 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
525 PCUT_ASSERT_NOT_NULL(mentry2);
526
527 rc = ui_menu_entry_create(menu, "Bar", "F2", &mentry3);
528 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
529 PCUT_ASSERT_NOT_NULL(mentry3);
530
531 prect.p0.x = 0;
532 prect.p0.y = 0;
533 prect.p1.x = 0;
534 prect.p1.y = 0;
535
536 /* Menu needs to be open to be able to move around it */
[5d380b6]537 rc = ui_menu_open(menu, &prect, 0);
[59768c7]538 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
539
540 /* When menu is open, the first entry is selected */
541 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
542
543 ui_menu_up(menu);
544
545 /* Now we've wrapped around to the last entry */
546 PCUT_ASSERT_EQUALS(mentry3, menu->selected);
547
548 ui_menu_up(menu);
549
550 /* mentry2 is a separator and was skipped */
551 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
552
553 ui_window_destroy(window);
554 ui_destroy(ui);
555}
556
557/** ui_menu_down() with empty menu does nothing */
558PCUT_TEST(down_empty)
559{
560 ui_t *ui = NULL;
561 ui_window_t *window = NULL;
562 ui_wnd_params_t params;
563 ui_menu_t *menu = NULL;
564 gfx_rect_t prect;
565 errno_t rc;
566
567 rc = ui_create_disp(NULL, &ui);
568 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
569
570 ui_wnd_params_init(&params);
571 params.caption = "Hello";
572
573 rc = ui_window_create(ui, &params, &window);
574 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
575 PCUT_ASSERT_NOT_NULL(window);
576
[46bd63c9]577 rc = ui_menu_create(window, &menu);
[59768c7]578 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
579 PCUT_ASSERT_NOT_NULL(menu);
580
581 prect.p0.x = 0;
582 prect.p0.y = 0;
583 prect.p1.x = 0;
584 prect.p1.y = 0;
585
586 /* Menu needs to be open to be able to move around it */
[5d380b6]587 rc = ui_menu_open(menu, &prect, 0);
[59768c7]588 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
589
590 ui_menu_down(menu);
591
592 ui_window_destroy(window);
593 ui_destroy(ui);
594}
595
596/** ui_menu_down() moves one entry down, skips separators, wraps around */
597PCUT_TEST(down)
598{
599 ui_t *ui = NULL;
600 ui_window_t *window = NULL;
601 ui_wnd_params_t params;
602 ui_menu_t *menu = NULL;
603 ui_menu_entry_t *mentry1 = NULL;
604 ui_menu_entry_t *mentry2 = NULL;
605 ui_menu_entry_t *mentry3 = NULL;
606 gfx_rect_t prect;
607 errno_t rc;
608
609 rc = ui_create_disp(NULL, &ui);
610 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
611
612 ui_wnd_params_init(&params);
613 params.caption = "Hello";
614
615 rc = ui_window_create(ui, &params, &window);
616 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
617 PCUT_ASSERT_NOT_NULL(window);
618
[46bd63c9]619 rc = ui_menu_create(window, &menu);
[59768c7]620 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
621 PCUT_ASSERT_NOT_NULL(menu);
622
623 rc = ui_menu_entry_create(menu, "Foo", "F1", &mentry1);
624 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
625 PCUT_ASSERT_NOT_NULL(mentry1);
626
627 rc = ui_menu_entry_sep_create(menu, &mentry2);
628 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
629 PCUT_ASSERT_NOT_NULL(mentry2);
630
631 rc = ui_menu_entry_create(menu, "Bar", "F2", &mentry3);
632 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
633 PCUT_ASSERT_NOT_NULL(mentry3);
634
635 prect.p0.x = 0;
636 prect.p0.y = 0;
637 prect.p1.x = 0;
638 prect.p1.y = 0;
639
640 /* Menu needs to be open to be able to move around it */
[5d380b6]641 rc = ui_menu_open(menu, &prect, 0);
[59768c7]642 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
643
644 /* When menu is open, the first entry is selected */
645 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
646
647 ui_menu_down(menu);
648
649 /* mentry2 is a separator and was skipped */
650 PCUT_ASSERT_EQUALS(mentry3, menu->selected);
651
652 ui_menu_up(menu);
653
654 /* Now we've wrapped around to the first entry */
655 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
656
657 ui_window_destroy(window);
658 ui_destroy(ui);
659}
660
[46bd63c9]661/** Sending an unhandled event does nothing. */
662PCUT_TEST(send_unhandled)
[95a9cbc]663{
664 ui_menu_t *menu = NULL;
665 errno_t rc;
[46bd63c9]666 sysarg_t idev_id;
667 char32_t c;
[95a9cbc]668
[46bd63c9]669 rc = ui_menu_create(NULL, &menu);
[95a9cbc]670 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[46bd63c9]671 PCUT_ASSERT_NOT_NULL(menu);
[95a9cbc]672
[46bd63c9]673 /* Send events without setting callback */
674 c = 'A';
675 idev_id = 42;
676 ui_menu_left(menu, idev_id);
677 ui_menu_right(menu, idev_id);
678 ui_menu_close_req(menu);
679 ui_menu_press_accel(menu, c, idev_id);
[95a9cbc]680
[46bd63c9]681 /* Set dummy callback structure */
682 ui_menu_set_cb(menu, &dummy_cb, NULL);
[95a9cbc]683
[46bd63c9]684 /* Send unhandled events */
685 ui_menu_left(menu, idev_id);
686 ui_menu_right(menu, idev_id);
687 ui_menu_close_req(menu);
688 ui_menu_press_accel(menu, c, idev_id);
689
690 ui_menu_destroy(menu);
691}
692
693/** ui_menu_left() sends left event */
694PCUT_TEST(left)
695{
696 ui_menu_t *menu = NULL;
697 errno_t rc;
698 test_resp_t resp;
699 sysarg_t idev_id;
[95a9cbc]700
[46bd63c9]701 rc = ui_menu_create(NULL, &menu);
[95a9cbc]702 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
703 PCUT_ASSERT_NOT_NULL(menu);
704
[46bd63c9]705 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
[95a9cbc]706
[46bd63c9]707 memset(&resp, 0, sizeof(resp));
708 PCUT_ASSERT_FALSE(resp.left_called);
709
710 idev_id = 42;
711 ui_menu_left(menu, idev_id);
712
713 PCUT_ASSERT_TRUE(resp.left_called);
714 PCUT_ASSERT_EQUALS(menu, resp.menu);
715 PCUT_ASSERT_INT_EQUALS(idev_id, resp.idev_id);
716
717 ui_menu_destroy(menu);
[95a9cbc]718}
719
[46bd63c9]720/** ui_menu_right() sends right event */
721PCUT_TEST(right)
[95a9cbc]722{
723 ui_menu_t *menu = NULL;
724 errno_t rc;
[46bd63c9]725 test_resp_t resp;
726 sysarg_t idev_id;
[95a9cbc]727
[46bd63c9]728 rc = ui_menu_create(NULL, &menu);
[95a9cbc]729 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[46bd63c9]730 PCUT_ASSERT_NOT_NULL(menu);
[95a9cbc]731
[46bd63c9]732 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
[95a9cbc]733
[46bd63c9]734 memset(&resp, 0, sizeof(resp));
735 PCUT_ASSERT_FALSE(resp.right_called);
736
737 idev_id = 42;
738 ui_menu_right(menu, idev_id);
739
740 PCUT_ASSERT_TRUE(resp.right_called);
741 PCUT_ASSERT_EQUALS(menu, resp.menu);
742 PCUT_ASSERT_INT_EQUALS(idev_id, resp.idev_id);
743
744 ui_menu_destroy(menu);
745}
[95a9cbc]746
[46bd63c9]747/** ui_menu_close_req() sends close_req event */
748PCUT_TEST(close_req)
749{
750 ui_menu_t *menu = NULL;
751 errno_t rc;
752 test_resp_t resp;
753
754 rc = ui_menu_create(NULL, &menu);
[95a9cbc]755 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
[46bd63c9]756 PCUT_ASSERT_NOT_NULL(menu);
757
758 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
[95a9cbc]759
[46bd63c9]760 memset(&resp, 0, sizeof(resp));
761 PCUT_ASSERT_FALSE(resp.close_req_called);
762
763 ui_menu_close_req(menu);
764
765 PCUT_ASSERT_TRUE(resp.close_req_called);
766 PCUT_ASSERT_EQUALS(menu, resp.menu);
767
768 ui_menu_destroy(menu);
769}
770
771/** ui_menu_press_accel() sends press_accel event */
772PCUT_TEST(press_accel)
773{
774 ui_menu_t *menu = NULL;
775 errno_t rc;
776 test_resp_t resp;
777 char32_t c;
778 sysarg_t idev_id;
779
780 rc = ui_menu_create(NULL, &menu);
[95a9cbc]781 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
782 PCUT_ASSERT_NOT_NULL(menu);
783
[46bd63c9]784 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
[95a9cbc]785
[46bd63c9]786 memset(&resp, 0, sizeof(resp));
787 PCUT_ASSERT_FALSE(resp.press_accel_called);
[95a9cbc]788
[46bd63c9]789 c = 'A';
790 idev_id = 42;
791 ui_menu_press_accel(menu, c, idev_id);
792
793 PCUT_ASSERT_TRUE(resp.press_accel_called);
794 PCUT_ASSERT_EQUALS(menu, resp.menu);
795 PCUT_ASSERT_EQUALS(c, resp.c);
796 PCUT_ASSERT_INT_EQUALS(idev_id, resp.idev_id);
797
798 ui_menu_destroy(menu);
799}
800
801/** Test menu left callback */
802static void testmenu_left(ui_menu_t *menu, void *arg, sysarg_t idev_id)
803{
804 test_resp_t *resp = (test_resp_t *)arg;
805
806 resp->left_called = true;
807 resp->menu = menu;
808 resp->idev_id = idev_id;
809}
810
811/** Test menu right callback */
812static void testmenu_right(ui_menu_t *menu, void *arg, sysarg_t idev_id)
813{
814 test_resp_t *resp = (test_resp_t *)arg;
815
816 resp->right_called = true;
817 resp->menu = menu;
818 resp->idev_id = idev_id;
819}
820
821/** Test menu close callback */
822static void testmenu_close_req(ui_menu_t *menu, void *arg)
823{
824 test_resp_t *resp = (test_resp_t *)arg;
825
826 resp->close_req_called = true;
827 resp->menu = menu;
828}
829
830/** Test menu press accel callback */
831static void testmenu_press_accel(ui_menu_t *menu, void *arg,
832 char32_t c, sysarg_t kbd_id)
833{
834 test_resp_t *resp = (test_resp_t *)arg;
835
836 resp->press_accel_called = true;
837 resp->menu = menu;
838 resp->c = c;
839 resp->idev_id = kbd_id;
[95a9cbc]840}
841
842PCUT_EXPORT(menu);
Note: See TracBrowser for help on using the repository browser.