Editor needs to hide cursor when menu bar is activated
[helenos.git] / uspace / lib / ui / test / tabset.c
blobb8c6c676c144514633a7521a7d617861599f3f9f
1 /*
2 * Copyright (c) 2023 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/coord.h>
30 #include <mem.h>
31 #include <pcut/pcut.h>
32 #include <stdbool.h>
33 #include <ui/control.h>
34 #include <ui/tab.h>
35 #include <ui/tabset.h>
36 #include <ui/testctl.h>
37 #include <ui/ui.h>
38 #include <ui/window.h>
39 #include "../private/tabset.h"
41 PCUT_INIT;
43 PCUT_TEST_SUITE(tabset);
45 /** Create and destroy tab set */
46 PCUT_TEST(create_destroy)
48 ui_tab_set_t *tabset = NULL;
49 errno_t rc;
51 rc = ui_tab_set_create(NULL, &tabset);
52 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
53 PCUT_ASSERT_NOT_NULL(tabset);
55 ui_tab_set_destroy(tabset);
58 /** ui_tab_set_destroy() can take NULL argument (no-op) */
59 PCUT_TEST(destroy_null)
61 ui_tab_set_destroy(NULL);
64 /** ui_tab_set_ctl() returns control that has a working virtual destructor */
65 PCUT_TEST(ctl)
67 ui_tab_set_t *tabset = NULL;
68 ui_control_t *control;
69 errno_t rc;
71 rc = ui_tab_set_create(NULL, &tabset);
72 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
73 PCUT_ASSERT_NOT_NULL(tabset);
75 control = ui_tab_set_ctl(tabset);
76 PCUT_ASSERT_NOT_NULL(control);
78 ui_control_destroy(control);
81 /** Set tab set rectangle sets internal field */
82 PCUT_TEST(set_rect)
84 errno_t rc;
85 ui_t *ui = NULL;
86 ui_window_t *window = NULL;
87 ui_wnd_params_t params;
88 ui_resource_t *res;
89 ui_tab_set_t *tabset = NULL;
90 gfx_rect_t rect;
92 rc = ui_create_disp(NULL, &ui);
93 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
95 ui_wnd_params_init(&params);
96 params.caption = "Hello";
98 rc = ui_window_create(ui, &params, &window);
99 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
100 PCUT_ASSERT_NOT_NULL(window);
102 res = ui_window_get_res(window);
104 rc = ui_tab_set_create(res, &tabset);
105 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
106 PCUT_ASSERT_NOT_NULL(tabset);
108 rect.p0.x = 1;
109 rect.p0.y = 2;
110 rect.p1.x = 3;
111 rect.p1.y = 4;
113 ui_tab_set_set_rect(tabset, &rect);
114 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tabset->rect.p0.x);
115 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tabset->rect.p0.y);
116 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tabset->rect.p1.x);
117 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tabset->rect.p1.y);
119 ui_tab_set_destroy(tabset);
120 ui_window_destroy(window);
121 ui_destroy(ui);
124 /** Paint tab set */
125 PCUT_TEST(paint)
127 ui_t *ui = NULL;
128 ui_window_t *window = NULL;
129 ui_wnd_params_t params;
130 ui_resource_t *res;
131 ui_tab_set_t *tabset = NULL;
132 errno_t rc;
134 rc = ui_create_disp(NULL, &ui);
135 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
137 ui_wnd_params_init(&params);
138 params.caption = "Hello";
140 rc = ui_window_create(ui, &params, &window);
141 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
142 PCUT_ASSERT_NOT_NULL(window);
144 res = ui_window_get_res(window);
146 rc = ui_tab_set_create(res, &tabset);
147 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
148 PCUT_ASSERT_NOT_NULL(tabset);
150 rc = ui_tab_set_paint(tabset);
151 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
153 ui_tab_set_destroy(tabset);
154 ui_window_destroy(window);
155 ui_destroy(ui);
158 /** Deliver tab set keyboard event */
159 PCUT_TEST(kbd_event)
161 ui_t *ui = NULL;
162 ui_window_t *window = NULL;
163 ui_wnd_params_t params;
164 ui_resource_t *res;
165 ui_tab_set_t *tabset = NULL;
166 ui_tab_t *tab = NULL;
167 ui_evclaim_t claimed;
168 kbd_event_t event;
169 ui_test_ctl_t *testctl = NULL;
170 ui_tc_resp_t resp;
171 errno_t rc;
173 rc = ui_create_disp(NULL, &ui);
174 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
176 ui_wnd_params_init(&params);
177 params.caption = "Hello";
179 rc = ui_window_create(ui, &params, &window);
180 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
181 PCUT_ASSERT_NOT_NULL(window);
183 res = ui_window_get_res(window);
185 rc = ui_tab_set_create(res, &tabset);
186 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
187 PCUT_ASSERT_NOT_NULL(tabset);
189 /* Without anytabs, event should be unclaimed */
190 event.type = KEY_PRESS;
191 event.key = KC_ENTER;
192 event.mods = 0;
193 claimed = ui_tab_set_kbd_event(tabset, &event);
194 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
195 PCUT_ASSERT_EQUALS(ui_unclaimed, claimed);
197 rc = ui_tab_create(tabset, "Test", &tab);
198 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
199 PCUT_ASSERT_NOT_NULL(tab);
201 rc = ui_test_ctl_create(&resp, &testctl);
202 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
204 /* Set up response */
205 ui_tab_add(tab, ui_test_ctl_ctl(testctl));
206 resp.claim = ui_claimed;
207 resp.kbd = false;
209 /* Send keyboard event */
210 event.type = KEY_PRESS;
211 event.key = KC_F10;
212 event.mods = 0;
213 claimed = ui_tab_set_kbd_event(tabset, &event);
214 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
215 PCUT_ASSERT_EQUALS(ui_claimed, claimed);
217 /* Make sure event was delivered */
218 PCUT_ASSERT_TRUE(resp.kbd);
219 PCUT_ASSERT_EQUALS(event.type, resp.kevent.type);
220 PCUT_ASSERT_EQUALS(event.key, resp.kevent.key);
221 PCUT_ASSERT_EQUALS(event.mods, resp.kevent.mods);
223 ui_tab_set_destroy(tabset);
224 ui_window_destroy(window);
225 ui_destroy(ui);
228 /** Press event on tab handle selects tab */
229 PCUT_TEST(pos_event_select)
231 ui_t *ui = NULL;
232 ui_window_t *window = NULL;
233 ui_wnd_params_t params;
234 ui_resource_t *res;
235 ui_tab_set_t *tabset = NULL;
236 ui_tab_t *tab1 = NULL;
237 ui_tab_t *tab2 = NULL;
238 ui_evclaim_t claimed;
239 pos_event_t event;
240 errno_t rc;
242 rc = ui_create_disp(NULL, &ui);
243 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
245 ui_wnd_params_init(&params);
246 params.caption = "Hello";
248 rc = ui_window_create(ui, &params, &window);
249 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
250 PCUT_ASSERT_NOT_NULL(window);
252 res = ui_window_get_res(window);
254 rc = ui_tab_set_create(res, &tabset);
255 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
256 PCUT_ASSERT_NOT_NULL(tabset);
258 /* Without any tabs, event should be unclaimed */
259 event.type = POS_PRESS;
260 event.hpos = 80;
261 event.vpos = 4;
262 event.btn_num = 1;
263 claimed = ui_tab_set_pos_event(tabset, &event);
264 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
265 PCUT_ASSERT_EQUALS(ui_unclaimed, claimed);
267 rc = ui_tab_create(tabset, "Test 1", &tab1);
268 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
270 /* The first added tab should be automatically selected */
271 PCUT_ASSERT_EQUALS(tab1, tabset->selected);
273 rc = ui_tab_create(tabset, "Test 2", &tab2);
274 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
276 /* After adding a second tab the first should still be selected */
277 PCUT_ASSERT_EQUALS(tab1, tabset->selected);
279 event.type = POS_PRESS;
280 event.hpos = 80;
281 event.vpos = 4;
282 event.btn_num = 1;
283 claimed = ui_tab_set_pos_event(tabset, &event);
284 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
285 PCUT_ASSERT_EQUALS(ui_claimed, claimed);
287 /* Clicking the second tab handle should select tab2 */
288 PCUT_ASSERT_EQUALS(tab2, tabset->selected);
290 ui_tab_set_destroy(tabset);
291 ui_window_destroy(window);
292 ui_destroy(ui);
295 /** ui_tab_set_select() selects tab */
296 PCUT_TEST(select)
298 ui_t *ui = NULL;
299 ui_window_t *window = NULL;
300 ui_wnd_params_t params;
301 ui_resource_t *res;
302 ui_tab_set_t *tabset = NULL;
303 ui_tab_t *tab1 = NULL;
304 ui_tab_t *tab2 = NULL;
305 errno_t rc;
307 rc = ui_create_disp(NULL, &ui);
308 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
310 ui_wnd_params_init(&params);
311 params.caption = "Hello";
313 rc = ui_window_create(ui, &params, &window);
314 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
315 PCUT_ASSERT_NOT_NULL(window);
317 res = ui_window_get_res(window);
319 rc = ui_tab_set_create(res, &tabset);
320 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
321 PCUT_ASSERT_NOT_NULL(tabset);
323 rc = ui_tab_create(tabset, "Test 1", &tab1);
324 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
326 /* The first added tab should be automatically selected */
327 PCUT_ASSERT_EQUALS(tab1, tabset->selected);
329 rc = ui_tab_create(tabset, "Test 2", &tab2);
330 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
332 /* After adding a second tab the first should still be selected */
333 PCUT_ASSERT_EQUALS(tab1, tabset->selected);
335 /* Select second tab */
336 ui_tab_set_select(tabset, tab2);
338 /* Now the second tab should be selected */
339 PCUT_ASSERT_EQUALS(tab2, tabset->selected);
341 ui_tab_set_destroy(tabset);
342 ui_window_destroy(window);
343 ui_destroy(ui);
346 PCUT_EXPORT(tabset);