Changeset 8ef48ece in mainline


Ignore:
Timestamp:
2020-10-15T22:12:22Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
de9992c
Parents:
faca61b8
Message:

Generating button activation event

Location:
uspace
Files:
6 edited

Legend:

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

    rfaca61b8 r8ef48ece  
    5454};
    5555
     56static void pb_clicked(ui_pbutton_t *, void *);
     57
     58static ui_pbutton_cb_t pbutton_cb = {
     59        .clicked = pb_clicked
     60};
     61
    5662static bool quit = false;
    5763
     
    8490        ui_pbutton_pos_event(demo->pb1, event);
    8591        ui_pbutton_pos_event(demo->pb2, event);
     92}
     93
     94/** Push button was clicked.
     95 *
     96 * @param pbutton Push button
     97 * @param arg Argument (demo)
     98 */
     99static void pb_clicked(ui_pbutton_t *pbutton, void *arg)
     100{
     101        ui_demo_t *demo = (ui_demo_t *) arg;
     102
     103        if (pbutton == demo->pb1) {
     104                printf("Clicked 'Confirm' button\n");
     105        } else {
     106                printf("Clicked 'Cancel' button\n");
     107        }
    86108}
    87109
     
    140162        }
    141163
     164        ui_pbutton_set_cb(demo.pb1, &pbutton_cb, (void *) &demo);
     165
    142166        rect.p0.x = 20;
    143167        rect.p0.y = 50;
     
    153177                return rc;
    154178        }
     179
     180        ui_pbutton_set_cb(demo.pb2, &pbutton_cb, (void *) &demo);
    155181
    156182        rect.p0.x = 120;
  • uspace/lib/ui/include/types/ui/pbutton.h

    rfaca61b8 r8ef48ece  
    4040typedef struct ui_pbutton ui_pbutton_t;
    4141
     42/** Push button callbacks */
     43typedef struct ui_pbutton_cb {
     44        void (*clicked)(ui_pbutton_t *, void *);
     45} ui_pbutton_cb_t;
     46
    4247#endif
    4348
  • uspace/lib/ui/include/ui/pbutton.h

    rfaca61b8 r8ef48ece  
    4747    ui_pbutton_t **);
    4848extern void ui_pbutton_destroy(ui_pbutton_t *);
     49extern void ui_pbutton_set_cb(ui_pbutton_t *, ui_pbutton_cb_t *, void *);
    4950extern void ui_pbutton_set_rect(ui_pbutton_t *, gfx_rect_t *);
    5051extern void ui_pbutton_set_default(ui_pbutton_t *, bool);
     
    5253extern void ui_pbutton_press(ui_pbutton_t *);
    5354extern void ui_pbutton_release(ui_pbutton_t *);
     55extern void ui_pbutton_enter(ui_pbutton_t *);
     56extern void ui_pbutton_leave(ui_pbutton_t *);
     57extern void ui_pbutton_clicked(ui_pbutton_t *);
    5458extern void ui_pbutton_pos_event(ui_pbutton_t *, pos_event_t *);
    5559
  • uspace/lib/ui/private/pbutton.h

    rfaca61b8 r8ef48ece  
    4949        /** UI resource */
    5050        struct ui_resource *res;
     51        /** Callbacks */
     52        struct ui_pbutton_cb *cb;
     53        /** Callback argument */
     54        void *arg;
    5155        /** Push button rectangle */
    5256        gfx_rect_t rect;
     
    5761        /** Button is currently held down */
    5862        bool held;
     63        /** Pointer is currently inside */
     64        bool inside;
    5965};
    6066
  • uspace/lib/ui/src/pbutton.c

    rfaca61b8 r8ef48ece  
    9191}
    9292
     93/** Set push button callbacks.
     94 *
     95 * @param pbutton Push button
     96 * @param cb Push button callbacks
     97 * @param arg Callback argument
     98 */
     99void ui_pbutton_set_cb(ui_pbutton_t *pbutton, ui_pbutton_cb_t *cb, void *arg)
     100{
     101        pbutton->cb = cb;
     102        pbutton->arg = arg;
     103}
     104
    93105/** Set button rectangle.
    94106 *
     
    314326        gfx_rect_t rect;
    315327        gfx_coord_t thickness;
     328        bool depressed;
    316329        errno_t rc;
    317330
    318331        thickness = pbutton->isdefault ? 2 : 1;
     332        depressed = pbutton->held && pbutton->inside;
    319333
    320334        rect.p0.x = pbutton->rect.p0.x + thickness;
     
    350364        pos.y = (rect.p0.y + rect.p1.y) / 2;
    351365
    352         if (pbutton->held) {
     366        if (depressed) {
    353367                pos.x += ui_pb_press_dx;
    354368                pos.y += ui_pb_press_dy;
     
    370384                goto error;
    371385
    372         if (pbutton->held) {
     386        if (depressed) {
    373387                rc = ui_pbutton_paint_inset(pbutton, &rect);
    374388                if (rc != EOK)
     
    389403/** Press down button.
    390404 *
    391  * This does not automatically repaint the button.
    392  *
    393405 * @param pbutton Push button
    394406 */
    395407void ui_pbutton_press(ui_pbutton_t *pbutton)
    396408{
     409        if (pbutton->held)
     410                return;
     411
     412        pbutton->inside = true;
    397413        pbutton->held = true;
     414        (void) ui_pbutton_paint(pbutton);
    398415}
    399416
    400417/** Release button.
    401418 *
    402  * This does not automatically repaint the button.
    403  *
    404419 * @param pbutton Push button
    405420 */
    406421void ui_pbutton_release(ui_pbutton_t *pbutton)
    407422{
     423        if (!pbutton->held)
     424                return;
     425
    408426        pbutton->held = false;
     427
     428        if (pbutton->inside) {
     429                (void) ui_pbutton_paint(pbutton);
     430                ui_pbutton_clicked(pbutton);
     431        }
     432}
     433
     434/** Pointer entered button.
     435 *
     436 * @param pbutton Push button
     437 */
     438void ui_pbutton_enter(ui_pbutton_t *pbutton)
     439{
     440        if (pbutton->inside)
     441                return;
     442
     443        pbutton->inside = true;
     444        if (pbutton->held)
     445                (void) ui_pbutton_paint(pbutton);
     446}
     447
     448/** Pointer left button.
     449 *
     450 * @param pbutton Push button
     451 */
     452void ui_pbutton_leave(ui_pbutton_t *pbutton)
     453{
     454        if (!pbutton->inside)
     455                return;
     456
     457        pbutton->inside = false;
     458        if (pbutton->held)
     459                (void) ui_pbutton_paint(pbutton);
     460}
     461
     462/** Button was clicked.
     463 *
     464 * @param pbutton Push button
     465 */
     466void ui_pbutton_clicked(ui_pbutton_t *pbutton)
     467{
     468        if (pbutton->cb != NULL && pbutton->cb->clicked != NULL)
     469                pbutton->cb->clicked(pbutton, pbutton->arg);
    409470}
    410471
     
    417478{
    418479        gfx_coord2_t pos;
     480        bool inside;
    419481
    420482        pos.x = event->hpos;
    421483        pos.y = event->vpos;
    422484
    423         if (gfx_pix_inside_rect(&pos, &pbutton->rect)) {
    424                 if (event->type == POS_PRESS) {
     485        inside = gfx_pix_inside_rect(&pos, &pbutton->rect);
     486
     487        switch (event->type) {
     488        case POS_PRESS:
     489                if (inside)
    425490                        ui_pbutton_press(pbutton);
    426                         (void) ui_pbutton_paint(pbutton);
     491                break;
     492        case POS_RELEASE:
     493                ui_pbutton_release(pbutton);
     494                break;
     495        case POS_UPDATE:
     496                if (inside && !pbutton->inside) {
     497                        ui_pbutton_enter(pbutton);
     498                } else if (!inside && pbutton->inside) {
     499                        ui_pbutton_leave(pbutton);
    427500                }
    428         }
    429 
    430         if (event->type == POS_RELEASE && pbutton->held) {
    431                 ui_pbutton_release(pbutton);
    432                 (void) ui_pbutton_paint(pbutton);
     501                break;
    433502        }
    434503}
  • uspace/lib/ui/test/pbutton.c

    rfaca61b8 r8ef48ece  
    5757};
    5858
     59static void test_pbutton_clicked(ui_pbutton_t *, void *);
     60
     61static ui_pbutton_cb_t test_pbutton_cb = {
     62        .clicked = test_pbutton_clicked
     63};
     64
     65static ui_pbutton_cb_t dummy_pbutton_cb = {
     66};
     67
    5968typedef struct {
    6069        bool bm_created;
     
    7483} testgc_bitmap_t;
    7584
     85typedef struct {
     86        bool clicked;
     87} test_cb_resp_t;
     88
    7689/** Create and destroy button */
    7790PCUT_TEST(create_destroy)
     
    165178}
    166179
    167 /** ui_pbutton_press()/release() sets/clears internal held flag */
     180/** Test ui_pbutton_clicked() */
     181PCUT_TEST(clicked)
     182{
     183        errno_t rc;
     184        ui_pbutton_t *pbutton;
     185        test_cb_resp_t resp;
     186
     187        rc = ui_pbutton_create(NULL, "Hello", &pbutton);
     188        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     189
     190        /* Clicked with no callbacks set */
     191        ui_pbutton_clicked(pbutton);
     192
     193        /* Clicked with callback not implementing clicked */
     194        ui_pbutton_set_cb(pbutton, &dummy_pbutton_cb, NULL);
     195        ui_pbutton_clicked(pbutton);
     196
     197        /* Clicked with real callback set */
     198        resp.clicked = false;
     199        ui_pbutton_set_cb(pbutton, &test_pbutton_cb, &resp);
     200        ui_pbutton_clicked(pbutton);
     201        PCUT_ASSERT_TRUE(resp.clicked);
     202
     203        ui_pbutton_destroy(pbutton);
     204}
     205
     206/** Press and release button */
    168207PCUT_TEST(press_release)
    169208{
    170         ui_pbutton_t *pbutton;
    171         errno_t rc;
    172 
    173         rc = ui_pbutton_create(NULL, "Hello", &pbutton);
    174         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    175 
    176         PCUT_ASSERT_FALSE(pbutton->held);
     209        errno_t rc;
     210        gfx_context_t *gc = NULL;
     211        test_gc_t tgc;
     212        ui_resource_t *resource = NULL;
     213        ui_pbutton_t *pbutton;
     214        test_cb_resp_t resp;
     215
     216        memset(&tgc, 0, sizeof(tgc));
     217        rc = gfx_context_new(&ops, &tgc, &gc);
     218        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     219
     220        rc = ui_resource_create(gc, &resource);
     221        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     222        PCUT_ASSERT_NOT_NULL(resource);
     223
     224        rc = ui_pbutton_create(resource, "Hello", &pbutton);
     225        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     226
     227        resp.clicked = false;
     228        ui_pbutton_set_cb(pbutton, &test_pbutton_cb, &resp);
     229
     230        PCUT_ASSERT_FALSE(pbutton->held);
     231        PCUT_ASSERT_FALSE(pbutton->inside);
    177232
    178233        ui_pbutton_press(pbutton);
    179234        PCUT_ASSERT_TRUE(pbutton->held);
     235        PCUT_ASSERT_TRUE(pbutton->inside);
     236        PCUT_ASSERT_FALSE(resp.clicked);
    180237
    181238        ui_pbutton_release(pbutton);
    182239        PCUT_ASSERT_FALSE(pbutton->held);
    183 
    184         ui_pbutton_destroy(pbutton);
     240        PCUT_ASSERT_TRUE(pbutton->inside);
     241        PCUT_ASSERT_TRUE(resp.clicked);
     242
     243        ui_pbutton_destroy(pbutton);
     244        ui_resource_destroy(resource);
     245
     246        rc = gfx_context_delete(gc);
     247        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     248}
     249
     250/** Press, leave and release button */
     251PCUT_TEST(press_leave_release)
     252{
     253        errno_t rc;
     254        gfx_context_t *gc = NULL;
     255        test_gc_t tgc;
     256        ui_resource_t *resource = NULL;
     257        ui_pbutton_t *pbutton;
     258        test_cb_resp_t resp;
     259
     260        memset(&tgc, 0, sizeof(tgc));
     261        rc = gfx_context_new(&ops, &tgc, &gc);
     262        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     263
     264        rc = ui_resource_create(gc, &resource);
     265        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     266        PCUT_ASSERT_NOT_NULL(resource);
     267
     268        rc = ui_pbutton_create(resource, "Hello", &pbutton);
     269        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     270
     271        resp.clicked = false;
     272        ui_pbutton_set_cb(pbutton, &test_pbutton_cb, &resp);
     273
     274        PCUT_ASSERT_FALSE(pbutton->held);
     275        PCUT_ASSERT_FALSE(pbutton->inside);
     276
     277        ui_pbutton_press(pbutton);
     278        PCUT_ASSERT_TRUE(pbutton->held);
     279        PCUT_ASSERT_TRUE(pbutton->inside);
     280        PCUT_ASSERT_FALSE(resp.clicked);
     281
     282        ui_pbutton_leave(pbutton);
     283        PCUT_ASSERT_TRUE(pbutton->held);
     284        PCUT_ASSERT_FALSE(pbutton->inside);
     285        PCUT_ASSERT_FALSE(resp.clicked);
     286
     287        ui_pbutton_release(pbutton);
     288        PCUT_ASSERT_FALSE(pbutton->held);
     289        PCUT_ASSERT_FALSE(pbutton->inside);
     290        PCUT_ASSERT_FALSE(resp.clicked);
     291
     292        ui_pbutton_destroy(pbutton);
     293        ui_resource_destroy(resource);
     294
     295        rc = gfx_context_delete(gc);
     296        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     297}
     298
     299/** Press, leave, enter and release button */
     300PCUT_TEST(press_leave_enter_release)
     301{
     302        errno_t rc;
     303        gfx_context_t *gc = NULL;
     304        test_gc_t tgc;
     305        ui_resource_t *resource = NULL;
     306        ui_pbutton_t *pbutton;
     307        test_cb_resp_t resp;
     308
     309        memset(&tgc, 0, sizeof(tgc));
     310        rc = gfx_context_new(&ops, &tgc, &gc);
     311        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     312
     313        rc = ui_resource_create(gc, &resource);
     314        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     315        PCUT_ASSERT_NOT_NULL(resource);
     316
     317        rc = ui_pbutton_create(resource, "Hello", &pbutton);
     318        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     319
     320        resp.clicked = false;
     321        ui_pbutton_set_cb(pbutton, &test_pbutton_cb, &resp);
     322
     323        PCUT_ASSERT_FALSE(pbutton->held);
     324        PCUT_ASSERT_FALSE(pbutton->inside);
     325
     326        ui_pbutton_press(pbutton);
     327        PCUT_ASSERT_TRUE(pbutton->held);
     328        PCUT_ASSERT_TRUE(pbutton->inside);
     329        PCUT_ASSERT_FALSE(resp.clicked);
     330
     331        ui_pbutton_leave(pbutton);
     332        PCUT_ASSERT_TRUE(pbutton->held);
     333        PCUT_ASSERT_FALSE(pbutton->inside);
     334        PCUT_ASSERT_FALSE(resp.clicked);
     335
     336        ui_pbutton_enter(pbutton);
     337        PCUT_ASSERT_TRUE(pbutton->held);
     338        PCUT_ASSERT_TRUE(pbutton->inside);
     339        PCUT_ASSERT_FALSE(resp.clicked);
     340
     341        ui_pbutton_release(pbutton);
     342        PCUT_ASSERT_FALSE(pbutton->held);
     343        PCUT_ASSERT_TRUE(pbutton->inside);
     344        PCUT_ASSERT_TRUE(resp.clicked);
     345
     346        ui_pbutton_destroy(pbutton);
     347        ui_resource_destroy(resource);
     348
     349        rc = gfx_context_delete(gc);
     350        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    185351}
    186352
     
    188354PCUT_TEST(pos_event_press_release)
    189355{
     356        errno_t rc;
     357        gfx_context_t *gc = NULL;
     358        test_gc_t tgc;
     359        ui_resource_t *resource = NULL;
    190360        ui_pbutton_t *pbutton;
    191361        pos_event_t event;
    192362        gfx_rect_t rect;
    193         errno_t rc;
    194 
    195         rc = ui_pbutton_create(NULL, "Hello", &pbutton);
     363
     364        memset(&tgc, 0, sizeof(tgc));
     365        rc = gfx_context_new(&ops, &tgc, &gc);
     366        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     367
     368        rc = ui_resource_create(gc, &resource);
     369        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     370        PCUT_ASSERT_NOT_NULL(resource);
     371
     372        rc = ui_pbutton_create(resource, "Hello", &pbutton);
    196373        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    197374
     
    226403
    227404        ui_pbutton_destroy(pbutton);
     405        ui_resource_destroy(resource);
     406
     407        rc = gfx_context_delete(gc);
     408        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     409}
     410
     411/** ui_pos_event() correctly translates POS_UPDATE to enter/leave */
     412PCUT_TEST(pos_event_enter_leave)
     413{
     414        errno_t rc;
     415        gfx_context_t *gc = NULL;
     416        test_gc_t tgc;
     417        ui_resource_t *resource = NULL;
     418        ui_pbutton_t *pbutton;
     419        pos_event_t event;
     420        gfx_rect_t rect;
     421
     422        memset(&tgc, 0, sizeof(tgc));
     423        rc = gfx_context_new(&ops, &tgc, &gc);
     424        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     425
     426        rc = ui_resource_create(gc, &resource);
     427        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     428        PCUT_ASSERT_NOT_NULL(resource);
     429
     430        rc = ui_pbutton_create(resource, "Hello", &pbutton);
     431        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     432
     433        PCUT_ASSERT_FALSE(pbutton->inside);
     434
     435        rect.p0.x = 10;
     436        rect.p0.y = 20;
     437        rect.p1.x = 30;
     438        rect.p1.y = 40;
     439        ui_pbutton_set_rect(pbutton, &rect);
     440
     441        /* Moving outside does nothing */
     442        event.type = POS_UPDATE;
     443        event.hpos = 9;
     444        event.vpos = 20;
     445        ui_pbutton_pos_event(pbutton, &event);
     446        PCUT_ASSERT_FALSE(pbutton->inside);
     447
     448        /* Moving inside sets inside flag */
     449        event.type = POS_UPDATE;
     450        event.hpos = 10;
     451        event.vpos = 20;
     452        ui_pbutton_pos_event(pbutton, &event);
     453        PCUT_ASSERT_TRUE(pbutton->inside);
     454
     455        /* Moving outside clears inside flag */
     456        event.type = POS_UPDATE;
     457        event.hpos = 9;
     458        event.vpos = 20;
     459        ui_pbutton_pos_event(pbutton, &event);
     460        PCUT_ASSERT_FALSE(pbutton->inside);
     461
     462        ui_pbutton_destroy(pbutton);
     463        ui_resource_destroy(resource);
     464
     465        rc = gfx_context_delete(gc);
     466        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    228467}
    229468
     
    304543}
    305544
     545static void test_pbutton_clicked(ui_pbutton_t *pbutton, void *arg)
     546{
     547        test_cb_resp_t *resp = (test_cb_resp_t *) arg;
     548
     549        resp->clicked = true;
     550}
     551
    306552PCUT_EXPORT(pbutton);
Note: See TracChangeset for help on using the changeset viewer.