source: mainline/uspace/app/uidemo/uidemo.c@ 1eaead4

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

Tab set control

This allows to expand the space available in a dialog window
using stacking, with individual tabs that can be activated
by clicking the handle.

  • Property mode set to 100644
File size: 27.8 KB
Line 
1/*
2 * Copyright (c) 2023 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/filedialog.h>
43#include <ui/fixed.h>
44#include <ui/image.h>
45#include <ui/label.h>
46#include <ui/menubar.h>
47#include <ui/menuentry.h>
48#include <ui/menu.h>
49#include <ui/msgdialog.h>
50#include <ui/pbutton.h>
51#include <ui/promptdialog.h>
52#include <ui/resource.h>
53#include <ui/tab.h>
54#include <ui/tabset.h>
55#include <ui/ui.h>
56#include <ui/window.h>
57#include "uidemo.h"
58
59static errno_t bitmap_moire(gfx_bitmap_t *, gfx_coord_t, gfx_coord_t);
60
61static void wnd_close(ui_window_t *, void *);
62
63static ui_window_cb_t window_cb = {
64 .close = wnd_close
65};
66
67static void pb_clicked(ui_pbutton_t *, void *);
68
69static ui_pbutton_cb_t pbutton_cb = {
70 .clicked = pb_clicked
71};
72
73static void checkbox_switched(ui_checkbox_t *, void *, bool);
74
75static ui_checkbox_cb_t checkbox_cb = {
76 .switched = checkbox_switched
77};
78
79static void rb_selected(ui_rbutton_group_t *, void *, void *);
80
81static ui_rbutton_group_cb_t rbutton_group_cb = {
82 .selected = rb_selected
83};
84
85static void slider_moved(ui_slider_t *, void *, gfx_coord_t);
86
87static ui_slider_cb_t slider_cb = {
88 .moved = slider_moved
89};
90
91static void scrollbar_up(ui_scrollbar_t *, void *);
92static void scrollbar_down(ui_scrollbar_t *, void *);
93static void scrollbar_page_up(ui_scrollbar_t *, void *);
94static void scrollbar_page_down(ui_scrollbar_t *, void *);
95static void scrollbar_moved(ui_scrollbar_t *, void *, gfx_coord_t);
96
97static ui_scrollbar_cb_t scrollbar_cb = {
98 .up = scrollbar_up,
99 .down = scrollbar_down,
100 .page_up = scrollbar_page_up,
101 .page_down = scrollbar_page_down,
102 .moved = scrollbar_moved
103};
104
105static void uidemo_file_load(ui_menu_entry_t *, void *);
106static void uidemo_file_message(ui_menu_entry_t *, void *);
107static void uidemo_file_exit(ui_menu_entry_t *, void *);
108static void uidemo_edit_modify(ui_menu_entry_t *, void *);
109
110static void file_dialog_bok(ui_file_dialog_t *, void *, const char *);
111static void file_dialog_bcancel(ui_file_dialog_t *, void *);
112static void file_dialog_close(ui_file_dialog_t *, void *);
113
114static ui_file_dialog_cb_t file_dialog_cb = {
115 .bok = file_dialog_bok,
116 .bcancel = file_dialog_bcancel,
117 .close = file_dialog_close
118};
119
120static void prompt_dialog_bok(ui_prompt_dialog_t *, void *, const char *);
121static void prompt_dialog_bcancel(ui_prompt_dialog_t *, void *);
122static void prompt_dialog_close(ui_prompt_dialog_t *, void *);
123
124static ui_prompt_dialog_cb_t prompt_dialog_cb = {
125 .bok = prompt_dialog_bok,
126 .bcancel = prompt_dialog_bcancel,
127 .close = prompt_dialog_close
128};
129
130static void msg_dialog_button(ui_msg_dialog_t *, void *, unsigned);
131static void msg_dialog_close(ui_msg_dialog_t *, void *);
132
133static ui_msg_dialog_cb_t msg_dialog_cb = {
134 .button = msg_dialog_button,
135 .close = msg_dialog_close
136};
137
138/** Horizontal alignment selected by each radio button */
139static const gfx_halign_t uidemo_halign[3] = {
140 gfx_halign_left,
141 gfx_halign_center,
142 gfx_halign_right
143};
144
145/** Window close button was clicked.
146 *
147 * @param window Window
148 * @param arg Argument (demo)
149 */
150static void wnd_close(ui_window_t *window, void *arg)
151{
152 ui_demo_t *demo = (ui_demo_t *) arg;
153
154 ui_quit(demo->ui);
155}
156
157/** Push button was clicked.
158 *
159 * @param pbutton Push button
160 * @param arg Argument (demo)
161 */
162static void pb_clicked(ui_pbutton_t *pbutton, void *arg)
163{
164 ui_demo_t *demo = (ui_demo_t *) arg;
165 errno_t rc;
166
167 if (pbutton == demo->pb1) {
168 rc = ui_entry_set_text(demo->entry, "OK pressed");
169 if (rc != EOK)
170 printf("Error changing entry text.\n");
171 } else {
172 rc = ui_entry_set_text(demo->entry, "Cancel pressed");
173 if (rc != EOK)
174 printf("Error changing entry text.\n");
175 }
176}
177
178/** Check box was switched.
179 *
180 * @param checkbox Check box
181 * @param arg Argument (demo)
182 */
183static void checkbox_switched(ui_checkbox_t *checkbox, void *arg, bool enable)
184{
185 ui_demo_t *demo = (ui_demo_t *) arg;
186
187 ui_entry_set_read_only(demo->entry, enable);
188}
189
190/** Radio button was selected.
191 *
192 * @param rbgroup Radio button group
193 * @param garg Group argument (demo)
194 * @param barg Button argument
195 */
196static void rb_selected(ui_rbutton_group_t *rbgroup, void *garg, void *barg)
197{
198 ui_demo_t *demo = (ui_demo_t *) garg;
199 gfx_halign_t halign = *(gfx_halign_t *) barg;
200
201 ui_entry_set_halign(demo->entry, halign);
202 (void) ui_entry_paint(demo->entry);
203}
204
205/** Slider was moved.
206 *
207 * @param slider Slider
208 * @param arg Argument (demo)
209 * @param pos Position
210 */
211static void slider_moved(ui_slider_t *slider, void *arg, gfx_coord_t pos)
212{
213 ui_demo_t *demo = (ui_demo_t *) arg;
214 char *str;
215 errno_t rc;
216 int rv;
217
218 rv = asprintf(&str, "Slider at %d of %d", (int) pos,
219 ui_slider_length(slider));
220 if (rv < 0) {
221 printf("Out of memory.\n");
222 return;
223 }
224
225 rc = ui_entry_set_text(demo->entry, str);
226 if (rc != EOK)
227 printf("Error changing entry text.\n");
228 (void) ui_entry_paint(demo->entry);
229
230 free(str);
231}
232
233/** Scrollbar up button pressed.
234 *
235 * @param scrollbar Scrollbar
236 * @param arg Argument (demo)
237 */
238static void scrollbar_up(ui_scrollbar_t *scrollbar, void *arg)
239{
240 gfx_coord_t pos;
241
242 pos = ui_scrollbar_get_pos(scrollbar);
243 ui_scrollbar_set_pos(scrollbar, pos - 1);
244
245 pos = ui_scrollbar_get_pos(scrollbar);
246 scrollbar_moved(scrollbar, arg, pos);
247}
248
249/** Scrollbar down button pressed.
250 *
251 * @param scrollbar Scrollbar
252 * @param arg Argument (demo)
253 */
254static void scrollbar_down(ui_scrollbar_t *scrollbar, void *arg)
255{
256 gfx_coord_t pos;
257
258 pos = ui_scrollbar_get_pos(scrollbar);
259 ui_scrollbar_set_pos(scrollbar, pos + 1);
260
261 pos = ui_scrollbar_get_pos(scrollbar);
262 scrollbar_moved(scrollbar, arg, pos);
263}
264
265/** Scrollbar page up event.
266 *
267 * @param scrollbar Scrollbar
268 * @param arg Argument (demo)
269 */
270static void scrollbar_page_up(ui_scrollbar_t *scrollbar, void *arg)
271{
272 gfx_coord_t pos;
273
274 pos = ui_scrollbar_get_pos(scrollbar);
275 ui_scrollbar_set_pos(scrollbar, pos -
276 ui_scrollbar_through_length(scrollbar) / 4);
277
278 pos = ui_scrollbar_get_pos(scrollbar);
279 scrollbar_moved(scrollbar, arg, pos);
280}
281
282/** Scrollbar page down event.
283 *
284 * @param scrollbar Scrollbar
285 * @param arg Argument (demo)
286 */
287static void scrollbar_page_down(ui_scrollbar_t *scrollbar, void *arg)
288{
289 gfx_coord_t pos;
290
291 pos = ui_scrollbar_get_pos(scrollbar);
292 ui_scrollbar_set_pos(scrollbar, pos +
293 ui_scrollbar_through_length(scrollbar) / 4);
294
295 pos = ui_scrollbar_get_pos(scrollbar);
296 scrollbar_moved(scrollbar, arg, pos);
297}
298
299/** Scrollbar was moved.
300 *
301 * @param scrollbar Scrollbar
302 * @param arg Argument (demo)
303 * @param pos Position
304 */
305static void scrollbar_moved(ui_scrollbar_t *scrollbar, void *arg,
306 gfx_coord_t pos)
307{
308 ui_demo_t *demo = (ui_demo_t *) arg;
309 char *str;
310 errno_t rc;
311 int rv;
312
313 rv = asprintf(&str, "Scrollbar: %d of %d", (int) pos,
314 ui_scrollbar_move_length(scrollbar));
315 if (rv < 0) {
316 printf("Out of memory.\n");
317 return;
318 }
319
320 rc = ui_entry_set_text(demo->entry, str);
321 if (rc != EOK)
322 printf("Error changing entry text.\n");
323 (void) ui_entry_paint(demo->entry);
324
325 free(str);
326}
327
328/** Display a message window.
329 *
330 * @param demo UI demo
331 * @param caption Window caption
332 * @param text Message text
333 */
334static void uidemo_show_message(ui_demo_t *demo, const char *caption,
335 const char *text)
336{
337 ui_msg_dialog_params_t mdparams;
338 ui_msg_dialog_t *dialog;
339 errno_t rc;
340
341 ui_msg_dialog_params_init(&mdparams);
342 mdparams.caption = caption;
343 mdparams.text = text;
344
345 rc = ui_msg_dialog_create(demo->ui, &mdparams, &dialog);
346 if (rc != EOK) {
347 printf("Error creating message dialog.\n");
348 return;
349 }
350
351 ui_msg_dialog_set_cb(dialog, &msg_dialog_cb, &demo);
352}
353
354/** File / Load menu entry selected.
355 *
356 * @param mentry Menu entry
357 * @param arg Argument (demo)
358 */
359static void uidemo_file_load(ui_menu_entry_t *mentry, void *arg)
360{
361 ui_demo_t *demo = (ui_demo_t *) arg;
362 ui_file_dialog_params_t fdparams;
363 ui_file_dialog_t *dialog;
364 errno_t rc;
365
366 ui_file_dialog_params_init(&fdparams);
367 fdparams.caption = "Load File";
368
369 rc = ui_file_dialog_create(demo->ui, &fdparams, &dialog);
370 if (rc != EOK) {
371 printf("Error creating message dialog.\n");
372 return;
373 }
374
375 ui_file_dialog_set_cb(dialog, &file_dialog_cb, demo);
376}
377
378/** File / Message menu entry selected.
379 *
380 * @param mentry Menu entry
381 * @param arg Argument (demo)
382 */
383static void uidemo_file_message(ui_menu_entry_t *mentry, void *arg)
384{
385 ui_demo_t *demo = (ui_demo_t *) arg;
386 ui_msg_dialog_params_t mdparams;
387 ui_msg_dialog_t *dialog;
388 errno_t rc;
389
390 ui_msg_dialog_params_init(&mdparams);
391 mdparams.caption = "Message For You";
392 mdparams.text = "Hello, world!";
393
394 rc = ui_msg_dialog_create(demo->ui, &mdparams, &dialog);
395 if (rc != EOK) {
396 printf("Error creating message dialog.\n");
397 return;
398 }
399
400 ui_msg_dialog_set_cb(dialog, &msg_dialog_cb, &demo);
401}
402
403/** File / Exit menu entry selected.
404 *
405 * @param mentry Menu entry
406 * @param arg Argument (demo)
407 */
408static void uidemo_file_exit(ui_menu_entry_t *mentry, void *arg)
409{
410 ui_demo_t *demo = (ui_demo_t *) arg;
411
412 ui_quit(demo->ui);
413}
414
415/** Edit / Modify menu entry selected.
416 *
417 * @param mentry Menu entry
418 * @param arg Argument (demo)
419 */
420static void uidemo_edit_modify(ui_menu_entry_t *mentry, void *arg)
421{
422 ui_demo_t *demo = (ui_demo_t *) arg;
423 ui_prompt_dialog_params_t pdparams;
424 ui_prompt_dialog_t *dialog;
425 errno_t rc;
426
427 ui_prompt_dialog_params_init(&pdparams);
428 pdparams.caption = "Modify Entry Text";
429 pdparams.prompt = "Enter New Text";
430
431 rc = ui_prompt_dialog_create(demo->ui, &pdparams, &dialog);
432 if (rc != EOK) {
433 printf("Error creating message dialog.\n");
434 return;
435 }
436
437 ui_prompt_dialog_set_cb(dialog, &prompt_dialog_cb, demo);
438}
439
440/** File dialog OK button press.
441 *
442 * @param dialog File dialog
443 * @param arg Argument (ui_demo_t *)
444 * @param fname File name
445 */
446static void file_dialog_bok(ui_file_dialog_t *dialog, void *arg,
447 const char *fname)
448{
449 ui_demo_t *demo = (ui_demo_t *) arg;
450 char buf[128];
451 char *p;
452 FILE *f;
453
454 ui_file_dialog_destroy(dialog);
455
456 f = fopen(fname, "rt");
457 if (f == NULL) {
458 uidemo_show_message(demo, "Error", "Error opening file.");
459 return;
460 }
461
462 p = fgets(buf, sizeof(buf), f);
463 if (p == NULL) {
464 uidemo_show_message(demo, "Error", "Error reading file.");
465 fclose(f);
466 return;
467 }
468
469 /* Cut string off at the first non-printable character */
470 p = buf;
471 while (*p != '\0') {
472 if (*p < ' ') {
473 *p = '\0';
474 break;
475 }
476 ++p;
477 }
478
479 ui_entry_set_text(demo->entry, buf);
480 fclose(f);
481}
482
483/** File dialog cancel button press.
484 *
485 * @param dialog File dialog
486 * @param arg Argument (ui_demo_t *)
487 */
488static void file_dialog_bcancel(ui_file_dialog_t *dialog, void *arg)
489{
490 ui_demo_t *demo = (ui_demo_t *) arg;
491
492 (void) demo;
493 ui_file_dialog_destroy(dialog);
494}
495
496/** File dialog close request.
497 *
498 * @param dialog File dialog
499 * @param arg Argument (ui_demo_t *)
500 */
501static void file_dialog_close(ui_file_dialog_t *dialog, void *arg)
502{
503 ui_demo_t *demo = (ui_demo_t *) arg;
504
505 (void) demo;
506 ui_file_dialog_destroy(dialog);
507}
508
509/** Prompt dialog OK button press.
510 *
511 * @param dialog Prompt dialog
512 * @param arg Argument (ui_demo_t *)
513 * @param text Submitted text
514 */
515static void prompt_dialog_bok(ui_prompt_dialog_t *dialog, void *arg,
516 const char *text)
517{
518 ui_demo_t *demo = (ui_demo_t *) arg;
519
520 ui_prompt_dialog_destroy(dialog);
521 ui_entry_set_text(demo->entry, text);
522}
523
524/** Prompt dialog cancel button press.
525 *
526 * @param dialog File dialog
527 * @param arg Argument (ui_demo_t *)
528 */
529static void prompt_dialog_bcancel(ui_prompt_dialog_t *dialog, void *arg)
530{
531 ui_demo_t *demo = (ui_demo_t *) arg;
532
533 (void) demo;
534 ui_prompt_dialog_destroy(dialog);
535}
536
537/** Prompt dialog close request.
538 *
539 * @param dialog File dialog
540 * @param arg Argument (ui_demo_t *)
541 */
542static void prompt_dialog_close(ui_prompt_dialog_t *dialog, void *arg)
543{
544 ui_demo_t *demo = (ui_demo_t *) arg;
545
546 (void) demo;
547 ui_prompt_dialog_destroy(dialog);
548}
549
550/** Message dialog button press.
551 *
552 * @param dialog Message dialog
553 * @param arg Argument (ui_demo_t *)
554 * @param bnum Button number
555 */
556static void msg_dialog_button(ui_msg_dialog_t *dialog, void *arg,
557 unsigned bnum)
558{
559 ui_demo_t *demo = (ui_demo_t *) arg;
560
561 (void) demo;
562 ui_msg_dialog_destroy(dialog);
563}
564
565/** Message dialog close request.
566 *
567 * @param dialog Message dialog
568 * @param arg Argument (ui_demo_t *)
569 */
570static void msg_dialog_close(ui_msg_dialog_t *dialog, void *arg)
571{
572 ui_demo_t *demo = (ui_demo_t *) arg;
573
574 (void) demo;
575 ui_msg_dialog_destroy(dialog);
576}
577
578/** Run UI demo on display server. */
579static errno_t ui_demo(const char *display_spec)
580{
581 ui_t *ui = NULL;
582 ui_wnd_params_t params;
583 ui_window_t *window = NULL;
584 ui_demo_t demo;
585 gfx_rect_t rect;
586 gfx_context_t *gc;
587 ui_resource_t *ui_res;
588 gfx_bitmap_params_t bparams;
589 gfx_bitmap_t *bitmap;
590 gfx_coord2_t off;
591 ui_menu_entry_t *mmsg;
592 ui_menu_entry_t *mload;
593 ui_menu_entry_t *mfoo;
594 ui_menu_entry_t *mbar;
595 ui_menu_entry_t *mfoobar;
596 ui_menu_entry_t *msep;
597 ui_menu_entry_t *mexit;
598 ui_menu_entry_t *mmodify;
599 ui_menu_entry_t *mabout;
600 errno_t rc;
601
602 rc = ui_create(display_spec, &ui);
603 if (rc != EOK) {
604 printf("Error creating UI on display %s.\n", display_spec);
605 return rc;
606 }
607
608 memset((void *) &demo, 0, sizeof(demo));
609 demo.ui = ui;
610
611 ui_wnd_params_init(&params);
612 params.caption = "UI Demo";
613 params.style |= ui_wds_maximize_btn | ui_wds_resizable;
614
615 /* FIXME: Auto layout */
616 if (ui_is_textmode(ui)) {
617 params.rect.p0.x = 0;
618 params.rect.p0.y = 0;
619 params.rect.p1.x = 46;
620 params.rect.p1.y = 25;
621 } else {
622 params.rect.p0.x = 0;
623 params.rect.p0.y = 0;
624 params.rect.p1.x = 255;
625 params.rect.p1.y = 410;
626 }
627
628 rc = ui_window_create(ui, &params, &window);
629 if (rc != EOK) {
630 printf("Error creating window.\n");
631 return rc;
632 }
633
634 ui_window_set_cb(window, &window_cb, (void *) &demo);
635 demo.window = window;
636
637 ui_res = ui_window_get_res(window);
638 gc = ui_window_get_gc(window);
639
640 rc = ui_fixed_create(&demo.fixed);
641 if (rc != EOK) {
642 printf("Error creating fixed layout.\n");
643 return rc;
644 }
645
646 rc = ui_menu_bar_create(ui, window, &demo.mbar);
647 if (rc != EOK) {
648 printf("Error creating menu bar.\n");
649 return rc;
650 }
651
652 rc = ui_menu_create(demo.mbar, "~F~ile", &demo.mfile);
653 if (rc != EOK) {
654 printf("Error creating menu.\n");
655 return rc;
656 }
657
658 rc = ui_menu_entry_create(demo.mfile, "~M~essage", "", &mmsg);
659 if (rc != EOK) {
660 printf("Error creating menu.\n");
661 return rc;
662 }
663
664 ui_menu_entry_set_cb(mmsg, uidemo_file_message, (void *) &demo);
665
666 rc = ui_menu_entry_create(demo.mfile, "~L~oad", "", &mload);
667 if (rc != EOK) {
668 printf("Error creating menu.\n");
669 return rc;
670 }
671
672 ui_menu_entry_set_cb(mload, uidemo_file_load, (void *) &demo);
673
674 rc = ui_menu_entry_create(demo.mfile, "~F~oo", "Ctrl-Alt-Del", &mfoo);
675 if (rc != EOK) {
676 printf("Error creating menu.\n");
677 return rc;
678 }
679
680 rc = ui_menu_entry_create(demo.mfile, "~B~ar", "", &mbar);
681 if (rc != EOK) {
682 printf("Error creating menu.\n");
683 return rc;
684 }
685
686 rc = ui_menu_entry_create(demo.mfile, "F~o~obar", "", &mfoobar);
687 if (rc != EOK) {
688 printf("Error creating menu.\n");
689 return rc;
690 }
691
692 rc = ui_menu_entry_sep_create(demo.mfile, &msep);
693 if (rc != EOK) {
694 printf("Error creating menu.\n");
695 return rc;
696 }
697
698 rc = ui_menu_entry_create(demo.mfile, "E~x~it", "Alt-F4", &mexit);
699 if (rc != EOK) {
700 printf("Error creating menu.\n");
701 return rc;
702 }
703
704 ui_menu_entry_set_cb(mexit, uidemo_file_exit, (void *) &demo);
705
706 rc = ui_menu_create(demo.mbar, "~E~dit", &demo.medit);
707 if (rc != EOK) {
708 printf("Error creating menu.\n");
709 return rc;
710 }
711
712 rc = ui_menu_entry_create(demo.medit, "~M~odify", "", &mmodify);
713 if (rc != EOK) {
714 printf("Error creating menu.\n");
715 return rc;
716 }
717
718 ui_menu_entry_set_cb(mmodify, uidemo_edit_modify, (void *) &demo);
719
720 rc = ui_menu_create(demo.mbar, "~P~references", &demo.mpreferences);
721 if (rc != EOK) {
722 printf("Error creating menu.\n");
723 return rc;
724 }
725
726 rc = ui_menu_create(demo.mbar, "~H~elp", &demo.mhelp);
727 if (rc != EOK) {
728 printf("Error creating menu.\n");
729 return rc;
730 }
731
732 rc = ui_menu_entry_create(demo.mhelp, "~A~bout", "Ctrl-H, F1", &mabout);
733 if (rc != EOK) {
734 printf("Error creating menu.\n");
735 return rc;
736 }
737
738 /* FIXME: Auto layout */
739 if (ui_is_textmode(ui)) {
740 rect.p0.x = 1;
741 rect.p0.y = 1;
742 rect.p1.x = 43;
743 rect.p1.y = 2;
744 } else {
745 rect.p0.x = 4;
746 rect.p0.y = 30;
747 rect.p1.x = 251;
748 rect.p1.y = 52;
749 }
750
751 ui_menu_bar_set_rect(demo.mbar, &rect);
752
753 rc = ui_fixed_add(demo.fixed, ui_menu_bar_ctl(demo.mbar));
754 if (rc != EOK) {
755 printf("Error adding control to layout.\n");
756 return rc;
757 }
758
759 rc = ui_tab_set_create(ui_res, &demo.tabset);
760 if (rc != EOK) {
761 printf("Error creating tab set.\n");
762 return rc;
763 }
764
765 /* FIXME: Auto layout */
766 if (ui_is_textmode(ui)) {
767 rect.p0.x = 2;
768 rect.p0.y = 2;
769 rect.p1.x = 44;
770 rect.p1.y = 24;
771 } else {
772 rect.p0.x = 8;
773 rect.p0.y = 53;
774 rect.p1.x = 250;
775 rect.p1.y = 405;
776 }
777
778 ui_tab_set_set_rect(demo.tabset, &rect);
779
780 rc = ui_tab_create(demo.tabset, "Basic", &demo.tbasic);
781 if (rc != EOK) {
782 printf("Error creating tab.\n");
783 return rc;
784 }
785
786 rc = ui_tab_create(demo.tabset, "Lists", &demo.tlists);
787 if (rc != EOK) {
788 printf("Error creating tab.\n");
789 return rc;
790 }
791
792 rc = ui_fixed_add(demo.fixed, ui_tab_set_ctl(demo.tabset));
793 if (rc != EOK) {
794 printf("Error adding control to layout.\n");
795 return rc;
796 }
797
798 rc = ui_fixed_create(&demo.bfixed);
799 if (rc != EOK) {
800 printf("Error creating fixed layout.\n");
801 return rc;
802 }
803
804 rc = ui_entry_create(window, "", &demo.entry);
805 if (rc != EOK) {
806 printf("Error creating entry.\n");
807 return rc;
808 }
809
810 /* FIXME: Auto layout */
811 if (ui_is_textmode(ui)) {
812 rect.p0.x = 4;
813 rect.p0.y = 5;
814 rect.p1.x = 41;
815 rect.p1.y = 6;
816 } else {
817 rect.p0.x = 15;
818 rect.p0.y = 88;
819 rect.p1.x = 205;
820 rect.p1.y = 113;
821 }
822
823 ui_entry_set_rect(demo.entry, &rect);
824 ui_entry_set_halign(demo.entry, gfx_halign_center);
825
826 rc = ui_fixed_add(demo.bfixed, ui_entry_ctl(demo.entry));
827 if (rc != EOK) {
828 printf("Error adding control to layout.\n");
829 return rc;
830 }
831
832 rc = ui_label_create(ui_res, "Text label", &demo.label);
833 if (rc != EOK) {
834 printf("Error creating label.\n");
835 return rc;
836 }
837
838 /* FIXME: Auto layout */
839 if (ui_is_textmode(ui)) {
840 rect.p0.x = 4;
841 rect.p0.y = 7;
842 rect.p1.x = 41;
843 rect.p1.y = 8;
844 } else {
845 rect.p0.x = 60;
846 rect.p0.y = 123;
847 rect.p1.x = 160;
848 rect.p1.y = 136;
849 }
850
851 ui_label_set_rect(demo.label, &rect);
852 ui_label_set_halign(demo.label, gfx_halign_center);
853
854 rc = ui_fixed_add(demo.bfixed, ui_label_ctl(demo.label));
855 if (rc != EOK) {
856 printf("Error adding control to layout.\n");
857 return rc;
858 }
859
860 rc = ui_pbutton_create(ui_res, "OK", &demo.pb1);
861 if (rc != EOK) {
862 printf("Error creating button.\n");
863 return rc;
864 }
865
866 ui_pbutton_set_cb(demo.pb1, &pbutton_cb, (void *) &demo);
867
868 /* FIXME: Auto layout */
869 if (ui_is_textmode(ui)) {
870 rect.p0.x = 4;
871 rect.p0.y = 9;
872 rect.p1.x = 15;
873 rect.p1.y = 10;
874 } else {
875 rect.p0.x = 15;
876 rect.p0.y = 146;
877 rect.p1.x = 105;
878 rect.p1.y = 174;
879 }
880
881 ui_pbutton_set_rect(demo.pb1, &rect);
882
883 ui_pbutton_set_default(demo.pb1, true);
884
885 rc = ui_fixed_add(demo.bfixed, ui_pbutton_ctl(demo.pb1));
886 if (rc != EOK) {
887 printf("Error adding control to layout.\n");
888 return rc;
889 }
890
891 rc = ui_pbutton_create(ui_res, "Cancel", &demo.pb2);
892 if (rc != EOK) {
893 printf("Error creating button.\n");
894 return rc;
895 }
896
897 ui_pbutton_set_cb(demo.pb2, &pbutton_cb, (void *) &demo);
898
899 if (ui_is_textmode(ui)) {
900 rect.p0.x = 30;
901 rect.p0.y = 9;
902 rect.p1.x = 41;
903 rect.p1.y = 10;
904 } else {
905 rect.p0.x = 115;
906 rect.p0.y = 146;
907 rect.p1.x = 205;
908 rect.p1.y = 174;
909 }
910
911 ui_pbutton_set_rect(demo.pb2, &rect);
912
913 rc = ui_fixed_add(demo.bfixed, ui_pbutton_ctl(demo.pb2));
914 if (rc != EOK) {
915 printf("Error adding control to layout.\n");
916 return rc;
917 }
918
919 gfx_bitmap_params_init(&bparams);
920 if (ui_is_textmode(ui)) {
921 bparams.rect.p0.x = 0;
922 bparams.rect.p0.y = 0;
923 bparams.rect.p1.x = 37;
924 bparams.rect.p1.y = 2;
925 } else {
926 bparams.rect.p0.x = 0;
927 bparams.rect.p0.y = 0;
928 bparams.rect.p1.x = 188;
929 bparams.rect.p1.y = 24;
930 }
931
932 rc = gfx_bitmap_create(gc, &bparams, NULL, &bitmap);
933 if (rc != EOK)
934 return rc;
935
936 rc = bitmap_moire(bitmap, bparams.rect.p1.x, bparams.rect.p1.y);
937 if (rc != EOK)
938 return rc;
939
940 rc = ui_image_create(ui_res, bitmap, &params.rect, &demo.image);
941 if (rc != EOK) {
942 printf("Error creating label.\n");
943 return rc;
944 }
945
946 if (ui_is_textmode(ui)) {
947 off.x = 4;
948 off.y = 11;
949 } else {
950 off.x = 15;
951 off.y = 190;
952 }
953
954 gfx_rect_translate(&off, &bparams.rect, &rect);
955
956 /* Adjust for frame width (2 x 1 pixel) */
957 if (!ui_is_textmode(ui)) {
958 ui_image_set_flags(demo.image, ui_imgf_frame);
959 rect.p1.x += 2;
960 rect.p1.y += 2;
961 }
962
963 ui_image_set_rect(demo.image, &rect);
964
965 rc = ui_fixed_add(demo.bfixed, ui_image_ctl(demo.image));
966 if (rc != EOK) {
967 printf("Error adding control to layout.\n");
968 return rc;
969 }
970
971 rc = ui_checkbox_create(ui_res, "Read only", &demo.checkbox);
972 if (rc != EOK) {
973 printf("Error creating check box.\n");
974 return rc;
975 }
976
977 ui_checkbox_set_cb(demo.checkbox, &checkbox_cb, (void *) &demo);
978
979 /* FIXME: Auto layout */
980 if (ui_is_textmode(ui)) {
981 rect.p0.x = 4;
982 rect.p0.y = 14;
983 rect.p1.x = 14;
984 rect.p1.y = 15;
985 } else {
986 rect.p0.x = 15;
987 rect.p0.y = 225;
988 rect.p1.x = 140;
989 rect.p1.y = 245;
990 }
991
992 ui_checkbox_set_rect(demo.checkbox, &rect);
993
994 rc = ui_fixed_add(demo.bfixed, ui_checkbox_ctl(demo.checkbox));
995 if (rc != EOK) {
996 printf("Error adding control to layout.\n");
997 return rc;
998 }
999
1000 rc = ui_rbutton_group_create(ui_res, &demo.rbgroup);
1001 if (rc != EOK) {
1002 printf("Error creating radio button group.\n");
1003 return rc;
1004 }
1005
1006 rc = ui_rbutton_create(demo.rbgroup, "Left", (void *) &uidemo_halign[0],
1007 &demo.rbleft);
1008 if (rc != EOK) {
1009 printf("Error creating radio button.\n");
1010 return rc;
1011 }
1012
1013 ui_rbutton_group_set_cb(demo.rbgroup, &rbutton_group_cb,
1014 (void *) &demo);
1015
1016 /* FIXME: Auto layout */
1017 if (ui_is_textmode(ui)) {
1018 rect.p0.x = 4;
1019 rect.p0.y = 16;
1020 rect.p1.x = 14;
1021 rect.p1.y = 17;
1022 } else {
1023 rect.p0.x = 15;
1024 rect.p0.y = 255;
1025 rect.p1.x = 140;
1026 rect.p1.y = 275;
1027 }
1028 ui_rbutton_set_rect(demo.rbleft, &rect);
1029
1030 rc = ui_fixed_add(demo.bfixed, ui_rbutton_ctl(demo.rbleft));
1031 if (rc != EOK) {
1032 printf("Error adding control to layout.\n");
1033 return rc;
1034 }
1035
1036 rc = ui_rbutton_create(demo.rbgroup, "Center", (void *) &uidemo_halign[1],
1037 &demo.rbcenter);
1038 if (rc != EOK) {
1039 printf("Error creating radio button.\n");
1040 return rc;
1041 }
1042
1043 /* FIXME: Auto layout */
1044 if (ui_is_textmode(ui)) {
1045 rect.p0.x = 4;
1046 rect.p0.y = 17;
1047 rect.p1.x = 14;
1048 rect.p1.y = 18;
1049 } else {
1050 rect.p0.x = 15;
1051 rect.p0.y = 285;
1052 rect.p1.x = 140;
1053 rect.p1.y = 305;
1054 }
1055 ui_rbutton_set_rect(demo.rbcenter, &rect);
1056 ui_rbutton_select(demo.rbcenter);
1057
1058 rc = ui_fixed_add(demo.bfixed, ui_rbutton_ctl(demo.rbcenter));
1059 if (rc != EOK) {
1060 printf("Error adding control to layout.\n");
1061 return rc;
1062 }
1063
1064 rc = ui_rbutton_create(demo.rbgroup, "Right", (void *) &uidemo_halign[2],
1065 &demo.rbright);
1066 if (rc != EOK) {
1067 printf("Error creating radio button.\n");
1068 return rc;
1069 }
1070
1071 /* FIXME: Auto layout */
1072 if (ui_is_textmode(ui)) {
1073 rect.p0.x = 4;
1074 rect.p0.y = 18;
1075 rect.p1.x = 14;
1076 rect.p1.y = 19;
1077 } else {
1078 rect.p0.x = 15;
1079 rect.p0.y = 315;
1080 rect.p1.x = 140;
1081 rect.p1.y = 335;
1082 }
1083 ui_rbutton_set_rect(demo.rbright, &rect);
1084
1085 rc = ui_fixed_add(demo.bfixed, ui_rbutton_ctl(demo.rbright));
1086 if (rc != EOK) {
1087 printf("Error adding control to layout.\n");
1088 return rc;
1089 }
1090
1091 rc = ui_slider_create(ui_res, &demo.slider);
1092 if (rc != EOK) {
1093 printf("Error creating button.\n");
1094 return rc;
1095 }
1096
1097 ui_slider_set_cb(demo.slider, &slider_cb, (void *) &demo);
1098
1099 /* FIXME: Auto layout */
1100 if (ui_is_textmode(ui)) {
1101 rect.p0.x = 4;
1102 rect.p0.y = 20;
1103 rect.p1.x = 32;
1104 rect.p1.y = 21;
1105 } else {
1106 rect.p0.x = 15;
1107 rect.p0.y = 345;
1108 rect.p1.x = 130;
1109 rect.p1.y = 365;
1110 }
1111
1112 ui_slider_set_rect(demo.slider, &rect);
1113
1114 rc = ui_fixed_add(demo.bfixed, ui_slider_ctl(demo.slider));
1115 if (rc != EOK) {
1116 printf("Error adding control to layout.\n");
1117 return rc;
1118 }
1119
1120 rc = ui_scrollbar_create(ui, window, ui_sbd_horiz, &demo.hscrollbar);
1121 if (rc != EOK) {
1122 printf("Error creating scrollbar.\n");
1123 return rc;
1124 }
1125
1126 ui_scrollbar_set_cb(demo.hscrollbar, &scrollbar_cb, (void *) &demo);
1127
1128 /* FIXME: Auto layout */
1129 if (ui_is_textmode(ui)) {
1130 rect.p0.x = 4;
1131 rect.p0.y = 22;
1132 rect.p1.x = 42;
1133 rect.p1.y = 23;
1134 } else {
1135 rect.p0.x = 15;
1136 rect.p0.y = 375;
1137 rect.p1.x = 220;
1138 rect.p1.y = 398;
1139 }
1140
1141 ui_scrollbar_set_rect(demo.hscrollbar, &rect);
1142
1143 ui_scrollbar_set_thumb_length(demo.hscrollbar,
1144 ui_scrollbar_through_length(demo.hscrollbar) / 4);
1145
1146 rc = ui_fixed_add(demo.bfixed, ui_scrollbar_ctl(demo.hscrollbar));
1147 if (rc != EOK) {
1148 printf("Error adding control to layout.\n");
1149 return rc;
1150 }
1151
1152 rc = ui_scrollbar_create(ui, window, ui_sbd_vert, &demo.vscrollbar);
1153 if (rc != EOK) {
1154 printf("Error creating button.\n");
1155 return rc;
1156 }
1157
1158 ui_scrollbar_set_cb(demo.vscrollbar, &scrollbar_cb, (void *) &demo);
1159
1160 /* FIXME: Auto layout */
1161 if (ui_is_textmode(ui)) {
1162 rect.p0.x = 42;
1163 rect.p0.y = 5;
1164 rect.p1.x = 43;
1165 rect.p1.y = 22;
1166 } else {
1167 rect.p0.x = 220;
1168 rect.p0.y = 88;
1169 rect.p1.x = 243;
1170 rect.p1.y = 375;
1171 }
1172
1173 ui_scrollbar_set_rect(demo.vscrollbar, &rect);
1174
1175 ui_scrollbar_set_thumb_length(demo.vscrollbar,
1176 ui_scrollbar_through_length(demo.vscrollbar) / 4);
1177
1178 rc = ui_fixed_add(demo.bfixed, ui_scrollbar_ctl(demo.vscrollbar));
1179 if (rc != EOK) {
1180 printf("Error adding control to layout.\n");
1181 return rc;
1182 }
1183
1184 ui_tab_add(demo.tbasic, ui_fixed_ctl(demo.bfixed));
1185
1186 ui_window_add(window, ui_fixed_ctl(demo.fixed));
1187
1188 rc = ui_window_paint(window);
1189 if (rc != EOK) {
1190 printf("Error painting window.\n");
1191 return rc;
1192 }
1193
1194 ui_run(ui);
1195
1196 ui_window_destroy(window);
1197 ui_destroy(ui);
1198
1199 return EOK;
1200}
1201
1202/** Fill bitmap with moire pattern.
1203 *
1204 * @param bitmap Bitmap
1205 * @param w Bitmap width
1206 * @param h Bitmap height
1207 * @return EOK on success or an error code
1208 */
1209static errno_t bitmap_moire(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
1210{
1211 int i, j;
1212 int k;
1213 pixelmap_t pixelmap;
1214 gfx_bitmap_alloc_t alloc;
1215 errno_t rc;
1216
1217 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
1218 if (rc != EOK)
1219 return rc;
1220
1221 /* In absence of anything else, use pixelmap */
1222 pixelmap.width = w;
1223 pixelmap.height = h;
1224 pixelmap.data = alloc.pixels;
1225
1226 for (i = 0; i < w; i++) {
1227 for (j = 0; j < h; j++) {
1228 k = i * i + j * j;
1229 pixelmap_put_pixel(&pixelmap, i, j,
1230 PIXEL(0, k, k, 255 - k));
1231 }
1232 }
1233
1234 return EOK;
1235}
1236
1237static void print_syntax(void)
1238{
1239 printf("Syntax: uidemo [-d <display-spec>]\n");
1240}
1241
1242int main(int argc, char *argv[])
1243{
1244 const char *display_spec = UI_ANY_DEFAULT;
1245 errno_t rc;
1246 int i;
1247
1248 i = 1;
1249 while (i < argc && argv[i][0] == '-') {
1250 if (str_cmp(argv[i], "-d") == 0) {
1251 ++i;
1252 if (i >= argc) {
1253 printf("Argument missing.\n");
1254 print_syntax();
1255 return 1;
1256 }
1257
1258 display_spec = argv[i++];
1259 } else {
1260 printf("Invalid option '%s'.\n", argv[i]);
1261 print_syntax();
1262 return 1;
1263 }
1264 }
1265
1266 if (i < argc) {
1267 print_syntax();
1268 return 1;
1269 }
1270
1271 rc = ui_demo(display_spec);
1272 if (rc != EOK)
1273 return 1;
1274
1275 return 0;
1276}
1277
1278/** @}
1279 */
Note: See TracBrowser for help on using the repository browser.