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

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

Slider UI control

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