Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 7020d1f in mainline


Ignore:
Timestamp:
2021-02-01T10:53:48Z (4 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
f14a900
Parents:
d70dc1c4
git-author:
Jiri Svoboda <jiri@…> (2020-01-31 16:53:25)
git-committer:
Jiri Svoboda <jiri@…> (2021-02-01 10:53:48)
Message:

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.

Location:
uspace
Files:
6 added
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/uidemo/uidemo.c

    rd70dc1c4 r7020d1f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6868};
    6969
     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
    7076/** Window close button was clicked.
    7177 *
     
    126132}
    127133
     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
    128152/** Run UI demo on display server. */
    129153static errno_t ui_demo(const char *display_spec)
     
    153177        params.rect.p0.y = 0;
    154178        params.rect.p1.x = 220;
    155         params.rect.p1.y = 220;
     179        params.rect.p1.y = 330;
    156180
    157181        memset((void *) &demo, 0, sizeof(demo));
     
    307331
    308332        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));
    309399        if (rc != EOK) {
    310400                printf("Error adding control to layout.\n");
  • uspace/app/uidemo/uidemo.h

    rd70dc1c4 r7020d1f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4343#include <ui/label.h>
    4444#include <ui/pbutton.h>
     45#include <ui/rbutton.h>
    4546#include <ui/ui.h>
    4647#include <ui/window.h>
     
    5758        ui_pbutton_t *pb2;
    5859        ui_checkbox_t *checkbox;
     60        ui_rbutton_group_t *rbgroup;
     61        ui_rbutton_t *rb1;
     62        ui_rbutton_t *rb2;
     63        ui_rbutton_t *rb3;
    5964} ui_demo_t;
    6065
  • uspace/lib/ui/include/ui/paint.h

    rd70dc1c4 r7020d1f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4040#include <gfx/color.h>
    4141#include <gfx/coord.h>
     42#include <types/ui/paint.h>
    4243#include <types/ui/resource.h>
    4344
    44 errno_t ui_paint_bevel(gfx_context_t *, gfx_rect_t *, gfx_color_t *,
     45extern errno_t ui_paint_bevel(gfx_context_t *, gfx_rect_t *, gfx_color_t *,
    4546    gfx_color_t *, gfx_coord_t, gfx_rect_t *);
    46 errno_t ui_paint_inset_frame(ui_resource_t *, gfx_rect_t *, gfx_rect_t *);
     47extern errno_t ui_paint_inset_frame(ui_resource_t *, gfx_rect_t *,
     48    gfx_rect_t *);
     49extern errno_t ui_paint_filled_circle(gfx_context_t *, gfx_coord2_t *,
     50    gfx_coord_t, ui_fcircle_part_t);
    4751
    4852#endif
  • uspace/lib/ui/meson.build

    rd70dc1c4 r7020d1f  
    11#
    2 # Copyright (c) 2020 Jiri Svoboda
     2# Copyright (c) 2021 Jiri Svoboda
    33# All rights reserved.
    44#
     
    3838        'src/paint.c',
    3939        'src/pbutton.c',
     40        'src/rbutton.c',
    4041        'src/resource.c',
    4142        'src/ui.c',
     
    5455        'test/paint.c',
    5556        'test/pbutton.c',
     57        'test/rbutton.c',
    5658        'test/resource.c',
    5759        'test/ui.c',
  • uspace/lib/ui/src/paint.c

    rd70dc1c4 r7020d1f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    149149}
    150150
     151/** Paint filled circle vertical scanline.
     152 *
     153 * @param gc Graphic context
     154 * @param center Coordinates of the center of the circle
     155 * @param x X-coordinate of the scanline
     156 * @param y0 Lowest Y coordinate of the scanline (inclusive)
     157 * @param y1 Highest Y coordinate of the scanline (inclusive)
     158 * @param part Which part(s) of cicle to paint
     159 * @return EOK on success or an error code
     160 */
     161static errno_t ui_paint_fcircle_line(gfx_context_t *gc, gfx_coord2_t *center,
     162    gfx_coord_t x, gfx_coord_t y0, gfx_coord_t y1, ui_fcircle_part_t part)
     163{
     164        gfx_rect_t rect;
     165        gfx_rect_t trect;
     166
     167        rect.p0.x = x;
     168        rect.p0.y = y0;
     169        rect.p1.x = x + 1;
     170        rect.p1.y = y1;
     171
     172        /* Clip to upper-left/lower-right half of circle, if required */
     173
     174        if ((part & ui_fcircle_upleft) == 0) {
     175                if (rect.p0.y < -rect.p1.x)
     176                        rect.p0.y = -rect.p1.x;
     177        }
     178
     179        if ((part & ui_fcircle_lowright) == 0) {
     180                if (rect.p1.y > -rect.p1.x)
     181                        rect.p1.y = -rect.p1.x;
     182        }
     183
     184        /* If coordinates are reversed, there is nothing to do */
     185        if (rect.p1.y <= rect.p0.y)
     186                return EOK;
     187
     188        gfx_rect_translate(center, &rect, &trect);
     189
     190        return gfx_fill_rect(gc, &trect);
     191}
     192
     193/** Paint filled circle scanlines corresponding to octant point.
     194 *
     195 * Fills the four vertical scanlines lying between the eight reflections
     196 * of a circle point.
     197 *
     198 * @param gc Graphic context
     199 * @param center Coordinates of the center
     200 * @param r Radius in pixels
     201 * @param part Which part(s) of cicle to paint
     202 * @return EOK on success or an error code
     203 */
     204static int ui_paint_fcircle_point(gfx_context_t *gc, gfx_coord2_t *center,
     205    gfx_coord2_t *p, ui_fcircle_part_t part)
     206{
     207        errno_t rc;
     208
     209        rc = ui_paint_fcircle_line(gc, center, +p->x, -p->y, p->y + 1, part);
     210        if (rc != EOK)
     211                return rc;
     212        rc = ui_paint_fcircle_line(gc, center, -p->x, -p->y, p->y + 1, part);
     213        if (rc != EOK)
     214                return rc;
     215        rc = ui_paint_fcircle_line(gc, center, +p->y, -p->x, p->x + 1, part);
     216        if (rc != EOK)
     217                return rc;
     218        rc = ui_paint_fcircle_line(gc, center, -p->y, -p->x, p->x + 1, part);
     219        if (rc != EOK)
     220                return rc;
     221
     222        return EOK;
     223}
     224
     225/** Paint a filled circle.
     226 *
     227 * @param gc Graphic context
     228 * @param center Coordinates of the center
     229 * @param r Radius in pixels
     230 * @param part Which part(s) of cicle to paint
     231 * @return EOK on success or an error code
     232 */
     233errno_t ui_paint_filled_circle(gfx_context_t *gc, gfx_coord2_t *center,
     234    gfx_coord_t r, ui_fcircle_part_t part)
     235{
     236        gfx_coord2_t p;
     237        gfx_coord_t f;
     238        errno_t rc;
     239
     240        /* Run through one octant using circle midpoint algorithm */
     241
     242        p.x = r;
     243        p.y = 0;
     244        f = 1 - r;
     245
     246        rc = ui_paint_fcircle_point(gc, center, &p, part);
     247        if (rc != EOK)
     248                return rc;
     249
     250        while (p.x > p.y) {
     251                if (f < 0) {
     252                        f = f + 2 * p.y + 3;
     253                } else {
     254                        f = f + 2 * (p.y - p.x) + 5;
     255                        --p.x;
     256                }
     257                ++p.y;
     258
     259                rc = ui_paint_fcircle_point(gc, center, &p, part);
     260                if (rc != EOK)
     261                        return rc;
     262        }
     263
     264        return EOK;
     265}
     266
    151267/** @}
    152268 */
  • uspace/lib/ui/src/resource.c

    rd70dc1c4 r7020d1f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    130130                goto error;
    131131
    132         rc = gfx_color_new_rgb_i16(0, 0, 0, &wnd_frame_sh_color);
     132        rc = gfx_color_new_rgb_i16(0x4444, 0x4444, 0x4444, &wnd_frame_sh_color);
    133133        if (rc != EOK)
    134134                goto error;
  • uspace/lib/ui/test/main.c

    rd70dc1c4 r7020d1f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3939PCUT_IMPORT(paint);
    4040PCUT_IMPORT(pbutton);
     41PCUT_IMPORT(rbutton);
    4142PCUT_IMPORT(resource);
    4243PCUT_IMPORT(ui);
Note: See TracChangeset for help on using the changeset viewer.