source: mainline/uspace/lib/ui/test/wdecor.c@ c77cfd8

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

Maximizing/unmaximizing a window

  • Property mode set to 100644
File size: 26.9 KB
Line 
1/*
2 * Copyright (c) 2022 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/pbutton.h>
35#include <ui/resource.h>
36#include <ui/wdecor.h>
37#include "../private/wdecor.h"
38
39PCUT_INIT;
40
41PCUT_TEST_SUITE(wdecor);
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_wdecor_maximize(ui_wdecor_t *, void *);
65static void test_wdecor_unmaximize(ui_wdecor_t *, void *);
66static void test_wdecor_close(ui_wdecor_t *, void *);
67static void test_wdecor_move(ui_wdecor_t *, void *, gfx_coord2_t *);
68static void test_wdecor_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
69 gfx_coord2_t *);
70static void test_wdecor_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
71
72static ui_wdecor_cb_t test_wdecor_cb = {
73 .maximize = test_wdecor_maximize,
74 .unmaximize = test_wdecor_unmaximize,
75 .close = test_wdecor_close,
76 .move = test_wdecor_move,
77 .resize = test_wdecor_resize,
78 .set_cursor = test_wdecor_set_cursor
79};
80
81static ui_wdecor_cb_t dummy_wdecor_cb = {
82};
83
84typedef struct {
85 bool bm_created;
86 bool bm_destroyed;
87 gfx_bitmap_params_t bm_params;
88 void *bm_pixels;
89 gfx_rect_t bm_srect;
90 gfx_coord2_t bm_offs;
91 bool bm_rendered;
92 bool bm_got_alloc;
93} test_gc_t;
94
95typedef struct {
96 test_gc_t *tgc;
97 gfx_bitmap_alloc_t alloc;
98 bool myalloc;
99} testgc_bitmap_t;
100
101typedef struct {
102 bool maximize;
103 bool unmaximize;
104 bool close;
105 bool move;
106 gfx_coord2_t pos;
107 bool resize;
108 ui_wdecor_rsztype_t rsztype;
109 bool set_cursor;
110 ui_stock_cursor_t cursor;
111} test_cb_resp_t;
112
113/** Create and destroy button */
114PCUT_TEST(create_destroy)
115{
116 ui_wdecor_t *wdecor = NULL;
117 errno_t rc;
118
119 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
120 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
121 PCUT_ASSERT_NOT_NULL(wdecor);
122
123 ui_wdecor_destroy(wdecor);
124}
125
126/** ui_wdecor_destroy() can take NULL argument (no-op) */
127PCUT_TEST(destroy_null)
128{
129 ui_wdecor_destroy(NULL);
130}
131
132/** Set window decoration rectangle sets internal field */
133PCUT_TEST(set_rect)
134{
135 ui_wdecor_t *wdecor;
136 gfx_rect_t rect;
137 errno_t rc;
138
139 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
140 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
141
142 rect.p0.x = 1;
143 rect.p0.y = 2;
144 rect.p1.x = 3;
145 rect.p1.y = 4;
146
147 ui_wdecor_set_rect(wdecor, &rect);
148 PCUT_ASSERT_INT_EQUALS(rect.p0.x, wdecor->rect.p0.x);
149 PCUT_ASSERT_INT_EQUALS(rect.p0.y, wdecor->rect.p0.y);
150 PCUT_ASSERT_INT_EQUALS(rect.p1.x, wdecor->rect.p1.x);
151 PCUT_ASSERT_INT_EQUALS(rect.p1.y, wdecor->rect.p1.y);
152
153 ui_wdecor_destroy(wdecor);
154}
155
156/** Set window decoration active sets internal field */
157PCUT_TEST(set_active)
158{
159 ui_wdecor_t *wdecor;
160 errno_t rc;
161
162 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
163 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
164
165 PCUT_ASSERT_TRUE(wdecor->active);
166
167 ui_wdecor_set_active(wdecor, false);
168 PCUT_ASSERT_FALSE(wdecor->active);
169
170 ui_wdecor_set_active(wdecor, true);
171 PCUT_ASSERT_TRUE(wdecor->active);
172
173 ui_wdecor_destroy(wdecor);
174}
175
176/** Set window decoration maximized sets internal field */
177PCUT_TEST(set_maximized)
178{
179 ui_wdecor_t *wdecor;
180 errno_t rc;
181
182 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
183 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
184
185 PCUT_ASSERT_TRUE(wdecor->active);
186
187 ui_wdecor_set_maximized(wdecor, false);
188 PCUT_ASSERT_FALSE(wdecor->maximized);
189
190 ui_wdecor_set_maximized(wdecor, true);
191 PCUT_ASSERT_TRUE(wdecor->maximized);
192
193 ui_wdecor_destroy(wdecor);
194}
195
196/** Paint button */
197PCUT_TEST(paint)
198{
199 errno_t rc;
200 gfx_context_t *gc = NULL;
201 test_gc_t tgc;
202 ui_resource_t *resource = NULL;
203 ui_wdecor_t *wdecor;
204
205 memset(&tgc, 0, sizeof(tgc));
206 rc = gfx_context_new(&ops, &tgc, &gc);
207 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
208
209 rc = ui_resource_create(gc, false, &resource);
210 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
211 PCUT_ASSERT_NOT_NULL(resource);
212
213 rc = ui_wdecor_create(resource, "Hello", ui_wds_none, &wdecor);
214 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
215
216 rc = ui_wdecor_paint(wdecor);
217 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
218
219 ui_wdecor_destroy(wdecor);
220 ui_resource_destroy(resource);
221
222 rc = gfx_context_delete(gc);
223 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
224}
225
226/** Test ui_wdecor_maximize() */
227PCUT_TEST(maximize)
228{
229 errno_t rc;
230 ui_wdecor_t *wdecor;
231 test_cb_resp_t resp;
232
233 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
234 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
235
236 /* Maximize callback with no callbacks set */
237 ui_wdecor_maximize(wdecor);
238
239 /* Maxmimize callback with maximize callback not implemented */
240 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
241 ui_wdecor_maximize(wdecor);
242
243 /* Maximize callback with real callback set */
244 resp.maximize = false;
245 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
246 ui_wdecor_maximize(wdecor);
247 PCUT_ASSERT_TRUE(resp.maximize);
248
249 ui_wdecor_destroy(wdecor);
250}
251
252/** Test ui_wdecor_unmaximize() */
253PCUT_TEST(unmaximize)
254{
255 errno_t rc;
256 ui_wdecor_t *wdecor;
257 test_cb_resp_t resp;
258
259 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
260 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
261
262 /* Unmaximize callback with no callbacks set */
263 ui_wdecor_unmaximize(wdecor);
264
265 /* Unmaximize callback with unmaximize callback not implemented */
266 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
267 ui_wdecor_unmaximize(wdecor);
268
269 /* Unmaximize callback with real callback set */
270 resp.unmaximize = false;
271 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
272 ui_wdecor_unmaximize(wdecor);
273 PCUT_ASSERT_TRUE(resp.unmaximize);
274
275 ui_wdecor_destroy(wdecor);
276}
277
278/** Test ui_wdecor_close() */
279PCUT_TEST(close)
280{
281 errno_t rc;
282 ui_wdecor_t *wdecor;
283 test_cb_resp_t resp;
284
285 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
286 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
287
288 /* Close callback with no callbacks set */
289 ui_wdecor_close(wdecor);
290
291 /* Close callback with close callback not implemented */
292 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
293 ui_wdecor_close(wdecor);
294
295 /* Close callback with real callback set */
296 resp.close = false;
297 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
298 ui_wdecor_close(wdecor);
299 PCUT_ASSERT_TRUE(resp.close);
300
301 ui_wdecor_destroy(wdecor);
302}
303
304/** Test ui_wdecor_move() */
305PCUT_TEST(move)
306{
307 errno_t rc;
308 ui_wdecor_t *wdecor;
309 test_cb_resp_t resp;
310 gfx_coord2_t pos;
311
312 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
313 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
314
315 pos.x = 3;
316 pos.y = 4;
317
318 /* Move callback with no callbacks set */
319 ui_wdecor_move(wdecor, &pos);
320
321 /* Move callback with move callback not implemented */
322 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
323 ui_wdecor_move(wdecor, &pos);
324
325 /* Move callback with real callback set */
326 resp.move = false;
327 resp.pos.x = 0;
328 resp.pos.y = 0;
329 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
330 ui_wdecor_move(wdecor, &pos);
331 PCUT_ASSERT_TRUE(resp.move);
332 PCUT_ASSERT_INT_EQUALS(pos.x, resp.pos.x);
333 PCUT_ASSERT_INT_EQUALS(pos.y, resp.pos.y);
334
335 ui_wdecor_destroy(wdecor);
336}
337
338/** Test ui_wdecor_resize() */
339PCUT_TEST(resize)
340{
341 errno_t rc;
342 ui_wdecor_t *wdecor;
343 test_cb_resp_t resp;
344 ui_wdecor_rsztype_t rsztype;
345 gfx_coord2_t pos;
346
347 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
348 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
349
350 rsztype = ui_wr_bottom;
351 pos.x = 3;
352 pos.y = 4;
353
354 /* Resize callback with no callbacks set */
355 ui_wdecor_resize(wdecor, rsztype, &pos);
356
357 /* Resize callback with move callback not implemented */
358 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
359 ui_wdecor_resize(wdecor, rsztype, &pos);
360
361 /* Resize callback with real callback set */
362 resp.resize = false;
363 resp.rsztype = ui_wr_none;
364 resp.pos.x = 0;
365 resp.pos.y = 0;
366 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
367 ui_wdecor_resize(wdecor, rsztype, &pos);
368 PCUT_ASSERT_TRUE(resp.resize);
369 PCUT_ASSERT_INT_EQUALS(rsztype, resp.rsztype);
370 PCUT_ASSERT_INT_EQUALS(pos.x, resp.pos.x);
371 PCUT_ASSERT_INT_EQUALS(pos.y, resp.pos.y);
372
373 ui_wdecor_destroy(wdecor);
374}
375
376/** Test ui_wdecor_set_cursor() */
377PCUT_TEST(set_cursor)
378{
379 errno_t rc;
380 ui_wdecor_t *wdecor;
381 test_cb_resp_t resp;
382 ui_stock_cursor_t cursor;
383
384 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
385 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
386
387 cursor = ui_curs_size_uldr;
388
389 /* Set cursor callback with no callbacks set */
390 ui_wdecor_set_cursor(wdecor, cursor);
391
392 /* Set cursor callback with move callback not implemented */
393 ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
394 ui_wdecor_set_cursor(wdecor, cursor);
395
396 /* Set cursor callback with real callback set */
397 resp.set_cursor = false;
398 resp.cursor = ui_curs_arrow;
399 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
400 ui_wdecor_set_cursor(wdecor, cursor);
401 PCUT_ASSERT_TRUE(resp.set_cursor);
402 PCUT_ASSERT_INT_EQUALS(cursor, resp.cursor);
403
404 ui_wdecor_destroy(wdecor);
405}
406
407/** Clicking the close button generates close callback */
408PCUT_TEST(close_btn_clicked)
409{
410 ui_wdecor_t *wdecor;
411 gfx_rect_t rect;
412 test_cb_resp_t resp;
413 errno_t rc;
414
415 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
416 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
417
418 rect.p0.x = 10;
419 rect.p0.y = 20;
420 rect.p1.x = 100;
421 rect.p1.y = 200;
422
423 ui_wdecor_set_rect(wdecor, &rect);
424
425 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, (void *) &resp);
426
427 resp.close = false;
428
429 ui_pbutton_clicked(wdecor->btn_close);
430 PCUT_ASSERT_TRUE(resp.close);
431
432 ui_wdecor_destroy(wdecor);
433}
434
435/** Button press on title bar generates move callback */
436PCUT_TEST(pos_event_move)
437{
438 errno_t rc;
439 gfx_rect_t rect;
440 pos_event_t event;
441 gfx_context_t *gc = NULL;
442 test_gc_t tgc;
443 test_cb_resp_t resp;
444 ui_resource_t *resource = NULL;
445 ui_wdecor_t *wdecor;
446
447 memset(&tgc, 0, sizeof(tgc));
448 rc = gfx_context_new(&ops, &tgc, &gc);
449 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
450
451 rc = ui_resource_create(gc, false, &resource);
452 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
453 PCUT_ASSERT_NOT_NULL(resource);
454
455 rc = ui_wdecor_create(resource, "Hello", ui_wds_decorated, &wdecor);
456 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
457
458 rect.p0.x = 10;
459 rect.p0.y = 20;
460 rect.p1.x = 100;
461 rect.p1.y = 200;
462
463 ui_wdecor_set_rect(wdecor, &rect);
464
465 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, (void *) &resp);
466
467 resp.move = false;
468 resp.pos.x = 0;
469 resp.pos.y = 0;
470
471 event.type = POS_PRESS;
472 event.hpos = 50;
473 event.vpos = 25;
474 ui_wdecor_pos_event(wdecor, &event);
475
476 PCUT_ASSERT_TRUE(resp.move);
477 PCUT_ASSERT_INT_EQUALS(event.hpos, resp.pos.x);
478 PCUT_ASSERT_INT_EQUALS(event.vpos, resp.pos.y);
479
480 ui_wdecor_destroy(wdecor);
481 ui_resource_destroy(resource);
482
483 rc = gfx_context_delete(gc);
484 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
485}
486
487/** ui_wdecor_get_geom() with ui_wds_none produces the correct geometry */
488PCUT_TEST(get_geom_none)
489{
490 gfx_context_t *gc = NULL;
491 test_gc_t tgc;
492 ui_resource_t *resource = NULL;
493 ui_wdecor_t *wdecor;
494 gfx_rect_t rect;
495 ui_wdecor_geom_t geom;
496 errno_t rc;
497
498 memset(&tgc, 0, sizeof(tgc));
499 rc = gfx_context_new(&ops, &tgc, &gc);
500 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
501
502 rc = ui_resource_create(gc, false, &resource);
503 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
504 PCUT_ASSERT_NOT_NULL(resource);
505
506 rc = ui_wdecor_create(resource, "Hello", ui_wds_none, &wdecor);
507 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
508
509 rect.p0.x = 10;
510 rect.p0.y = 20;
511 rect.p1.x = 100;
512 rect.p1.y = 200;
513
514 ui_wdecor_set_rect(wdecor, &rect);
515 ui_wdecor_get_geom(wdecor, &geom);
516
517 PCUT_ASSERT_INT_EQUALS(10, geom.interior_rect.p0.x);
518 PCUT_ASSERT_INT_EQUALS(20, geom.interior_rect.p0.y);
519 PCUT_ASSERT_INT_EQUALS(100, geom.interior_rect.p1.x);
520 PCUT_ASSERT_INT_EQUALS(200, geom.interior_rect.p1.y);
521
522 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.x);
523 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.y);
524 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.x);
525 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.y);
526
527 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.x);
528 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.y);
529 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.x);
530 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.y);
531
532 PCUT_ASSERT_INT_EQUALS(10, geom.app_area_rect.p0.x);
533 PCUT_ASSERT_INT_EQUALS(20, geom.app_area_rect.p0.y);
534 PCUT_ASSERT_INT_EQUALS(100, geom.app_area_rect.p1.x);
535 PCUT_ASSERT_INT_EQUALS(200, geom.app_area_rect.p1.y);
536
537 ui_wdecor_destroy(wdecor);
538 ui_resource_destroy(resource);
539
540 rc = gfx_context_delete(gc);
541 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
542}
543
544/** ui_wdecor_get_geom() with ui_wds_frame produces the correct geometry */
545PCUT_TEST(get_geom_frame)
546{
547 gfx_context_t *gc = NULL;
548 test_gc_t tgc;
549 ui_resource_t *resource = NULL;
550 ui_wdecor_t *wdecor;
551 gfx_rect_t rect;
552 ui_wdecor_geom_t geom;
553 errno_t rc;
554
555 memset(&tgc, 0, sizeof(tgc));
556 rc = gfx_context_new(&ops, &tgc, &gc);
557 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
558
559 rc = ui_resource_create(gc, false, &resource);
560 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
561 PCUT_ASSERT_NOT_NULL(resource);
562
563 rc = ui_wdecor_create(resource, "Hello", ui_wds_frame, &wdecor);
564 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
565
566 rect.p0.x = 10;
567 rect.p0.y = 20;
568 rect.p1.x = 100;
569 rect.p1.y = 200;
570
571 ui_wdecor_set_rect(wdecor, &rect);
572 ui_wdecor_get_geom(wdecor, &geom);
573
574 PCUT_ASSERT_INT_EQUALS(14, geom.interior_rect.p0.x);
575 PCUT_ASSERT_INT_EQUALS(24, geom.interior_rect.p0.y);
576 PCUT_ASSERT_INT_EQUALS(96, geom.interior_rect.p1.x);
577 PCUT_ASSERT_INT_EQUALS(196, geom.interior_rect.p1.y);
578
579 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.x);
580 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p0.y);
581 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.x);
582 PCUT_ASSERT_INT_EQUALS(0, geom.title_bar_rect.p1.y);
583
584 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.x);
585 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.y);
586 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.x);
587 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.y);
588
589 PCUT_ASSERT_INT_EQUALS(14, geom.app_area_rect.p0.x);
590 PCUT_ASSERT_INT_EQUALS(24, geom.app_area_rect.p0.y);
591 PCUT_ASSERT_INT_EQUALS(96, geom.app_area_rect.p1.x);
592 PCUT_ASSERT_INT_EQUALS(196, geom.app_area_rect.p1.y);
593
594 ui_wdecor_destroy(wdecor);
595 ui_resource_destroy(resource);
596
597 rc = gfx_context_delete(gc);
598 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
599}
600
601/** ui_wdecor_get_geom() with ui_wds_frame | ui_wds_titlebar */
602PCUT_TEST(get_geom_frame_titlebar)
603{
604 gfx_context_t *gc = NULL;
605 test_gc_t tgc;
606 ui_resource_t *resource = NULL;
607 ui_wdecor_t *wdecor;
608 gfx_rect_t rect;
609 ui_wdecor_geom_t geom;
610 errno_t rc;
611
612 memset(&tgc, 0, sizeof(tgc));
613 rc = gfx_context_new(&ops, &tgc, &gc);
614 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
615
616 rc = ui_resource_create(gc, false, &resource);
617 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
618 PCUT_ASSERT_NOT_NULL(resource);
619
620 rc = ui_wdecor_create(resource, "Hello", ui_wds_frame | ui_wds_titlebar,
621 &wdecor);
622 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
623
624 rect.p0.x = 10;
625 rect.p0.y = 20;
626 rect.p1.x = 100;
627 rect.p1.y = 200;
628
629 ui_wdecor_set_rect(wdecor, &rect);
630 ui_wdecor_get_geom(wdecor, &geom);
631
632 PCUT_ASSERT_INT_EQUALS(14, geom.interior_rect.p0.x);
633 PCUT_ASSERT_INT_EQUALS(24, geom.interior_rect.p0.y);
634 PCUT_ASSERT_INT_EQUALS(96, geom.interior_rect.p1.x);
635 PCUT_ASSERT_INT_EQUALS(196, geom.interior_rect.p1.y);
636
637 PCUT_ASSERT_INT_EQUALS(14, geom.title_bar_rect.p0.x);
638 PCUT_ASSERT_INT_EQUALS(24, geom.title_bar_rect.p0.y);
639 PCUT_ASSERT_INT_EQUALS(96, geom.title_bar_rect.p1.x);
640 PCUT_ASSERT_INT_EQUALS(46, geom.title_bar_rect.p1.y);
641
642 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.x);
643 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p0.y);
644 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.x);
645 PCUT_ASSERT_INT_EQUALS(0, geom.btn_close_rect.p1.y);
646
647 PCUT_ASSERT_INT_EQUALS(14, geom.app_area_rect.p0.x);
648 PCUT_ASSERT_INT_EQUALS(46, geom.app_area_rect.p0.y);
649 PCUT_ASSERT_INT_EQUALS(96, geom.app_area_rect.p1.x);
650 PCUT_ASSERT_INT_EQUALS(196, geom.app_area_rect.p1.y);
651
652 ui_wdecor_destroy(wdecor);
653 ui_resource_destroy(resource);
654
655 rc = gfx_context_delete(gc);
656 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
657}
658
659/** ui_wdecor_get_geom() with ui_wds_decorated produces the correct geometry */
660PCUT_TEST(get_geom_decorated)
661{
662 gfx_context_t *gc = NULL;
663 test_gc_t tgc;
664 ui_resource_t *resource = NULL;
665 ui_wdecor_t *wdecor;
666 gfx_rect_t rect;
667 ui_wdecor_geom_t geom;
668 errno_t rc;
669
670 memset(&tgc, 0, sizeof(tgc));
671 rc = gfx_context_new(&ops, &tgc, &gc);
672 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
673
674 rc = ui_resource_create(gc, false, &resource);
675 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
676 PCUT_ASSERT_NOT_NULL(resource);
677
678 rc = ui_wdecor_create(resource, "Hello", ui_wds_decorated, &wdecor);
679 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
680
681 rect.p0.x = 10;
682 rect.p0.y = 20;
683 rect.p1.x = 100;
684 rect.p1.y = 200;
685
686 ui_wdecor_set_rect(wdecor, &rect);
687 ui_wdecor_get_geom(wdecor, &geom);
688
689 PCUT_ASSERT_INT_EQUALS(14, geom.interior_rect.p0.x);
690 PCUT_ASSERT_INT_EQUALS(24, geom.interior_rect.p0.y);
691 PCUT_ASSERT_INT_EQUALS(96, geom.interior_rect.p1.x);
692 PCUT_ASSERT_INT_EQUALS(196, geom.interior_rect.p1.y);
693
694 PCUT_ASSERT_INT_EQUALS(14, geom.title_bar_rect.p0.x);
695 PCUT_ASSERT_INT_EQUALS(24, geom.title_bar_rect.p0.y);
696 PCUT_ASSERT_INT_EQUALS(96, geom.title_bar_rect.p1.x);
697 PCUT_ASSERT_INT_EQUALS(46, geom.title_bar_rect.p1.y);
698
699 PCUT_ASSERT_INT_EQUALS(75, geom.btn_close_rect.p0.x);
700 PCUT_ASSERT_INT_EQUALS(25, geom.btn_close_rect.p0.y);
701 PCUT_ASSERT_INT_EQUALS(95, geom.btn_close_rect.p1.x);
702 PCUT_ASSERT_INT_EQUALS(45, geom.btn_close_rect.p1.y);
703
704 PCUT_ASSERT_INT_EQUALS(14, geom.app_area_rect.p0.x);
705 PCUT_ASSERT_INT_EQUALS(46, geom.app_area_rect.p0.y);
706 PCUT_ASSERT_INT_EQUALS(96, geom.app_area_rect.p1.x);
707 PCUT_ASSERT_INT_EQUALS(196, geom.app_area_rect.p1.y);
708
709 ui_wdecor_destroy(wdecor);
710 ui_resource_destroy(resource);
711
712 rc = gfx_context_delete(gc);
713 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
714}
715
716/** ui_wdecor_rect_from_app() correctly converts application to window rect */
717PCUT_TEST(rect_from_app)
718{
719 gfx_rect_t arect;
720 gfx_rect_t rect;
721
722 arect.p0.x = 14;
723 arect.p0.y = 46;
724 arect.p1.x = 96;
725 arect.p1.y = 196;
726
727 ui_wdecor_rect_from_app(ui_wds_none, &arect, &rect);
728
729 PCUT_ASSERT_INT_EQUALS(14, rect.p0.x);
730 PCUT_ASSERT_INT_EQUALS(46, rect.p0.y);
731 PCUT_ASSERT_INT_EQUALS(96, rect.p1.x);
732 PCUT_ASSERT_INT_EQUALS(196, rect.p1.y);
733
734 ui_wdecor_rect_from_app(ui_wds_frame, &arect, &rect);
735
736 PCUT_ASSERT_INT_EQUALS(10, rect.p0.x);
737 PCUT_ASSERT_INT_EQUALS(42, rect.p0.y);
738 PCUT_ASSERT_INT_EQUALS(100, rect.p1.x);
739 PCUT_ASSERT_INT_EQUALS(200, rect.p1.y);
740
741 ui_wdecor_rect_from_app(ui_wds_decorated, &arect, &rect);
742
743 PCUT_ASSERT_INT_EQUALS(10, rect.p0.x);
744 PCUT_ASSERT_INT_EQUALS(20, rect.p0.y);
745 PCUT_ASSERT_INT_EQUALS(100, rect.p1.x);
746 PCUT_ASSERT_INT_EQUALS(200, rect.p1.y);
747
748}
749
750/** Test ui_wdecor_get_rsztype() */
751PCUT_TEST(get_rsztype)
752{
753 ui_wdecor_t *wdecor;
754 gfx_rect_t rect;
755 ui_wdecor_rsztype_t rsztype;
756 gfx_coord2_t pos;
757 errno_t rc;
758
759 rc = ui_wdecor_create(NULL, "Hello", ui_wds_resizable, &wdecor);
760 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
761
762 rect.p0.x = 10;
763 rect.p0.y = 20;
764 rect.p1.x = 100;
765 rect.p1.y = 200;
766
767 ui_wdecor_set_rect(wdecor, &rect);
768
769 /* Outside of the window */
770 pos.x = 0;
771 pos.y = -1;
772 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
773 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
774
775 /* Middle of the window */
776 pos.x = 50;
777 pos.y = 100;
778 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
779 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
780
781 /* Top-left corner, but not on edge */
782 pos.x = 20;
783 pos.y = 30;
784 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
785 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
786
787 /* Top-left corner on top edge */
788 pos.x = 20;
789 pos.y = 20;
790 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
791 PCUT_ASSERT_EQUALS(ui_wr_top_left, rsztype);
792
793 /* Top-left corner on left edge */
794 pos.x = 10;
795 pos.y = 30;
796 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
797 PCUT_ASSERT_EQUALS(ui_wr_top_left, rsztype);
798
799 /* Top-right corner on top edge */
800 pos.x = 90;
801 pos.y = 20;
802 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
803 PCUT_ASSERT_EQUALS(ui_wr_top_right, rsztype);
804
805 /* Top-right corner on right edge */
806 pos.x = 99;
807 pos.y = 30;
808 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
809 PCUT_ASSERT_EQUALS(ui_wr_top_right, rsztype);
810
811 /* Top edge */
812 pos.x = 50;
813 pos.y = 20;
814 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
815 PCUT_ASSERT_EQUALS(ui_wr_top, rsztype);
816
817 /* Bottom edge */
818 pos.x = 50;
819 pos.y = 199;
820 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
821 PCUT_ASSERT_EQUALS(ui_wr_bottom, rsztype);
822
823 /* Left edge */
824 pos.x = 10;
825 pos.y = 100;
826 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
827 PCUT_ASSERT_EQUALS(ui_wr_left, rsztype);
828
829 /* Right edge */
830 pos.x = 99;
831 pos.y = 100;
832 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
833 PCUT_ASSERT_EQUALS(ui_wr_right, rsztype);
834
835 ui_wdecor_destroy(wdecor);
836
837 /* Non-resizable window */
838
839 rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
840 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
841
842 rect.p0.x = 10;
843 rect.p0.y = 20;
844 rect.p1.x = 100;
845 rect.p1.y = 200;
846
847 ui_wdecor_set_rect(wdecor, &rect);
848
849 pos.x = 10;
850 pos.y = 20;
851 rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
852 PCUT_ASSERT_EQUALS(ui_wr_none, rsztype);
853
854 ui_wdecor_destroy(wdecor);
855}
856
857/** Test ui_wdecor_cursor_from_rsztype() */
858PCUT_TEST(cursor_from_rsztype)
859{
860 PCUT_ASSERT_EQUALS(ui_curs_arrow,
861 ui_wdecor_cursor_from_rsztype(ui_wr_none));
862 PCUT_ASSERT_EQUALS(ui_curs_size_ud,
863 ui_wdecor_cursor_from_rsztype(ui_wr_top));
864 PCUT_ASSERT_EQUALS(ui_curs_size_ud,
865 ui_wdecor_cursor_from_rsztype(ui_wr_bottom));
866 PCUT_ASSERT_EQUALS(ui_curs_size_lr,
867 ui_wdecor_cursor_from_rsztype(ui_wr_left));
868 PCUT_ASSERT_EQUALS(ui_curs_size_lr,
869 ui_wdecor_cursor_from_rsztype(ui_wr_right));
870 PCUT_ASSERT_EQUALS(ui_curs_size_uldr,
871 ui_wdecor_cursor_from_rsztype(ui_wr_top_left));
872 PCUT_ASSERT_EQUALS(ui_curs_size_uldr,
873 ui_wdecor_cursor_from_rsztype(ui_wr_bottom_right));
874 PCUT_ASSERT_EQUALS(ui_curs_size_urdl,
875 ui_wdecor_cursor_from_rsztype(ui_wr_top_right));
876 PCUT_ASSERT_EQUALS(ui_curs_size_urdl,
877 ui_wdecor_cursor_from_rsztype(ui_wr_bottom_left));
878}
879
880/** Test ui_wdecor_frame_pos_event() */
881PCUT_TEST(frame_pos_event)
882{
883 ui_wdecor_t *wdecor;
884 gfx_rect_t rect;
885 test_cb_resp_t resp;
886 pos_event_t event;
887 errno_t rc;
888
889 rc = ui_wdecor_create(NULL, "Hello", ui_wds_resizable, &wdecor);
890 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
891
892 rect.p0.x = 10;
893 rect.p0.y = 20;
894 rect.p1.x = 100;
895 rect.p1.y = 200;
896
897 ui_wdecor_set_rect(wdecor, &rect);
898 ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
899
900 /* Release on window border should do nothing */
901 resp.resize = false;
902 event.type = POS_RELEASE;
903 event.hpos = 10;
904 event.vpos = 10;
905 ui_wdecor_frame_pos_event(wdecor, &event);
906 PCUT_ASSERT_FALSE(resp.resize);
907
908 /* Press in the middle of the window should do nothing */
909 resp.resize = false;
910 event.type = POS_PRESS;
911 event.hpos = 50;
912 event.vpos = 100;
913 ui_wdecor_frame_pos_event(wdecor, &event);
914 PCUT_ASSERT_FALSE(resp.resize);
915
916 /* Press on window border should cause resize to be called */
917 resp.resize = false;
918 event.type = POS_PRESS;
919 event.hpos = 10;
920 event.vpos = 20;
921 ui_wdecor_frame_pos_event(wdecor, &event);
922 PCUT_ASSERT_TRUE(resp.resize);
923
924 ui_wdecor_destroy(wdecor);
925}
926
927static errno_t testgc_set_clip_rect(void *arg, gfx_rect_t *rect)
928{
929 (void) arg;
930 (void) rect;
931 return EOK;
932}
933
934static errno_t testgc_set_color(void *arg, gfx_color_t *color)
935{
936 (void) arg;
937 (void) color;
938 return EOK;
939}
940
941static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
942{
943 (void) arg;
944 (void) rect;
945 return EOK;
946}
947
948static errno_t testgc_update(void *arg)
949{
950 (void) arg;
951 return EOK;
952}
953
954static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
955 gfx_bitmap_alloc_t *alloc, void **rbm)
956{
957 test_gc_t *tgc = (test_gc_t *) arg;
958 testgc_bitmap_t *tbm;
959
960 tbm = calloc(1, sizeof(testgc_bitmap_t));
961 if (tbm == NULL)
962 return ENOMEM;
963
964 if (alloc == NULL) {
965 tbm->alloc.pitch = (params->rect.p1.x - params->rect.p0.x) *
966 sizeof(uint32_t);
967 tbm->alloc.off0 = 0;
968 tbm->alloc.pixels = calloc(sizeof(uint32_t),
969 (params->rect.p1.x - params->rect.p0.x) *
970 (params->rect.p1.y - params->rect.p0.y));
971 tbm->myalloc = true;
972 if (tbm->alloc.pixels == NULL) {
973 free(tbm);
974 return ENOMEM;
975 }
976 } else {
977 tbm->alloc = *alloc;
978 }
979
980 tbm->tgc = tgc;
981 tgc->bm_created = true;
982 tgc->bm_params = *params;
983 tgc->bm_pixels = tbm->alloc.pixels;
984 *rbm = (void *)tbm;
985 return EOK;
986}
987
988static errno_t testgc_bitmap_destroy(void *bm)
989{
990 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
991 if (tbm->myalloc)
992 free(tbm->alloc.pixels);
993 tbm->tgc->bm_destroyed = true;
994 free(tbm);
995 return EOK;
996}
997
998static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
999 gfx_coord2_t *offs)
1000{
1001 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
1002 tbm->tgc->bm_rendered = true;
1003 tbm->tgc->bm_srect = *srect;
1004 tbm->tgc->bm_offs = *offs;
1005 return EOK;
1006}
1007
1008static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
1009{
1010 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
1011 *alloc = tbm->alloc;
1012 tbm->tgc->bm_got_alloc = true;
1013 return EOK;
1014}
1015
1016static void test_wdecor_maximize(ui_wdecor_t *wdecor, void *arg)
1017{
1018 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1019
1020 resp->maximize = true;
1021}
1022
1023static void test_wdecor_unmaximize(ui_wdecor_t *wdecor, void *arg)
1024{
1025 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1026
1027 resp->unmaximize = true;
1028}
1029
1030static void test_wdecor_close(ui_wdecor_t *wdecor, void *arg)
1031{
1032 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1033
1034 resp->close = true;
1035}
1036
1037static void test_wdecor_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos)
1038{
1039 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1040
1041 resp->move = true;
1042 resp->pos = *pos;
1043}
1044
1045static void test_wdecor_resize(ui_wdecor_t *wdecor, void *arg,
1046 ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos)
1047{
1048 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1049
1050 resp->resize = true;
1051 resp->rsztype = rsztype;
1052 resp->pos = *pos;
1053}
1054
1055static void test_wdecor_set_cursor(ui_wdecor_t *wdecor, void *arg,
1056 ui_stock_cursor_t cursor)
1057{
1058 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
1059
1060 resp->set_cursor = true;
1061 resp->cursor = cursor;
1062}
1063
1064PCUT_EXPORT(wdecor);
Note: See TracBrowser for help on using the repository browser.