source: mainline/uspace/app/uidemo/uidemo.c@ b8b64a8

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

Add column with keyboard shortcuts to menu

  • Property mode set to 100644
File size: 14.3 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_create(demo.mfile, "Exit", "Alt-F4", &mexit);
290 if (rc != EOK) {
291 printf("Error creating menu.\n");
292 return rc;
293 }
294
295 ui_menu_entry_set_cb(mexit, uidemo_file_exit, (void *) &demo);
296
297 rc = ui_menu_create(demo.mbar, "Edit", &demo.medit);
298 if (rc != EOK) {
299 printf("Error creating menu.\n");
300 return rc;
301 }
302
303 rc = ui_menu_create(demo.mbar, "Preferences", &demo.mpreferences);
304 if (rc != EOK) {
305 printf("Error creating menu.\n");
306 return rc;
307 }
308
309 rc = ui_menu_create(demo.mbar, "Help", &demo.mhelp);
310 if (rc != EOK) {
311 printf("Error creating menu.\n");
312 return rc;
313 }
314
315 rc = ui_menu_entry_create(demo.mhelp, "About", "Ctrl-H, F1", &mabout);
316 if (rc != EOK) {
317 printf("Error creating menu.\n");
318 return rc;
319 }
320
321 rect.p0.x = 4;
322 rect.p0.y = 30;
323 rect.p1.x = 216;
324 rect.p1.y = 52;
325 ui_menu_bar_set_rect(demo.mbar, &rect);
326
327 rc = ui_fixed_add(demo.fixed, ui_menu_bar_ctl(demo.mbar));
328 if (rc != EOK) {
329 printf("Error adding control to layout.\n");
330 return rc;
331 }
332
333 rc = ui_entry_create(ui_res, "", &demo.entry);
334 if (rc != EOK) {
335 printf("Error creating entry.\n");
336 return rc;
337 }
338
339 rect.p0.x = 15;
340 rect.p0.y = 53;
341 rect.p1.x = 205;
342 rect.p1.y = 78;
343 ui_entry_set_rect(demo.entry, &rect);
344 ui_entry_set_halign(demo.entry, gfx_halign_center);
345
346 rc = ui_fixed_add(demo.fixed, ui_entry_ctl(demo.entry));
347 if (rc != EOK) {
348 printf("Error adding control to layout.\n");
349 return rc;
350 }
351
352 rc = ui_label_create(ui_res, "Text label", &demo.label);
353 if (rc != EOK) {
354 printf("Error creating label.\n");
355 return rc;
356 }
357
358 rect.p0.x = 60;
359 rect.p0.y = 88;
360 rect.p1.x = 160;
361 rect.p1.y = 101;
362 ui_label_set_rect(demo.label, &rect);
363 ui_label_set_halign(demo.label, gfx_halign_center);
364
365 rc = ui_fixed_add(demo.fixed, ui_label_ctl(demo.label));
366 if (rc != EOK) {
367 printf("Error adding control to layout.\n");
368 return rc;
369 }
370
371 rc = ui_pbutton_create(ui_res, "OK", &demo.pb1);
372 if (rc != EOK) {
373 printf("Error creating button.\n");
374 return rc;
375 }
376
377 ui_pbutton_set_cb(demo.pb1, &pbutton_cb, (void *) &demo);
378
379 rect.p0.x = 15;
380 rect.p0.y = 111;
381 rect.p1.x = 105;
382 rect.p1.y = 139;
383 ui_pbutton_set_rect(demo.pb1, &rect);
384
385 ui_pbutton_set_default(demo.pb1, true);
386
387 rc = ui_fixed_add(demo.fixed, ui_pbutton_ctl(demo.pb1));
388 if (rc != EOK) {
389 printf("Error adding control to layout.\n");
390 return rc;
391 }
392
393 rc = ui_pbutton_create(ui_res, "Cancel", &demo.pb2);
394 if (rc != EOK) {
395 printf("Error creating button.\n");
396 return rc;
397 }
398
399 ui_pbutton_set_cb(demo.pb2, &pbutton_cb, (void *) &demo);
400
401 rect.p0.x = 115;
402 rect.p0.y = 111;
403 rect.p1.x = 205;
404 rect.p1.y = 139;
405 ui_pbutton_set_rect(demo.pb2, &rect);
406
407 rc = ui_fixed_add(demo.fixed, ui_pbutton_ctl(demo.pb2));
408 if (rc != EOK) {
409 printf("Error adding control to layout.\n");
410 return rc;
411 }
412
413 gfx_bitmap_params_init(&bparams);
414 bparams.rect.p0.x = 0;
415 bparams.rect.p0.y = 0;
416 bparams.rect.p1.x = 188;
417 bparams.rect.p1.y = 24;
418
419 rc = gfx_bitmap_create(gc, &bparams, NULL, &bitmap);
420 if (rc != EOK)
421 return rc;
422
423 rc = bitmap_moire(bitmap, bparams.rect.p1.x, bparams.rect.p1.y);
424 if (rc != EOK)
425 return rc;
426
427 rc = ui_image_create(ui_res, bitmap, &params.rect, &demo.image);
428 if (rc != EOK) {
429 printf("Error creating label.\n");
430 return rc;
431 }
432
433 off.x = 15;
434 off.y = 155;
435 gfx_rect_translate(&off, &bparams.rect, &rect);
436
437 /* Adjust for frame width (2 x 1 pixel) */
438 rect.p1.x += 2;
439 rect.p1.y += 2;
440 ui_image_set_rect(demo.image, &rect);
441 ui_image_set_flags(demo.image, ui_imgf_frame);
442
443 rc = ui_fixed_add(demo.fixed, ui_image_ctl(demo.image));
444 if (rc != EOK) {
445 printf("Error adding control to layout.\n");
446 return rc;
447 }
448
449 rc = ui_checkbox_create(ui_res, "Check me", &demo.checkbox);
450 if (rc != EOK) {
451 printf("Error creating check box.\n");
452 return rc;
453 }
454
455 ui_checkbox_set_cb(demo.checkbox, &checkbox_cb, (void *) &demo);
456
457 rect.p0.x = 15;
458 rect.p0.y = 190;
459 rect.p1.x = 140;
460 rect.p1.y = 210;
461 ui_checkbox_set_rect(demo.checkbox, &rect);
462
463 rc = ui_fixed_add(demo.fixed, ui_checkbox_ctl(demo.checkbox));
464 if (rc != EOK) {
465 printf("Error adding control to layout.\n");
466 return rc;
467 }
468
469 rc = ui_rbutton_group_create(ui_res, &demo.rbgroup);
470 if (rc != EOK) {
471 printf("Error creating radio button group.\n");
472 return rc;
473 }
474
475 rc = ui_rbutton_create(demo.rbgroup, "Option 1", (void *) "First",
476 &demo.rb1);
477 if (rc != EOK) {
478 printf("Error creating radio button.\n");
479 return rc;
480 }
481
482 ui_rbutton_group_set_cb(demo.rbgroup, &rbutton_group_cb,
483 (void *) &demo);
484
485 rect.p0.x = 15;
486 rect.p0.y = 220;
487 rect.p1.x = 140;
488 rect.p1.y = 240;
489 ui_rbutton_set_rect(demo.rb1, &rect);
490
491 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb1));
492 if (rc != EOK) {
493 printf("Error adding control to layout.\n");
494 return rc;
495 }
496
497 rc = ui_rbutton_create(demo.rbgroup, "Option 2", (void *) "Second",
498 &demo.rb2);
499 if (rc != EOK) {
500 printf("Error creating radio button.\n");
501 return rc;
502 }
503
504 rect.p0.x = 15;
505 rect.p0.y = 250;
506 rect.p1.x = 140;
507 rect.p1.y = 270;
508 ui_rbutton_set_rect(demo.rb2, &rect);
509
510 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb2));
511 if (rc != EOK) {
512 printf("Error adding control to layout.\n");
513 return rc;
514 }
515
516 rc = ui_rbutton_create(demo.rbgroup, "Option 3", (void *) "Third",
517 &demo.rb3);
518 if (rc != EOK) {
519 printf("Error creating radio button.\n");
520 return rc;
521 }
522
523 rect.p0.x = 15;
524 rect.p0.y = 280;
525 rect.p1.x = 140;
526 rect.p1.y = 300;
527 ui_rbutton_set_rect(demo.rb3, &rect);
528
529 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb3));
530 if (rc != EOK) {
531 printf("Error adding control to layout.\n");
532 return rc;
533 }
534
535 rc = ui_slider_create(ui_res, "Slide!", &demo.slider);
536 if (rc != EOK) {
537 printf("Error creating button.\n");
538 return rc;
539 }
540
541 ui_slider_set_cb(demo.slider, &slider_cb, (void *) &demo);
542
543 rect.p0.x = 15;
544 rect.p0.y = 310;
545 rect.p1.x = 130;
546 rect.p1.y = 330;
547 ui_slider_set_rect(demo.slider, &rect);
548
549 rc = ui_fixed_add(demo.fixed, ui_slider_ctl(demo.slider));
550 if (rc != EOK) {
551 printf("Error adding control to layout.\n");
552 return rc;
553 }
554
555 ui_window_add(window, ui_fixed_ctl(demo.fixed));
556
557 rc = ui_window_paint(window);
558 if (rc != EOK) {
559 printf("Error painting window.\n");
560 return rc;
561 }
562
563 ui_run(ui);
564
565 ui_window_destroy(window);
566 ui_destroy(ui);
567
568 return EOK;
569}
570
571/** Fill bitmap with moire pattern.
572 *
573 * @param bitmap Bitmap
574 * @param w Bitmap width
575 * @param h Bitmap height
576 * @return EOK on success or an error code
577 */
578static errno_t bitmap_moire(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
579{
580 int i, j;
581 int k;
582 pixelmap_t pixelmap;
583 gfx_bitmap_alloc_t alloc;
584 errno_t rc;
585
586 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
587 if (rc != EOK)
588 return rc;
589
590 /* In absence of anything else, use pixelmap */
591 pixelmap.width = w;
592 pixelmap.height = h;
593 pixelmap.data = alloc.pixels;
594
595 for (i = 0; i < w; i++) {
596 for (j = 0; j < h; j++) {
597 k = i * i + j * j;
598 pixelmap_put_pixel(&pixelmap, i, j,
599 PIXEL(255, k, k, 255 - k));
600 }
601 }
602
603 return EOK;
604}
605
606static void print_syntax(void)
607{
608 printf("Syntax: uidemo [-d <display-spec>]\n");
609}
610
611int main(int argc, char *argv[])
612{
613 const char *display_spec = UI_DISPLAY_DEFAULT;
614 errno_t rc;
615 int i;
616
617 i = 1;
618 while (i < argc && argv[i][0] == '-') {
619 if (str_cmp(argv[i], "-d") == 0) {
620 ++i;
621 if (i >= argc) {
622 printf("Argument missing.\n");
623 print_syntax();
624 return 1;
625 }
626
627 display_spec = argv[i++];
628 } else {
629 printf("Invalid option '%s'.\n", argv[i]);
630 print_syntax();
631 return 1;
632 }
633 }
634
635 if (i < argc) {
636 print_syntax();
637 return 1;
638 }
639
640 rc = ui_demo(display_spec);
641 if (rc != EOK)
642 return 1;
643
644 return 0;
645}
646
647/** @}
648 */
Note: See TracBrowser for help on using the repository browser.