source: mainline/uspace/app/uidemo/uidemo.c@ 6186f9f

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

Add menu separator entry

  • Property mode set to 100644
File size: 14.4 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/** @addtogroup uidemo
30 * @{
31 */
32/** @file User interface demo
33 */
34
35#include <gfx/bitmap.h>
36#include <gfx/coord.h>
37#include <io/pixelmap.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <str.h>
41#include <ui/entry.h>
42#include <ui/fixed.h>
43#include <ui/image.h>
44#include <ui/label.h>
45#include <ui/menubar.h>
46#include <ui/menuentry.h>
47#include <ui/menu.h>
48#include <ui/pbutton.h>
49#include <ui/resource.h>
50#include <ui/ui.h>
51#include <ui/window.h>
52#include "uidemo.h"
53
54static errno_t bitmap_moire(gfx_bitmap_t *, gfx_coord_t, gfx_coord_t);
55
56static void wnd_close(ui_window_t *, void *);
57
58static ui_window_cb_t window_cb = {
59 .close = wnd_close
60};
61
62static void pb_clicked(ui_pbutton_t *, void *);
63
64static ui_pbutton_cb_t pbutton_cb = {
65 .clicked = pb_clicked
66};
67
68static void checkbox_switched(ui_checkbox_t *, void *, bool);
69
70static ui_checkbox_cb_t checkbox_cb = {
71 .switched = checkbox_switched
72};
73
74static void rb_selected(ui_rbutton_group_t *, void *, void *);
75
76static ui_rbutton_group_cb_t rbutton_group_cb = {
77 .selected = rb_selected
78};
79
80static void slider_moved(ui_slider_t *, void *, gfx_coord_t);
81
82static ui_slider_cb_t slider_cb = {
83 .moved = slider_moved
84};
85
86static void uidemo_file_exit(ui_menu_entry_t *, void *);
87
88/** Window close button was clicked.
89 *
90 * @param window Window
91 * @param arg Argument (demo)
92 */
93static void wnd_close(ui_window_t *window, void *arg)
94{
95 ui_demo_t *demo = (ui_demo_t *) arg;
96
97 ui_quit(demo->ui);
98}
99
100/** Push button was clicked.
101 *
102 * @param pbutton Push button
103 * @param arg Argument (demo)
104 */
105static void pb_clicked(ui_pbutton_t *pbutton, void *arg)
106{
107 ui_demo_t *demo = (ui_demo_t *) arg;
108 errno_t rc;
109
110 if (pbutton == demo->pb1) {
111 rc = ui_entry_set_text(demo->entry, "OK pressed");
112 if (rc != EOK)
113 printf("Error changing entry text.\n");
114 (void) ui_entry_paint(demo->entry);
115 } else {
116 rc = ui_entry_set_text(demo->entry, "Cancel pressed");
117 if (rc != EOK)
118 printf("Error changing entry text.\n");
119 (void) ui_entry_paint(demo->entry);
120 }
121}
122
123/** Check box was switched.
124 *
125 * @param checkbox Check box
126 * @param arg Argument (demo)
127 */
128static void checkbox_switched(ui_checkbox_t *checkbox, void *arg, bool enable)
129{
130 ui_demo_t *demo = (ui_demo_t *) arg;
131 errno_t rc;
132
133 if (enable) {
134 rc = ui_entry_set_text(demo->entry, "Checked");
135 if (rc != EOK)
136 printf("Error changing entry text.\n");
137 (void) ui_entry_paint(demo->entry);
138 } else {
139 rc = ui_entry_set_text(demo->entry, "Unchecked");
140 if (rc != EOK)
141 printf("Error changing entry text.\n");
142 (void) ui_entry_paint(demo->entry);
143 }
144}
145
146/** Radio button was selected.
147 *
148 * @param rbgroup Radio button group
149 * @param garg Group argument (demo)
150 * @param barg Button argument
151 */
152static void rb_selected(ui_rbutton_group_t *rbgroup, void *garg, void *barg)
153{
154 ui_demo_t *demo = (ui_demo_t *) garg;
155 const char *text = (const char *) barg;
156 errno_t rc;
157
158 rc = ui_entry_set_text(demo->entry, text);
159 if (rc != EOK)
160 printf("Error changing entry text.\n");
161 (void) ui_entry_paint(demo->entry);
162}
163
164/** Slider was moved.
165 *
166 * @param slider Slider
167 * @param arg Argument (demo)
168 * @param pos Position
169 */
170static void slider_moved(ui_slider_t *slider, void *arg, gfx_coord_t pos)
171{
172 ui_demo_t *demo = (ui_demo_t *) arg;
173 char *str;
174 errno_t rc;
175 int rv;
176
177 rv = asprintf(&str, "Slider at %d of %d", (int) pos,
178 ui_slider_length(slider));
179 if (rv < 0) {
180 printf("Out of memory.\n");
181 return;
182 }
183
184 rc = ui_entry_set_text(demo->entry, str);
185 if (rc != EOK)
186 printf("Error changing entry text.\n");
187 (void) ui_entry_paint(demo->entry);
188
189 free(str);
190}
191
192/** File/exit menu entry selected.
193 *
194 * @param mentry Menu entry
195 * @param arg Argument (demo)
196 */
197static void uidemo_file_exit(ui_menu_entry_t *mentry, void *arg)
198{
199 ui_demo_t *demo = (ui_demo_t *) arg;
200
201 ui_quit(demo->ui);
202}
203
204/** Run UI demo on display server. */
205static errno_t ui_demo(const char *display_spec)
206{
207 ui_t *ui = NULL;
208 ui_wnd_params_t params;
209 ui_window_t *window = NULL;
210 ui_demo_t demo;
211 gfx_rect_t rect;
212 gfx_context_t *gc;
213 ui_resource_t *ui_res;
214 gfx_bitmap_params_t bparams;
215 gfx_bitmap_t *bitmap;
216 gfx_coord2_t off;
217 ui_menu_entry_t *mfoo;
218 ui_menu_entry_t *mbar;
219 ui_menu_entry_t *mfoobar;
220 ui_menu_entry_t *mexit;
221 ui_menu_entry_t *mabout;
222 errno_t rc;
223
224 rc = ui_create(display_spec, &ui);
225 if (rc != EOK) {
226 printf("Error creating UI on display %s.\n", display_spec);
227 return rc;
228 }
229
230 ui_wnd_params_init(&params);
231 params.caption = "UI Demo";
232 params.style |= ui_wds_resizable;
233 params.rect.p0.x = 0;
234 params.rect.p0.y = 0;
235 params.rect.p1.x = 220;
236 params.rect.p1.y = 350;
237
238 memset((void *) &demo, 0, sizeof(demo));
239 demo.ui = ui;
240
241 rc = ui_window_create(ui, &params, &window);
242 if (rc != EOK) {
243 printf("Error creating window.\n");
244 return rc;
245 }
246
247 ui_window_set_cb(window, &window_cb, (void *) &demo);
248 demo.window = window;
249
250 ui_res = ui_window_get_res(window);
251 gc = ui_window_get_gc(window);
252
253 rc = ui_fixed_create(&demo.fixed);
254 if (rc != EOK) {
255 printf("Error creating fixed layout.\n");
256 return rc;
257 }
258
259 rc = ui_menu_bar_create(ui_res, &demo.mbar);
260 if (rc != EOK) {
261 printf("Error creating menu bar.\n");
262 return rc;
263 }
264
265 rc = ui_menu_create(demo.mbar, "File", &demo.mfile);
266 if (rc != EOK) {
267 printf("Error creating menu.\n");
268 return rc;
269 }
270
271 rc = ui_menu_entry_create(demo.mfile, "Foo", "Ctrl-Alt-Del", &mfoo);
272 if (rc != EOK) {
273 printf("Error creating menu.\n");
274 return rc;
275 }
276
277 rc = ui_menu_entry_create(demo.mfile, "Bar", "", &mbar);
278 if (rc != EOK) {
279 printf("Error creating menu.\n");
280 return rc;
281 }
282
283 rc = ui_menu_entry_create(demo.mfile, "Foobar", "", &mfoobar);
284 if (rc != EOK) {
285 printf("Error creating menu.\n");
286 return rc;
287 }
288
289 rc = ui_menu_entry_sep_create(demo.mfile, &mexit);
290 if (rc != EOK) {
291 printf("Error creating menu.\n");
292 return rc;
293 }
294
295 rc = ui_menu_entry_create(demo.mfile, "Exit", "Alt-F4", &mexit);
296 if (rc != EOK) {
297 printf("Error creating menu.\n");
298 return rc;
299 }
300
301 ui_menu_entry_set_cb(mexit, uidemo_file_exit, (void *) &demo);
302
303 rc = ui_menu_create(demo.mbar, "Edit", &demo.medit);
304 if (rc != EOK) {
305 printf("Error creating menu.\n");
306 return rc;
307 }
308
309 rc = ui_menu_create(demo.mbar, "Preferences", &demo.mpreferences);
310 if (rc != EOK) {
311 printf("Error creating menu.\n");
312 return rc;
313 }
314
315 rc = ui_menu_create(demo.mbar, "Help", &demo.mhelp);
316 if (rc != EOK) {
317 printf("Error creating menu.\n");
318 return rc;
319 }
320
321 rc = ui_menu_entry_create(demo.mhelp, "About", "Ctrl-H, F1", &mabout);
322 if (rc != EOK) {
323 printf("Error creating menu.\n");
324 return rc;
325 }
326
327 rect.p0.x = 4;
328 rect.p0.y = 30;
329 rect.p1.x = 216;
330 rect.p1.y = 52;
331 ui_menu_bar_set_rect(demo.mbar, &rect);
332
333 rc = ui_fixed_add(demo.fixed, ui_menu_bar_ctl(demo.mbar));
334 if (rc != EOK) {
335 printf("Error adding control to layout.\n");
336 return rc;
337 }
338
339 rc = ui_entry_create(ui_res, "", &demo.entry);
340 if (rc != EOK) {
341 printf("Error creating entry.\n");
342 return rc;
343 }
344
345 rect.p0.x = 15;
346 rect.p0.y = 53;
347 rect.p1.x = 205;
348 rect.p1.y = 78;
349 ui_entry_set_rect(demo.entry, &rect);
350 ui_entry_set_halign(demo.entry, gfx_halign_center);
351
352 rc = ui_fixed_add(demo.fixed, ui_entry_ctl(demo.entry));
353 if (rc != EOK) {
354 printf("Error adding control to layout.\n");
355 return rc;
356 }
357
358 rc = ui_label_create(ui_res, "Text label", &demo.label);
359 if (rc != EOK) {
360 printf("Error creating label.\n");
361 return rc;
362 }
363
364 rect.p0.x = 60;
365 rect.p0.y = 88;
366 rect.p1.x = 160;
367 rect.p1.y = 101;
368 ui_label_set_rect(demo.label, &rect);
369 ui_label_set_halign(demo.label, gfx_halign_center);
370
371 rc = ui_fixed_add(demo.fixed, ui_label_ctl(demo.label));
372 if (rc != EOK) {
373 printf("Error adding control to layout.\n");
374 return rc;
375 }
376
377 rc = ui_pbutton_create(ui_res, "OK", &demo.pb1);
378 if (rc != EOK) {
379 printf("Error creating button.\n");
380 return rc;
381 }
382
383 ui_pbutton_set_cb(demo.pb1, &pbutton_cb, (void *) &demo);
384
385 rect.p0.x = 15;
386 rect.p0.y = 111;
387 rect.p1.x = 105;
388 rect.p1.y = 139;
389 ui_pbutton_set_rect(demo.pb1, &rect);
390
391 ui_pbutton_set_default(demo.pb1, true);
392
393 rc = ui_fixed_add(demo.fixed, ui_pbutton_ctl(demo.pb1));
394 if (rc != EOK) {
395 printf("Error adding control to layout.\n");
396 return rc;
397 }
398
399 rc = ui_pbutton_create(ui_res, "Cancel", &demo.pb2);
400 if (rc != EOK) {
401 printf("Error creating button.\n");
402 return rc;
403 }
404
405 ui_pbutton_set_cb(demo.pb2, &pbutton_cb, (void *) &demo);
406
407 rect.p0.x = 115;
408 rect.p0.y = 111;
409 rect.p1.x = 205;
410 rect.p1.y = 139;
411 ui_pbutton_set_rect(demo.pb2, &rect);
412
413 rc = ui_fixed_add(demo.fixed, ui_pbutton_ctl(demo.pb2));
414 if (rc != EOK) {
415 printf("Error adding control to layout.\n");
416 return rc;
417 }
418
419 gfx_bitmap_params_init(&bparams);
420 bparams.rect.p0.x = 0;
421 bparams.rect.p0.y = 0;
422 bparams.rect.p1.x = 188;
423 bparams.rect.p1.y = 24;
424
425 rc = gfx_bitmap_create(gc, &bparams, NULL, &bitmap);
426 if (rc != EOK)
427 return rc;
428
429 rc = bitmap_moire(bitmap, bparams.rect.p1.x, bparams.rect.p1.y);
430 if (rc != EOK)
431 return rc;
432
433 rc = ui_image_create(ui_res, bitmap, &params.rect, &demo.image);
434 if (rc != EOK) {
435 printf("Error creating label.\n");
436 return rc;
437 }
438
439 off.x = 15;
440 off.y = 155;
441 gfx_rect_translate(&off, &bparams.rect, &rect);
442
443 /* Adjust for frame width (2 x 1 pixel) */
444 rect.p1.x += 2;
445 rect.p1.y += 2;
446 ui_image_set_rect(demo.image, &rect);
447 ui_image_set_flags(demo.image, ui_imgf_frame);
448
449 rc = ui_fixed_add(demo.fixed, ui_image_ctl(demo.image));
450 if (rc != EOK) {
451 printf("Error adding control to layout.\n");
452 return rc;
453 }
454
455 rc = ui_checkbox_create(ui_res, "Check me", &demo.checkbox);
456 if (rc != EOK) {
457 printf("Error creating check box.\n");
458 return rc;
459 }
460
461 ui_checkbox_set_cb(demo.checkbox, &checkbox_cb, (void *) &demo);
462
463 rect.p0.x = 15;
464 rect.p0.y = 190;
465 rect.p1.x = 140;
466 rect.p1.y = 210;
467 ui_checkbox_set_rect(demo.checkbox, &rect);
468
469 rc = ui_fixed_add(demo.fixed, ui_checkbox_ctl(demo.checkbox));
470 if (rc != EOK) {
471 printf("Error adding control to layout.\n");
472 return rc;
473 }
474
475 rc = ui_rbutton_group_create(ui_res, &demo.rbgroup);
476 if (rc != EOK) {
477 printf("Error creating radio button group.\n");
478 return rc;
479 }
480
481 rc = ui_rbutton_create(demo.rbgroup, "Option 1", (void *) "First",
482 &demo.rb1);
483 if (rc != EOK) {
484 printf("Error creating radio button.\n");
485 return rc;
486 }
487
488 ui_rbutton_group_set_cb(demo.rbgroup, &rbutton_group_cb,
489 (void *) &demo);
490
491 rect.p0.x = 15;
492 rect.p0.y = 220;
493 rect.p1.x = 140;
494 rect.p1.y = 240;
495 ui_rbutton_set_rect(demo.rb1, &rect);
496
497 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb1));
498 if (rc != EOK) {
499 printf("Error adding control to layout.\n");
500 return rc;
501 }
502
503 rc = ui_rbutton_create(demo.rbgroup, "Option 2", (void *) "Second",
504 &demo.rb2);
505 if (rc != EOK) {
506 printf("Error creating radio button.\n");
507 return rc;
508 }
509
510 rect.p0.x = 15;
511 rect.p0.y = 250;
512 rect.p1.x = 140;
513 rect.p1.y = 270;
514 ui_rbutton_set_rect(demo.rb2, &rect);
515
516 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb2));
517 if (rc != EOK) {
518 printf("Error adding control to layout.\n");
519 return rc;
520 }
521
522 rc = ui_rbutton_create(demo.rbgroup, "Option 3", (void *) "Third",
523 &demo.rb3);
524 if (rc != EOK) {
525 printf("Error creating radio button.\n");
526 return rc;
527 }
528
529 rect.p0.x = 15;
530 rect.p0.y = 280;
531 rect.p1.x = 140;
532 rect.p1.y = 300;
533 ui_rbutton_set_rect(demo.rb3, &rect);
534
535 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb3));
536 if (rc != EOK) {
537 printf("Error adding control to layout.\n");
538 return rc;
539 }
540
541 rc = ui_slider_create(ui_res, "Slide!", &demo.slider);
542 if (rc != EOK) {
543 printf("Error creating button.\n");
544 return rc;
545 }
546
547 ui_slider_set_cb(demo.slider, &slider_cb, (void *) &demo);
548
549 rect.p0.x = 15;
550 rect.p0.y = 310;
551 rect.p1.x = 130;
552 rect.p1.y = 330;
553 ui_slider_set_rect(demo.slider, &rect);
554
555 rc = ui_fixed_add(demo.fixed, ui_slider_ctl(demo.slider));
556 if (rc != EOK) {
557 printf("Error adding control to layout.\n");
558 return rc;
559 }
560
561 ui_window_add(window, ui_fixed_ctl(demo.fixed));
562
563 rc = ui_window_paint(window);
564 if (rc != EOK) {
565 printf("Error painting window.\n");
566 return rc;
567 }
568
569 ui_run(ui);
570
571 ui_window_destroy(window);
572 ui_destroy(ui);
573
574 return EOK;
575}
576
577/** Fill bitmap with moire pattern.
578 *
579 * @param bitmap Bitmap
580 * @param w Bitmap width
581 * @param h Bitmap height
582 * @return EOK on success or an error code
583 */
584static errno_t bitmap_moire(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
585{
586 int i, j;
587 int k;
588 pixelmap_t pixelmap;
589 gfx_bitmap_alloc_t alloc;
590 errno_t rc;
591
592 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
593 if (rc != EOK)
594 return rc;
595
596 /* In absence of anything else, use pixelmap */
597 pixelmap.width = w;
598 pixelmap.height = h;
599 pixelmap.data = alloc.pixels;
600
601 for (i = 0; i < w; i++) {
602 for (j = 0; j < h; j++) {
603 k = i * i + j * j;
604 pixelmap_put_pixel(&pixelmap, i, j,
605 PIXEL(255, k, k, 255 - k));
606 }
607 }
608
609 return EOK;
610}
611
612static void print_syntax(void)
613{
614 printf("Syntax: uidemo [-d <display-spec>]\n");
615}
616
617int main(int argc, char *argv[])
618{
619 const char *display_spec = UI_DISPLAY_DEFAULT;
620 errno_t rc;
621 int i;
622
623 i = 1;
624 while (i < argc && argv[i][0] == '-') {
625 if (str_cmp(argv[i], "-d") == 0) {
626 ++i;
627 if (i >= argc) {
628 printf("Argument missing.\n");
629 print_syntax();
630 return 1;
631 }
632
633 display_spec = argv[i++];
634 } else {
635 printf("Invalid option '%s'.\n", argv[i]);
636 print_syntax();
637 return 1;
638 }
639 }
640
641 if (i < argc) {
642 print_syntax();
643 return 1;
644 }
645
646 rc = ui_demo(display_spec);
647 if (rc != EOK)
648 return 1;
649
650 return 0;
651}
652
653/** @}
654 */
Note: See TracBrowser for help on using the repository browser.