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

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

Create menu windows in the correct seat

Add a mechanism to set the seat of a new display window, UI window,
UI popup - input device ID. This is set to the ID of the device which
activated the menu (mouse, keyboard). The display server determines
the correct seat from there.

This makes sure clicking outside closes the correct pop-up window.

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