source: mainline/uspace/app/uidemo/uidemo.c@ 7020d1f

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

Radio button

Please don't ask me how I derived the formulae for circle midpoint
algorithm, it's been 8 years and I just don't remember.

  • Property mode set to 100644
File size: 11.1 KB
RevLine 
[f80690a]1/*
[7020d1f]2 * Copyright (c) 2021 Jiri Svoboda
[f80690a]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
[d8ddf7a]35#include <gfx/bitmap.h>
[c9a7adc]36#include <gfx/coord.h>
[d8ddf7a]37#include <io/pixelmap.h>
[f80690a]38#include <stdio.h>
39#include <str.h>
[d8ddf7a]40#include <ui/entry.h>
[8009dc27]41#include <ui/fixed.h>
[d8ddf7a]42#include <ui/image.h>
[ba09d06]43#include <ui/label.h>
[f80690a]44#include <ui/pbutton.h>
[47728678]45#include <ui/resource.h>
[d284ce9]46#include <ui/ui.h>
47#include <ui/window.h>
[f6df5a3]48#include "uidemo.h"
[47728678]49
[d8ddf7a]50static errno_t bitmap_moire(gfx_bitmap_t *, gfx_coord_t, gfx_coord_t);
51
[d284ce9]52static void wnd_close(ui_window_t *, void *);
53
54static ui_window_cb_t window_cb = {
[b71c0fc]55 .close = wnd_close
[47728678]56};
57
[8ef48ece]58static void pb_clicked(ui_pbutton_t *, void *);
59
60static ui_pbutton_cb_t pbutton_cb = {
61 .clicked = pb_clicked
62};
63
[d70dc1c4]64static void checkbox_switched(ui_checkbox_t *, void *, bool);
65
66static ui_checkbox_cb_t checkbox_cb = {
67 .switched = checkbox_switched
68};
69
[7020d1f]70static void rb_selected(ui_rbutton_group_t *, void *, void *);
71
72static ui_rbutton_group_cb_t rbutton_group_cb = {
73 .selected = rb_selected
74};
75
[d284ce9]76/** Window close button was clicked.
77 *
78 * @param window Window
79 * @param arg Argument (demo)
80 */
81static void wnd_close(ui_window_t *window, void *arg)
[47728678]82{
[20d2c6c]83 ui_demo_t *demo = (ui_demo_t *) arg;
84
[d284ce9]85 ui_quit(demo->ui);
[47728678]86}
87
[8ef48ece]88/** Push button was clicked.
89 *
90 * @param pbutton Push button
91 * @param arg Argument (demo)
92 */
93static void pb_clicked(ui_pbutton_t *pbutton, void *arg)
94{
95 ui_demo_t *demo = (ui_demo_t *) arg;
[ba09d06]96 errno_t rc;
[8ef48ece]97
98 if (pbutton == demo->pb1) {
[d8ddf7a]99 rc = ui_entry_set_text(demo->entry, "OK pressed");
[ba09d06]100 if (rc != EOK)
[d8ddf7a]101 printf("Error changing entry text.\n");
102 (void) ui_entry_paint(demo->entry);
[8ef48ece]103 } else {
[d8ddf7a]104 rc = ui_entry_set_text(demo->entry, "Cancel pressed");
[ba09d06]105 if (rc != EOK)
[d8ddf7a]106 printf("Error changing entry text.\n");
107 (void) ui_entry_paint(demo->entry);
[8ef48ece]108 }
109}
110
[d70dc1c4]111/** Check box was switched.
112 *
113 * @param checkbox Check box
114 * @param arg Argument (demo)
115 */
116static void checkbox_switched(ui_checkbox_t *checkbox, void *arg, bool enable)
117{
118 ui_demo_t *demo = (ui_demo_t *) arg;
119 errno_t rc;
120
121 if (enable) {
122 rc = ui_entry_set_text(demo->entry, "Checked");
123 if (rc != EOK)
124 printf("Error changing entry text.\n");
125 (void) ui_entry_paint(demo->entry);
126 } else {
127 rc = ui_entry_set_text(demo->entry, "Unchecked");
128 if (rc != EOK)
129 printf("Error changing entry text.\n");
130 (void) ui_entry_paint(demo->entry);
131 }
132}
133
[7020d1f]134/** Radio button was selected.
135 *
136 * @param rbgroup Radio button group
137 * @param garg Group argument (demo)
138 * @param barg Button argument
139 */
140static void rb_selected(ui_rbutton_group_t *rbgroup, void *garg, void *barg)
141{
142 ui_demo_t *demo = (ui_demo_t *) garg;
143 const char *text = (const char *) barg;
144 errno_t rc;
145
146 rc = ui_entry_set_text(demo->entry, text);
147 if (rc != EOK)
148 printf("Error changing entry text.\n");
149 (void) ui_entry_paint(demo->entry);
150}
151
[47728678]152/** Run UI demo on display server. */
[d284ce9]153static errno_t ui_demo(const char *display_spec)
[47728678]154{
[d284ce9]155 ui_t *ui = NULL;
156 ui_wnd_params_t params;
157 ui_window_t *window = NULL;
[f6df5a3]158 ui_demo_t demo;
[47728678]159 gfx_rect_t rect;
[d8ddf7a]160 gfx_context_t *gc;
[3583ffb]161 ui_resource_t *ui_res;
[d8ddf7a]162 gfx_bitmap_params_t bparams;
163 gfx_bitmap_t *bitmap;
164 gfx_coord2_t off;
[47728678]165 errno_t rc;
166
[d284ce9]167 rc = ui_create(display_spec, &ui);
[47728678]168 if (rc != EOK) {
[d284ce9]169 printf("Error creating UI on display %s.\n", display_spec);
[47728678]170 return rc;
171 }
172
[d284ce9]173 ui_wnd_params_init(&params);
174 params.caption = "UI Demo";
[2d879f7]175 params.style |= ui_wds_resizable;
[47728678]176 params.rect.p0.x = 0;
177 params.rect.p0.y = 0;
178 params.rect.p1.x = 220;
[7020d1f]179 params.rect.p1.y = 330;
[47728678]180
[1769693]181 memset((void *) &demo, 0, sizeof(demo));
[d284ce9]182 demo.ui = ui;
[1769693]183
[d284ce9]184 rc = ui_window_create(ui, &params, &window);
[47728678]185 if (rc != EOK) {
186 printf("Error creating window.\n");
187 return rc;
188 }
189
[d284ce9]190 ui_window_set_cb(window, &window_cb, (void *) &demo);
191 demo.window = window;
[47728678]192
[3583ffb]193 ui_res = ui_window_get_res(window);
[d8ddf7a]194 gc = ui_window_get_gc(window);
[3583ffb]195
[8009dc27]196 rc = ui_fixed_create(&demo.fixed);
197 if (rc != EOK) {
198 printf("Error creating fixed layout.\n");
199 return rc;
200 }
201
[d8ddf7a]202 rc = ui_label_create(ui_res, "Text label", &demo.label);
[ba09d06]203 if (rc != EOK) {
204 printf("Error creating label.\n");
205 return rc;
206 }
207
208 rect.p0.x = 60;
209 rect.p0.y = 37;
210 rect.p1.x = 160;
211 rect.p1.y = 50;
212 ui_label_set_rect(demo.label, &rect);
[58a67050]213 ui_label_set_halign(demo.label, gfx_halign_center);
[ba09d06]214
[8009dc27]215 rc = ui_fixed_add(demo.fixed, ui_label_ctl(demo.label));
216 if (rc != EOK) {
217 printf("Error adding control to layout.\n");
218 return rc;
219 }
220
[d8ddf7a]221 rc = ui_pbutton_create(ui_res, "OK", &demo.pb1);
[47728678]222 if (rc != EOK) {
223 printf("Error creating button.\n");
[f6df5a3]224 return rc;
[47728678]225 }
226
[8ef48ece]227 ui_pbutton_set_cb(demo.pb1, &pbutton_cb, (void *) &demo);
228
[ba09d06]229 rect.p0.x = 15;
[d8ddf7a]230 rect.p0.y = 70;
[ba09d06]231 rect.p1.x = 105;
[d8ddf7a]232 rect.p1.y = 98;
[f6df5a3]233 ui_pbutton_set_rect(demo.pb1, &rect);
[47728678]234
[c9a7adc]235 ui_pbutton_set_default(demo.pb1, true);
236
[8009dc27]237 rc = ui_fixed_add(demo.fixed, ui_pbutton_ctl(demo.pb1));
238 if (rc != EOK) {
239 printf("Error adding control to layout.\n");
240 return rc;
241 }
242
[3583ffb]243 rc = ui_pbutton_create(ui_res, "Cancel", &demo.pb2);
[47728678]244 if (rc != EOK) {
245 printf("Error creating button.\n");
[f6df5a3]246 return rc;
[47728678]247 }
248
[8ef48ece]249 ui_pbutton_set_cb(demo.pb2, &pbutton_cb, (void *) &demo);
250
[ba09d06]251 rect.p0.x = 115;
[d8ddf7a]252 rect.p0.y = 70;
[ba09d06]253 rect.p1.x = 205;
[d8ddf7a]254 rect.p1.y = 98;
[f6df5a3]255 ui_pbutton_set_rect(demo.pb2, &rect);
[47728678]256
[8009dc27]257 rc = ui_fixed_add(demo.fixed, ui_pbutton_ctl(demo.pb2));
258 if (rc != EOK) {
259 printf("Error adding control to layout.\n");
260 return rc;
261 }
262
[d8ddf7a]263 rc = ui_entry_create(ui_res, "", &demo.entry);
264 if (rc != EOK) {
265 printf("Error creating entry.\n");
266 return rc;
267 }
268
269 rect.p0.x = 15;
270 rect.p0.y = 110;
271 rect.p1.x = 205;
272 rect.p1.y = 135;
273 ui_entry_set_rect(demo.entry, &rect);
274 ui_entry_set_halign(demo.entry, gfx_halign_center);
275
276 rc = ui_fixed_add(demo.fixed, ui_entry_ctl(demo.entry));
277 if (rc != EOK) {
278 printf("Error adding control to layout.\n");
279 return rc;
280 }
281
282 gfx_bitmap_params_init(&bparams);
283 bparams.rect.p0.x = 0;
284 bparams.rect.p0.y = 0;
285 bparams.rect.p1.x = 188;
286 bparams.rect.p1.y = 24;
287
288 rc = gfx_bitmap_create(gc, &bparams, NULL, &bitmap);
289 if (rc != EOK)
290 return rc;
291
292 rc = bitmap_moire(bitmap, bparams.rect.p1.x, bparams.rect.p1.y);
293 if (rc != EOK)
294 return rc;
295
296 rc = ui_image_create(ui_res, bitmap, &params.rect, &demo.image);
297 if (rc != EOK) {
298 printf("Error creating label.\n");
299 return rc;
300 }
301
302 off.x = 15;
303 off.y = 145;
304 gfx_rect_translate(&off, &bparams.rect, &rect);
305
306 /* Adjust for frame width (2 x 1 pixel) */
307 rect.p1.x += 2;
308 rect.p1.y += 2;
309 ui_image_set_rect(demo.image, &rect);
310 ui_image_set_flags(demo.image, ui_imgf_frame);
311
312 rc = ui_fixed_add(demo.fixed, ui_image_ctl(demo.image));
313 if (rc != EOK) {
314 printf("Error adding control to layout.\n");
315 return rc;
316 }
317
[d70dc1c4]318 rc = ui_checkbox_create(ui_res, "Check me", &demo.checkbox);
319 if (rc != EOK) {
320 printf("Error creating check box.\n");
321 return rc;
322 }
323
324 ui_checkbox_set_cb(demo.checkbox, &checkbox_cb, (void *) &demo);
325
326 rect.p0.x = 15;
327 rect.p0.y = 180;
328 rect.p1.x = 140;
329 rect.p1.y = 200;
330 ui_checkbox_set_rect(demo.checkbox, &rect);
331
332 rc = ui_fixed_add(demo.fixed, ui_checkbox_ctl(demo.checkbox));
333 if (rc != EOK) {
334 printf("Error adding control to layout.\n");
335 return rc;
336 }
337
[7020d1f]338 rc = ui_rbutton_group_create(ui_res, &demo.rbgroup);
339 if (rc != EOK) {
340 printf("Error creating radio button group.\n");
341 return rc;
342 }
343
344 rc = ui_rbutton_create(demo.rbgroup, "Option 1", (void *) "First",
345 &demo.rb1);
346 if (rc != EOK) {
347 printf("Error creating radio button.\n");
348 return rc;
349 }
350
351 ui_rbutton_group_set_cb(demo.rbgroup, &rbutton_group_cb,
352 (void *) &demo);
353
354 rect.p0.x = 15;
355 rect.p0.y = 210;
356 rect.p1.x = 140;
357 rect.p1.y = 230;
358 ui_rbutton_set_rect(demo.rb1, &rect);
359
360 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb1));
361 if (rc != EOK) {
362 printf("Error adding control to layout.\n");
363 return rc;
364 }
365
366 rc = ui_rbutton_create(demo.rbgroup, "Option 2", (void *) "Second",
367 &demo.rb2);
368 if (rc != EOK) {
369 printf("Error creating radio button.\n");
370 return rc;
371 }
372
373 rect.p0.x = 15;
374 rect.p0.y = 240;
375 rect.p1.x = 140;
376 rect.p1.y = 260;
377 ui_rbutton_set_rect(demo.rb2, &rect);
378
379 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb2));
380 if (rc != EOK) {
381 printf("Error adding control to layout.\n");
382 return rc;
383 }
384
385 rc = ui_rbutton_create(demo.rbgroup, "Option 3", (void *) "Third",
386 &demo.rb3);
387 if (rc != EOK) {
388 printf("Error creating radio button.\n");
389 return rc;
390 }
391
392 rect.p0.x = 15;
393 rect.p0.y = 270;
394 rect.p1.x = 140;
395 rect.p1.y = 290;
396 ui_rbutton_set_rect(demo.rb3, &rect);
397
398 rc = ui_fixed_add(demo.fixed, ui_rbutton_ctl(demo.rb3));
399 if (rc != EOK) {
400 printf("Error adding control to layout.\n");
401 return rc;
402 }
403
[b71c0fc]404 ui_window_add(window, ui_fixed_ctl(demo.fixed));
405
[fa01c05]406 rc = ui_window_paint(window);
[ba09d06]407 if (rc != EOK) {
[fa01c05]408 printf("Error painting window.\n");
[f6df5a3]409 return rc;
[47728678]410 }
411
[d284ce9]412 ui_run(ui);
[47728678]413
[d284ce9]414 ui_window_destroy(window);
415 ui_destroy(ui);
[47728678]416
417 return EOK;
418}
419
[d8ddf7a]420/** Fill bitmap with moire pattern.
421 *
422 * @param bitmap Bitmap
423 * @param w Bitmap width
424 * @param h Bitmap height
425 * @return EOK on success or an error code
426 */
427static errno_t bitmap_moire(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
428{
429 int i, j;
430 int k;
431 pixelmap_t pixelmap;
432 gfx_bitmap_alloc_t alloc;
433 errno_t rc;
434
435 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
436 if (rc != EOK)
437 return rc;
438
439 /* In absence of anything else, use pixelmap */
440 pixelmap.width = w;
441 pixelmap.height = h;
442 pixelmap.data = alloc.pixels;
443
444 for (i = 0; i < w; i++) {
445 for (j = 0; j < h; j++) {
446 k = i * i + j * j;
447 pixelmap_put_pixel(&pixelmap, i, j,
448 PIXEL(255, k, k, 255 - k));
449 }
450 }
451
452 return EOK;
453}
454
[d284ce9]455static void print_syntax(void)
456{
457 printf("Syntax: uidemo [-d <display-spec>]\n");
458}
459
[f80690a]460int main(int argc, char *argv[])
461{
[d284ce9]462 const char *display_spec = UI_DISPLAY_DEFAULT;
[f80690a]463 errno_t rc;
464 int i;
465
466 i = 1;
467 while (i < argc && argv[i][0] == '-') {
468 if (str_cmp(argv[i], "-d") == 0) {
469 ++i;
470 if (i >= argc) {
471 printf("Argument missing.\n");
472 print_syntax();
473 return 1;
474 }
475
[d284ce9]476 display_spec = argv[i++];
[f80690a]477 } else {
478 printf("Invalid option '%s'.\n", argv[i]);
479 print_syntax();
480 return 1;
481 }
482 }
483
484 if (i < argc) {
485 print_syntax();
486 return 1;
487 }
488
[d284ce9]489 rc = ui_demo(display_spec);
[47728678]490 if (rc != EOK)
[f80690a]491 return 1;
492
493 return 0;
494}
495
496/** @}
497 */
Note: See TracBrowser for help on using the repository browser.