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
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 <str.h>
40#include <ui/entry.h>
41#include <ui/fixed.h>
42#include <ui/image.h>
43#include <ui/label.h>
44#include <ui/pbutton.h>
45#include <ui/resource.h>
46#include <ui/ui.h>
47#include <ui/window.h>
48#include "uidemo.h"
49
50static errno_t bitmap_moire(gfx_bitmap_t *, gfx_coord_t, gfx_coord_t);
51
52static void wnd_close(ui_window_t *, void *);
53
54static ui_window_cb_t window_cb = {
55 .close = wnd_close
56};
57
58static void pb_clicked(ui_pbutton_t *, void *);
59
60static ui_pbutton_cb_t pbutton_cb = {
61 .clicked = pb_clicked
62};
63
64static void checkbox_switched(ui_checkbox_t *, void *, bool);
65
66static ui_checkbox_cb_t checkbox_cb = {
67 .switched = checkbox_switched
68};
69
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
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)
82{
83 ui_demo_t *demo = (ui_demo_t *) arg;
84
85 ui_quit(demo->ui);
86}
87
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;
96 errno_t rc;
97
98 if (pbutton == demo->pb1) {
99 rc = ui_entry_set_text(demo->entry, "OK pressed");
100 if (rc != EOK)
101 printf("Error changing entry text.\n");
102 (void) ui_entry_paint(demo->entry);
103 } else {
104 rc = ui_entry_set_text(demo->entry, "Cancel pressed");
105 if (rc != EOK)
106 printf("Error changing entry text.\n");
107 (void) ui_entry_paint(demo->entry);
108 }
109}
110
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
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
152/** Run UI demo on display server. */
153static errno_t ui_demo(const char *display_spec)
154{
155 ui_t *ui = NULL;
156 ui_wnd_params_t params;
157 ui_window_t *window = NULL;
158 ui_demo_t demo;
159 gfx_rect_t rect;
160 gfx_context_t *gc;
161 ui_resource_t *ui_res;
162 gfx_bitmap_params_t bparams;
163 gfx_bitmap_t *bitmap;
164 gfx_coord2_t off;
165 errno_t rc;
166
167 rc = ui_create(display_spec, &ui);
168 if (rc != EOK) {
169 printf("Error creating UI on display %s.\n", display_spec);
170 return rc;
171 }
172
173 ui_wnd_params_init(&params);
174 params.caption = "UI Demo";
175 params.style |= ui_wds_resizable;
176 params.rect.p0.x = 0;
177 params.rect.p0.y = 0;
178 params.rect.p1.x = 220;
179 params.rect.p1.y = 330;
180
181 memset((void *) &demo, 0, sizeof(demo));
182 demo.ui = ui;
183
184 rc = ui_window_create(ui, &params, &window);
185 if (rc != EOK) {
186 printf("Error creating window.\n");
187 return rc;
188 }
189
190 ui_window_set_cb(window, &window_cb, (void *) &demo);
191 demo.window = window;
192
193 ui_res = ui_window_get_res(window);
194 gc = ui_window_get_gc(window);
195
196 rc = ui_fixed_create(&demo.fixed);
197 if (rc != EOK) {
198 printf("Error creating fixed layout.\n");
199 return rc;
200 }
201
202 rc = ui_label_create(ui_res, "Text label", &demo.label);
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);
213 ui_label_set_halign(demo.label, gfx_halign_center);
214
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
221 rc = ui_pbutton_create(ui_res, "OK", &demo.pb1);
222 if (rc != EOK) {
223 printf("Error creating button.\n");
224 return rc;
225 }
226
227 ui_pbutton_set_cb(demo.pb1, &pbutton_cb, (void *) &demo);
228
229 rect.p0.x = 15;
230 rect.p0.y = 70;
231 rect.p1.x = 105;
232 rect.p1.y = 98;
233 ui_pbutton_set_rect(demo.pb1, &rect);
234
235 ui_pbutton_set_default(demo.pb1, true);
236
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
243 rc = ui_pbutton_create(ui_res, "Cancel", &demo.pb2);
244 if (rc != EOK) {
245 printf("Error creating button.\n");
246 return rc;
247 }
248
249 ui_pbutton_set_cb(demo.pb2, &pbutton_cb, (void *) &demo);
250
251 rect.p0.x = 115;
252 rect.p0.y = 70;
253 rect.p1.x = 205;
254 rect.p1.y = 98;
255 ui_pbutton_set_rect(demo.pb2, &rect);
256
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
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
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
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
404 ui_window_add(window, ui_fixed_ctl(demo.fixed));
405
406 rc = ui_window_paint(window);
407 if (rc != EOK) {
408 printf("Error painting window.\n");
409 return rc;
410 }
411
412 ui_run(ui);
413
414 ui_window_destroy(window);
415 ui_destroy(ui);
416
417 return EOK;
418}
419
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
455static void print_syntax(void)
456{
457 printf("Syntax: uidemo [-d <display-spec>]\n");
458}
459
460int main(int argc, char *argv[])
461{
462 const char *display_spec = UI_DISPLAY_DEFAULT;
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
476 display_spec = argv[i++];
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
489 rc = ui_demo(display_spec);
490 if (rc != EOK)
491 return 1;
492
493 return 0;
494}
495
496/** @}
497 */
Note: See TracBrowser for help on using the repository browser.