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

Changeset 7481ee19 in mainline for uspace/lib/ui/src/entry.c


Ignore:
Timestamp:
2021-06-23T08:15:00Z (5 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
a977e37
Parents:
034ce6bb
git-author:
Jiri Svoboda <jiri@…> (2021-06-22 17:14:40)
git-committer:
Jiri Svoboda <jiri@…> (2021-06-23 08:15:00)
Message:

Basic editable text entry

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ui/src/entry.c

    r034ce6bb r7481ee19  
    5353static void ui_entry_ctl_destroy(void *);
    5454static errno_t ui_entry_ctl_paint(void *);
     55static ui_evclaim_t ui_entry_ctl_kbd_event(void *, kbd_event_t *);
    5556static ui_evclaim_t ui_entry_ctl_pos_event(void *, pos_event_t *);
    5657
     
    6667        .destroy = ui_entry_ctl_destroy,
    6768        .paint = ui_entry_ctl_paint,
     69        .kbd_event = ui_entry_ctl_kbd_event,
    6870        .pos_event = ui_entry_ctl_pos_event
    6971};
     
    148150}
    149151
     152/** Set text entry read-only flag.
     153 *
     154 * @param entry Text entry
     155 * @param read_only True iff entry is to be read-only.
     156 */
     157void ui_entry_set_read_only(ui_entry_t *entry, bool read_only)
     158{
     159        entry->read_only = read_only;
     160}
     161
    150162/** Set entry text.
    151163 *
     
    180192        gfx_coord_t hpad;
    181193        gfx_coord_t vpad;
     194        gfx_coord_t width;
    182195        gfx_rect_t inside;
    183196        errno_t rc;
     
    212225                goto error;
    213226
     227        width = gfx_text_width(res->font, entry->text);
     228
    214229        switch (entry->halign) {
    215230        case gfx_halign_left:
     
    218233                break;
    219234        case gfx_halign_center:
    220                 pos.x = (inside.p0.x + inside.p1.x) / 2;
     235                pos.x = (inside.p0.x + inside.p1.x) / 2 - width / 2;
    221236                break;
    222237        case gfx_halign_right:
    223                 pos.x = inside.p1.x - hpad - 1;
     238                pos.x = inside.p1.x - hpad - 1 - width;
    224239                break;
    225240        }
     
    229244        gfx_text_fmt_init(&fmt);
    230245        fmt.color = res->entry_fg_color;
    231         fmt.halign = entry->halign;
     246        fmt.halign = gfx_halign_left;
    232247        fmt.valign = gfx_valign_top;
    233248
     249        rc = gfx_set_clip_rect(res->gc, &inside);
     250        if (rc != EOK)
     251                goto error;
     252
    234253        rc = gfx_puttext(res->font, &pos, &fmt, entry->text);
     254        if (rc != EOK) {
     255                (void) gfx_set_clip_rect(res->gc, NULL);
     256                goto error;
     257        }
     258
     259        if (entry->active) {
     260                /* Cursor */
     261                pos.x += width;
     262
     263                rc = gfx_puttext(res->font, &pos, &fmt, "_");
     264                if (rc != EOK) {
     265                        (void) gfx_set_clip_rect(res->gc, NULL);
     266                        goto error;
     267                }
     268        }
     269
     270        rc = gfx_set_clip_rect(res->gc, NULL);
    235271        if (rc != EOK)
    236272                goto error;
     
    268304}
    269305
    270 /** Handle text entry control position event.
    271  *
    272  * @param arg Argument (ui_entry_t *)
     306/** Insert string at cursor position.
     307 *
     308 * @param entry Text entry
     309 * @param str String
     310 * @return EOK on success, ENOMEM if out of memory
     311 */
     312errno_t ui_entry_insert_str(ui_entry_t *entry, const char *str)
     313{
     314        char *newtext;
     315        char *oldtext;
     316        int rc;
     317
     318        rc = asprintf(&newtext, "%s%s", entry->text, str);
     319        if (rc < 0)
     320                return ENOMEM;
     321
     322        oldtext = entry->text;
     323        entry->text = newtext;
     324        free(oldtext);
     325        ui_entry_paint(entry);
     326
     327        return EOK;
     328}
     329
     330/** Delete character before cursor.
     331 *
     332 * @param entry Text entry
     333 */
     334void ui_entry_backspace(ui_entry_t *entry)
     335{
     336        size_t off;
     337
     338        off = str_size(entry->text);
     339        (void) str_decode_reverse(entry->text, &off,
     340            str_size(entry->text));
     341        entry->text[off] = '\0';
     342        ui_entry_paint(entry);
     343}
     344
     345/** Handle text entry key press without modifiers.
     346 *
     347 * @param entry Text entry
     348 * @param kbd_event Keyboard event
     349 * @return @c ui_claimed iff the event is claimed
     350 */
     351ui_evclaim_t ui_entry_key_press_unmod(ui_entry_t *entry, kbd_event_t *event)
     352{
     353        assert(event->type == KEY_PRESS);
     354
     355        if (event->key == KC_BACKSPACE)
     356                ui_entry_backspace(entry);
     357
     358        if (event->key == KC_ESCAPE) {
     359                entry->active = false;
     360                (void) ui_entry_paint(entry);
     361        }
     362
     363        return ui_claimed;
     364}
     365
     366/** Handle text entry keyboard event.
     367 *
     368 * @param entry Text entry
     369 * @param kbd_event Keyboard event
     370 * @return @c ui_claimed iff the event is claimed
     371 */
     372ui_evclaim_t ui_entry_kbd_event(ui_entry_t *entry, kbd_event_t *event)
     373{
     374        char buf[STR_BOUNDS(1) + 1];
     375        size_t off;
     376        errno_t rc;
     377
     378        if (!entry->active)
     379                return ui_unclaimed;
     380
     381        if (event->type == KEY_PRESS && event->c >= ' ') {
     382                off = 0;
     383                rc = chr_encode(event->c, buf, &off, sizeof(buf));
     384                if (rc == EOK) {
     385                        buf[off] = '\0';
     386                        (void) ui_entry_insert_str(entry, buf);
     387                }
     388        }
     389
     390        if (event->type == KEY_PRESS &&
     391            (event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0)
     392                return ui_entry_key_press_unmod(entry, event);
     393
     394        return ui_claimed;
     395}
     396
     397/** Handle text entry position event.
     398 *
     399 * @param entry Text entry
    273400 * @param pos_event Position event
    274401 * @return @c ui_claimed iff the event is claimed
    275402 */
    276 ui_evclaim_t ui_entry_ctl_pos_event(void *arg, pos_event_t *event)
    277 {
    278         ui_entry_t *entry = (ui_entry_t *) arg;
     403ui_evclaim_t ui_entry_pos_event(ui_entry_t *entry, pos_event_t *event)
     404{
    279405        gfx_coord2_t pos;
     406
     407        if (entry->read_only)
     408                return ui_unclaimed;
    280409
    281410        if (event->type == POS_UPDATE) {
     
    298427        }
    299428
     429        if (event->type == POS_PRESS) {
     430                pos.x = event->hpos;
     431                pos.y = event->vpos;
     432
     433                if (gfx_pix_inside_rect(&pos, &entry->rect)) {
     434                        if (!entry->active) {
     435                                entry->active = true;
     436                                (void) ui_entry_paint(entry);
     437                        }
     438
     439                        return ui_claimed;
     440                } else {
     441                        if (entry->active) {
     442                                entry->active = false;
     443                                (void) ui_entry_paint(entry);
     444                        }
     445                }
     446        }
     447
    300448        return ui_unclaimed;
    301449}
    302450
     451/** Handle text entry control keyboard event.
     452 *
     453 * @param arg Argument (ui_entry_t *)
     454 * @param kbd_event Keyboard event
     455 * @return @c ui_claimed iff the event is claimed
     456 */
     457static ui_evclaim_t ui_entry_ctl_kbd_event(void *arg, kbd_event_t *event)
     458{
     459        ui_entry_t *entry = (ui_entry_t *) arg;
     460
     461        return ui_entry_kbd_event(entry, event);
     462}
     463
     464/** Handle text entry control position event.
     465 *
     466 * @param arg Argument (ui_entry_t *)
     467 * @param pos_event Position event
     468 * @return @c ui_claimed iff the event is claimed
     469 */
     470static ui_evclaim_t ui_entry_ctl_pos_event(void *arg, pos_event_t *event)
     471{
     472        ui_entry_t *entry = (ui_entry_t *) arg;
     473
     474        return ui_entry_pos_event(entry, event);
     475}
     476
    303477/** @}
    304478 */
Note: See TracChangeset for help on using the changeset viewer.