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

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3c8c580 was 3c8c580, checked in by jxsvoboda <5887334+jxsvoboda@…>, 4 years ago

Open menu in separate popup window (WIP)

  • Property mode set to 100644
File size: 8.6 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 <str.h>
35#include <ui/control.h>
36#include <ui/menu.h>
37#include <ui/menubar.h>
38#include <ui/resource.h>
39#include <ui/ui.h>
40#include "../private/dummygc.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 dummy_gc_t *dgc;
81 gfx_context_t *gc;
82 ui_resource_t *resource = NULL;
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 = dummygc_create(&dgc);
90 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
91
92 gc = dummygc_get_ctx(dgc);
93
94 rc = ui_resource_create(gc, false, &resource);
95 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
96 PCUT_ASSERT_NOT_NULL(resource);
97
98 rc = ui_menu_bar_create(NULL, resource, &mbar);
99 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
100 PCUT_ASSERT_NOT_NULL(mbar);
101
102 rc = ui_menu_create(mbar, "Test 1", &menu1);
103 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
104 PCUT_ASSERT_NOT_NULL(menu1);
105
106 rc = ui_menu_create(mbar, "Test 1", &menu2);
107 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
108 PCUT_ASSERT_NOT_NULL(menu2);
109
110 m = ui_menu_first(mbar);
111 PCUT_ASSERT_EQUALS(menu1, m);
112
113 m = ui_menu_next(m);
114 PCUT_ASSERT_EQUALS(menu2, m);
115
116 m = ui_menu_next(m);
117 PCUT_ASSERT_NULL(m);
118
119 ui_menu_bar_destroy(mbar);
120 ui_resource_destroy(resource);
121 dummygc_destroy(dgc);
122}
123
124/** ui_menu_caption() returns the menu's caption */
125PCUT_TEST(caption)
126{
127 dummy_gc_t *dgc;
128 gfx_context_t *gc;
129 ui_resource_t *resource = NULL;
130 ui_menu_bar_t *mbar = NULL;
131 ui_menu_t *menu = NULL;
132 const char *caption;
133 errno_t rc;
134
135 rc = dummygc_create(&dgc);
136 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
137
138 gc = dummygc_get_ctx(dgc);
139
140 rc = ui_resource_create(gc, false, &resource);
141 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
142 PCUT_ASSERT_NOT_NULL(resource);
143
144 rc = ui_menu_bar_create(NULL, resource, &mbar);
145 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
146 PCUT_ASSERT_NOT_NULL(mbar);
147
148 rc = ui_menu_create(mbar, "Test", &menu);
149 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
150 PCUT_ASSERT_NOT_NULL(menu);
151
152 caption = ui_menu_caption(menu);
153 PCUT_ASSERT_NOT_NULL(caption);
154
155 PCUT_ASSERT_INT_EQUALS(0, str_cmp(caption, "Test"));
156
157 ui_menu_bar_destroy(mbar);
158 ui_resource_destroy(resource);
159 dummygc_destroy(dgc);
160}
161
162/** ui_menu_get_rect() returns outer menu rectangle */
163PCUT_TEST(get_rect)
164{
165 dummy_gc_t *dgc;
166 gfx_context_t *gc;
167 ui_resource_t *resource = NULL;
168 ui_menu_bar_t *mbar = NULL;
169 ui_menu_t *menu = NULL;
170 gfx_coord2_t pos;
171 gfx_rect_t rect;
172 const char *caption;
173 errno_t rc;
174
175 rc = dummygc_create(&dgc);
176 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
177
178 gc = dummygc_get_ctx(dgc);
179
180 rc = ui_resource_create(gc, false, &resource);
181 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
182 PCUT_ASSERT_NOT_NULL(resource);
183
184 rc = ui_menu_bar_create(NULL, resource, &mbar);
185 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
186 PCUT_ASSERT_NOT_NULL(mbar);
187
188 rc = ui_menu_create(mbar, "Test", &menu);
189 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
190 PCUT_ASSERT_NOT_NULL(menu);
191
192 caption = ui_menu_caption(menu);
193 PCUT_ASSERT_NOT_NULL(caption);
194
195 pos.x = 0;
196 pos.y = 0;
197 ui_menu_get_rect(menu, &pos, &rect);
198
199 PCUT_ASSERT_INT_EQUALS(0, rect.p0.x);
200 PCUT_ASSERT_INT_EQUALS(0, rect.p0.y);
201 PCUT_ASSERT_INT_EQUALS(16, rect.p1.x);
202 PCUT_ASSERT_INT_EQUALS(8, rect.p1.y);
203
204 ui_menu_bar_destroy(mbar);
205 ui_resource_destroy(resource);
206 dummygc_destroy(dgc);
207}
208
209/** Paint menu */
210PCUT_TEST(paint)
211{
212 dummy_gc_t *dgc;
213 gfx_context_t *gc;
214 ui_t *ui = NULL;
215 ui_resource_t *resource = NULL;
216 ui_menu_bar_t *mbar = NULL;
217 ui_menu_t *menu = NULL;
218 gfx_rect_t prect;
219 gfx_coord2_t pos;
220 errno_t rc;
221
222 rc = dummygc_create(&dgc);
223 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
224
225 gc = dummygc_get_ctx(dgc);
226
227 rc = ui_create_disp(NULL, &ui);
228 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
229
230 rc = ui_resource_create(gc, false, &resource);
231 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
232 PCUT_ASSERT_NOT_NULL(resource);
233
234 rc = ui_menu_bar_create(ui, resource, &mbar);
235 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
236 PCUT_ASSERT_NOT_NULL(mbar);
237
238 rc = ui_menu_create(mbar, "Test", &menu);
239 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
240 PCUT_ASSERT_NOT_NULL(menu);
241
242 prect.p0.x = 0;
243 prect.p0.y = 0;
244 prect.p1.x = 0;
245 prect.p1.y = 0;
246
247 /* Menu needs to be open to be able to paint it */
248 rc = ui_menu_open(menu, &prect);
249 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
250
251 pos.x = 0;
252 pos.y = 0;
253 rc = ui_menu_paint(menu, &pos);
254 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
255
256 ui_menu_bar_destroy(mbar);
257 ui_resource_destroy(resource);
258 ui_destroy(ui);
259 dummygc_destroy(dgc);
260}
261
262/** ui_menu_pos_event() inside menu is claimed */
263PCUT_TEST(pos_event_inside)
264{
265 dummy_gc_t *dgc;
266 gfx_context_t *gc;
267 ui_resource_t *resource = NULL;
268 ui_menu_bar_t *mbar = NULL;
269 ui_menu_t *menu = NULL;
270 ui_evclaim_t claimed;
271 gfx_coord2_t pos;
272 pos_event_t event;
273 errno_t rc;
274
275 rc = dummygc_create(&dgc);
276 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
277
278 gc = dummygc_get_ctx(dgc);
279
280 rc = ui_resource_create(gc, false, &resource);
281 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
282 PCUT_ASSERT_NOT_NULL(resource);
283
284 rc = ui_menu_bar_create(NULL, resource, &mbar);
285 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
286 PCUT_ASSERT_NOT_NULL(mbar);
287
288 rc = ui_menu_create(mbar, "Test", &menu);
289 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
290 PCUT_ASSERT_NOT_NULL(menu);
291
292 pos.x = 0;
293 pos.y = 0;
294 event.type = POS_PRESS;
295 event.hpos = 0;
296 event.vpos = 0;
297 claimed = ui_menu_pos_event(menu, &pos, &event);
298 PCUT_ASSERT_EQUALS(ui_claimed, claimed);
299
300 ui_menu_bar_destroy(mbar);
301 ui_resource_destroy(resource);
302 dummygc_destroy(dgc);
303}
304
305/** Computing menu geometry */
306PCUT_TEST(get_geom)
307{
308 dummy_gc_t *dgc;
309 gfx_context_t *gc;
310 ui_resource_t *resource = NULL;
311 ui_menu_bar_t *mbar = NULL;
312 ui_menu_t *menu = NULL;
313 ui_menu_geom_t geom;
314 gfx_coord2_t pos;
315 errno_t rc;
316
317 rc = dummygc_create(&dgc);
318 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
319
320 gc = dummygc_get_ctx(dgc);
321
322 rc = ui_resource_create(gc, false, &resource);
323 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
324 PCUT_ASSERT_NOT_NULL(resource);
325
326 rc = ui_menu_bar_create(NULL, resource, &mbar);
327 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
328 PCUT_ASSERT_NOT_NULL(mbar);
329
330 rc = ui_menu_create(mbar, "Test", &menu);
331 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
332 PCUT_ASSERT_NOT_NULL(menu);
333
334 pos.x = 0;
335 pos.y = 0;
336 ui_menu_get_geom(menu, &pos, &geom);
337
338 PCUT_ASSERT_INT_EQUALS(0, geom.outer_rect.p0.x);
339 PCUT_ASSERT_INT_EQUALS(0, geom.outer_rect.p0.y);
340 PCUT_ASSERT_INT_EQUALS(16, geom.outer_rect.p1.x);
341 PCUT_ASSERT_INT_EQUALS(8, geom.outer_rect.p1.y);
342 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p0.x);
343 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p0.y);
344 PCUT_ASSERT_INT_EQUALS(12, geom.entries_rect.p1.x);
345 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p1.y);
346
347 ui_menu_bar_destroy(mbar);
348 ui_resource_destroy(resource);
349 dummygc_destroy(dgc);
350}
351
352PCUT_EXPORT(menu);
Note: See TracBrowser for help on using the repository browser.