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

Changeset 9eb8d12 in mainline


Ignore:
Timestamp:
2021-07-19T22:35:19Z (3 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
c9722c1
Parents:
ead72f2
Message:

Entry text selection (using keyboard)

Text can be selected with movement keys while holding down Shift.
Selection can be deleted by pressing Backspace, Delete or typing
in replacement text.

Location:
uspace/lib
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gfxfont/include/gfx/text.h

    read72f2 r9eb8d12  
    5050extern size_t gfx_text_find_pos(gfx_font_t *, gfx_coord2_t *, gfx_text_fmt_t *,
    5151    const char *, gfx_coord2_t *);
     52extern void gfx_text_cont(gfx_font_t *, gfx_coord2_t *, gfx_text_fmt_t *,
     53    const char *, gfx_coord2_t *, gfx_text_fmt_t *);
     54extern void gfx_text_rect(gfx_font_t *, gfx_coord2_t *, gfx_text_fmt_t *,
     55    const char *, gfx_rect_t *);
    5256
    5357#endif
  • uspace/lib/gfxfont/src/text.c

    read72f2 r9eb8d12  
    174174 * @param str String
    175175 * @param spos Place to store starting position
    176  * @return EOK on success or an error code
    177176 */
    178177void gfx_text_start_pos(gfx_font_t *font, gfx_coord2_t *pos,
     
    333332}
    334333
     334/** Get text continuation parameters.
     335 *
     336 * Return the anchor position and format needed to continue printing
     337 * text after the specified string. It is allowed for the sources
     338 * (@a pos, @a fmt) and destinations (@a cpos, @a cfmt) to point
     339 * to the same objects, respectively.
     340 *
     341 * @param font Font
     342 * @param pos Anchor position
     343 * @param fmt Text formatting
     344 * @param str String
     345 * @param cpos Place to store anchor position for continuation
     346 * @param cfmt Place to store format for continuation
     347 */
     348void gfx_text_cont(gfx_font_t *font, gfx_coord2_t *pos,
     349    gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *cpos,
     350    gfx_text_fmt_t *cfmt)
     351{
     352        gfx_coord2_t spos;
     353        gfx_text_fmt_t tfmt;
     354
     355        /* Continuation should start where the current string ends */
     356        gfx_text_start_pos(font, pos, fmt, str, &spos);
     357        cpos->x = spos.x + gfx_text_width(font, str);
     358        cpos->y = spos.y;
     359
     360        /*
     361         * Formatting is the same, except the text should be aligned
     362         * so that it starts at the anchor point.
     363         */
     364        tfmt = *fmt;
     365        tfmt.halign = gfx_halign_left;
     366        tfmt.valign = gfx_valign_baseline;
     367
     368        *cfmt = tfmt;
     369}
     370
     371/** Get text bounding rectangle.
     372 *
     373 * @param font Font
     374 * @param pos Anchor position
     375 * @param fmt Text formatting
     376 * @param str String
     377 * @param rect Place to store bounding rectangle
     378 */
     379void gfx_text_rect(gfx_font_t *font, gfx_coord2_t *pos,
     380    gfx_text_fmt_t *fmt, const char *str, gfx_rect_t *rect)
     381{
     382        gfx_coord2_t spos;
     383
     384        gfx_text_start_pos(font, pos, fmt, str, &spos);
     385
     386        rect->p0.x = spos.x;
     387        rect->p0.y = spos.y - font->metrics.ascent;
     388        rect->p1.x = spos.x + gfx_text_width(font, str);
     389        rect->p1.y = spos.y + font->metrics.descent + 1;
     390}
     391
    335392/** @}
    336393 */
  • uspace/lib/gfxfont/test/text.c

    read72f2 r9eb8d12  
    356356}
    357357
     358/** gfx_text_cont() produces correct continuation parameters */
     359PCUT_TEST(text_cont)
     360{
     361        gfx_typeface_t *tface;
     362        gfx_font_t *font;
     363        gfx_context_t *gc;
     364        gfx_color_t *color;
     365        test_gc_t tgc;
     366        gfx_text_fmt_t fmt;
     367        gfx_coord2_t anchor;
     368        gfx_coord2_t cpos;
     369        gfx_text_fmt_t cfmt;
     370        errno_t rc;
     371
     372        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
     373        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     374
     375        rc = gfx_typeface_create(gc, &tface);
     376        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     377
     378        rc = gfx_font_create_textmode(tface, &font);
     379        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     380
     381        rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
     382        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     383
     384        anchor.x = 10;
     385        anchor.y = 20;
     386        gfx_text_fmt_init(&fmt);
     387        fmt.color = color;
     388
     389        gfx_text_cont(font, &anchor, &fmt, "Abc", &cpos, &cfmt);
     390
     391        PCUT_ASSERT_INT_EQUALS(13, cpos.x);
     392        PCUT_ASSERT_INT_EQUALS(20, cpos.y);
     393        PCUT_ASSERT_EQUALS(fmt.color, cfmt.color);
     394        PCUT_ASSERT_EQUALS(gfx_halign_left, cfmt.halign);
     395        PCUT_ASSERT_EQUALS(gfx_valign_baseline, cfmt.valign);
     396
     397        gfx_font_close(font);
     398        gfx_typeface_destroy(tface);
     399        gfx_color_delete(color);
     400
     401        rc = gfx_context_delete(gc);
     402        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     403}
     404
     405/** gfx_text_rect() computes bounding rectangle */
     406PCUT_TEST(text_rect)
     407{
     408        gfx_typeface_t *tface;
     409        gfx_font_t *font;
     410        gfx_context_t *gc;
     411        gfx_color_t *color;
     412        test_gc_t tgc;
     413        gfx_text_fmt_t fmt;
     414        gfx_coord2_t anchor;
     415        gfx_rect_t rect;
     416        errno_t rc;
     417
     418        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
     419        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     420
     421        rc = gfx_typeface_create(gc, &tface);
     422        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     423
     424        rc = gfx_font_create_textmode(tface, &font);
     425        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     426
     427        rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
     428        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     429
     430        anchor.x = 10;
     431        anchor.y = 20;
     432        gfx_text_fmt_init(&fmt);
     433        fmt.color = color;
     434
     435        gfx_text_rect(font, &anchor, &fmt, "Abc", &rect);
     436
     437        PCUT_ASSERT_INT_EQUALS(10, rect.p0.x);
     438        PCUT_ASSERT_INT_EQUALS(20, rect.p0.y);
     439        PCUT_ASSERT_INT_EQUALS(13, rect.p1.x);
     440        PCUT_ASSERT_INT_EQUALS(21, rect.p1.y);
     441
     442        gfx_font_close(font);
     443        gfx_typeface_destroy(tface);
     444        gfx_color_delete(color);
     445
     446        rc = gfx_context_delete(gc);
     447        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     448}
     449
    358450static errno_t testgc_set_clip_rect(void *arg, gfx_rect_t *rect)
    359451{
  • uspace/lib/ui/include/ui/entry.h

    read72f2 r9eb8d12  
    5555extern void ui_entry_backspace(ui_entry_t *);
    5656extern void ui_entry_delete(ui_entry_t *);
    57 extern void ui_entry_seek_start(ui_entry_t *);
    58 extern void ui_entry_seek_end(ui_entry_t *);
    59 extern void ui_entry_seek_prev_char(ui_entry_t *);
    60 extern void ui_entry_seek_next_char(ui_entry_t *);
     57extern void ui_entry_seek_start(ui_entry_t *, bool);
     58extern void ui_entry_seek_end(ui_entry_t *, bool);
     59extern void ui_entry_seek_prev_char(ui_entry_t *, bool);
     60extern void ui_entry_seek_next_char(ui_entry_t *, bool);
    6161extern ui_evclaim_t ui_entry_kbd_event(ui_entry_t *, kbd_event_t *);
    6262extern ui_evclaim_t ui_entry_pos_event(ui_entry_t *, pos_event_t *);
  • uspace/lib/ui/private/entry.h

    read72f2 r9eb8d12  
    6060        /** Cursor position in the text (offset in bytes) */
    6161        unsigned pos;
     62        /** Selection start position in text (offset in bytes) */
     63        unsigned sel_start;
    6264        /** Pointer is currently inside */
    6365        bool pointer_inside;
     
    7880
    7981extern errno_t ui_entry_insert_str(ui_entry_t *, const char *);
     82extern ui_evclaim_t ui_entry_key_press_shift(ui_entry_t *, kbd_event_t *);
    8083extern ui_evclaim_t ui_entry_key_press_unmod(ui_entry_t *, kbd_event_t *);
    8184extern void ui_entry_get_geom(ui_entry_t *, ui_entry_geom_t *);
    8285extern size_t ui_entry_find_pos(ui_entry_t *, gfx_coord2_t *);
     86extern void ui_entry_delete_sel(ui_entry_t *);
    8387extern void ui_entry_activate(ui_entry_t *);
    8488extern void ui_entry_deactivate(ui_entry_t *);
  • uspace/lib/ui/src/entry.c

    read72f2 r9eb8d12  
    4242#include <gfx/render.h>
    4343#include <gfx/text.h>
     44#include <macros.h>
    4445#include <stdlib.h>
    4546#include <str.h>
     
    6364        ui_entry_vpad_text = 0,
    6465        ui_entry_cursor_overshoot = 1,
    65         ui_entry_cursor_width = 2
     66        ui_entry_cursor_width = 2,
     67        ui_entry_sel_hpad = 0,
     68        ui_entry_sel_vpad = 2
    6669};
    6770
     
    181184        entry->text = tcopy;
    182185        entry->pos = str_size(text);
     186        entry->sel_start = entry->pos;
    183187
    184188        return EOK;
     
    259263        gfx_text_fmt_t fmt;
    260264        gfx_coord2_t pos;
     265        gfx_text_fmt_t cfmt;
     266        gfx_coord2_t cpos;
    261267        gfx_rect_t inside;
     268        unsigned off1, off2;
     269        gfx_rect_t sel;
     270        char c;
    262271        errno_t rc;
    263272
     
    296305                goto error;
    297306
     307        off1 = min(entry->pos, entry->sel_start);
     308        off2 = max(entry->pos, entry->sel_start);
     309
     310        /* Render initial segment before start of selection */
     311        c = entry->text[off1];
     312        entry->text[off1] = '\0';
     313
    298314        rc = gfx_puttext(res->font, &pos, &fmt, entry->text);
     315        if (rc != EOK) {
     316                (void) gfx_set_clip_rect(res->gc, NULL);
     317                goto error;
     318        }
     319
     320        gfx_text_cont(res->font, &pos, &fmt, entry->text, &cpos, &cfmt);
     321        entry->text[off1] = c;
     322
     323        /* Render selected text */
     324
     325        if (off1 != off2) {
     326                c = entry->text[off2];
     327                entry->text[off2] = '\0';
     328                cfmt.color = res->entry_bg_color;
     329
     330                gfx_text_rect(res->font, &cpos, &cfmt, entry->text + off1, &sel);
     331                sel.p0.x -= ui_entry_sel_hpad;
     332                sel.p0.y -= ui_entry_sel_vpad;
     333                sel.p1.x += ui_entry_sel_hpad;
     334                sel.p1.y += ui_entry_sel_vpad;
     335
     336                rc = gfx_set_color(res->gc, res->entry_fg_color);
     337                if (rc != EOK)
     338                        goto error;
     339
     340                rc = gfx_fill_rect(res->gc, &sel);
     341                if (rc != EOK)
     342                        goto error;
     343
     344                rc = gfx_puttext(res->font, &cpos, &cfmt, entry->text + off1);
     345                if (rc != EOK) {
     346                        (void) gfx_set_clip_rect(res->gc, NULL);
     347                        goto error;
     348                }
     349
     350                gfx_text_cont(res->font, &cpos, &cfmt, entry->text + off1,
     351                    &cpos, &cfmt);
     352
     353                entry->text[off2] = c;
     354        }
     355
     356        /* Render trailing, non-selected text */
     357        cfmt.color = res->entry_fg_color;
     358
     359        rc = gfx_puttext(res->font, &cpos, &cfmt, entry->text + off2);
    299360        if (rc != EOK) {
    300361                (void) gfx_set_clip_rect(res->gc, NULL);
     
    373434}
    374435
     436/** Delete selected text.
     437 *
     438 * @param entry Text entry
     439 */
     440void ui_entry_delete_sel(ui_entry_t *entry)
     441{
     442        size_t off1;
     443        size_t off2;
     444
     445        off1 = min(entry->sel_start, entry->pos);
     446        off2 = max(entry->sel_start, entry->pos);
     447
     448        memmove(entry->text + off1, entry->text + off2,
     449            str_size(entry->text + off2) + 1);
     450
     451        entry->pos = off1;
     452        entry->sel_start = off1;
     453        ui_entry_paint(entry);
     454}
     455
    375456/** Insert string at cursor position.
    376457 *
     
    387468        int rc;
    388469
     470        /* Do we have a selection? */
     471        if (entry->sel_start != entry->pos)
     472                ui_entry_delete_sel(entry);
     473
    389474        tmp = entry->text[entry->pos];
    390475        entry->text[entry->pos] = '\0';
     
    407492        free(ltext);
    408493
     494        entry->sel_start = entry->pos;
    409495        ui_entry_paint(entry);
    410496
     
    419505{
    420506        size_t off;
     507
     508        /* Do we have a selection? */
     509        if (entry->sel_start != entry->pos) {
     510                ui_entry_delete_sel(entry);
     511                return;
     512        }
    421513
    422514        if (entry->pos == 0)
     
    431523            str_size(entry->text + entry->pos) + 1);
    432524        entry->pos = off;
     525        entry->sel_start = off;
    433526
    434527        ui_entry_paint(entry);
     
    443536        size_t off;
    444537
    445         /* Find offset where character after cursor end */
     538        /* Do we have a selection? */
     539        if (entry->sel_start != entry->pos) {
     540                ui_entry_delete_sel(entry);
     541                return;
     542        }
     543
     544        /* Find offset where character after cursor ends */
    446545        off = entry->pos;
    447546        (void) str_decode(entry->text, &off,
     
    478577
    479578        case KC_HOME:
    480                 ui_entry_seek_start(entry);
     579                ui_entry_seek_start(entry, false);
    481580                break;
    482581
    483582        case KC_END:
    484                 ui_entry_seek_end(entry);
     583                ui_entry_seek_end(entry, false);
    485584                break;
    486585
    487586        case KC_LEFT:
    488                 ui_entry_seek_prev_char(entry);
     587                ui_entry_seek_prev_char(entry, false);
    489588                break;
    490589
    491590        case KC_RIGHT:
    492                 ui_entry_seek_next_char(entry);
     591                ui_entry_seek_next_char(entry, false);
     592                break;
     593
     594        default:
     595                break;
     596        }
     597
     598        return ui_claimed;
     599}
     600
     601/** Handle text entry key press with shift modifier.
     602 *
     603 * @param entry Text entry
     604 * @param kbd_event Keyboard event
     605 * @return @c ui_claimed iff the event is claimed
     606 */
     607ui_evclaim_t ui_entry_key_press_shift(ui_entry_t *entry, kbd_event_t *event)
     608{
     609        assert(event->type == KEY_PRESS);
     610
     611        switch (event->key) {
     612        case KC_HOME:
     613                ui_entry_seek_start(entry, true);
     614                break;
     615
     616        case KC_END:
     617                ui_entry_seek_end(entry, true);
     618                break;
     619
     620        case KC_LEFT:
     621                ui_entry_seek_prev_char(entry, true);
     622                break;
     623
     624        case KC_RIGHT:
     625                ui_entry_seek_next_char(entry, true);
    493626                break;
    494627
     
    527660            (event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0)
    528661                return ui_entry_key_press_unmod(entry, event);
     662
     663        if (event->type == KEY_PRESS &&
     664            (event->mods & KM_SHIFT) != 0 &&
     665            (event->mods & (KM_CTRL | KM_ALT)) == 0)
     666                return ui_entry_key_press_shift(entry, event);
    529667
    530668        return ui_claimed;
     
    569707                if (gfx_pix_inside_rect(&pos, &entry->rect)) {
    570708                        entry->pos = ui_entry_find_pos(entry, &pos);
     709                        entry->sel_start = entry->pos;
    571710                        if (entry->active)
    572711                                ui_entry_paint(entry);
     
    680819 *
    681820 * @param entry Text entry
    682  */
    683 void ui_entry_seek_start(ui_entry_t *entry)
     821 * @param shift @c true iff shift key is pressed
     822 */
     823void ui_entry_seek_start(ui_entry_t *entry, bool shift)
    684824{
    685825        entry->pos = 0;
     826
     827        if (!shift)
     828                entry->sel_start = entry->pos;
    686829        (void) ui_entry_paint(entry);
    687830}
     
    690833 *
    691834 * @param entry Text entry
    692  */
    693 void ui_entry_seek_end(ui_entry_t *entry)
     835 * @param shift @c true iff shift key is pressed
     836 */
     837void ui_entry_seek_end(ui_entry_t *entry, bool shift)
    694838{
    695839        entry->pos = str_size(entry->text);
     840
     841        if (!shift)
     842                entry->sel_start = entry->pos;
    696843        (void) ui_entry_paint(entry);
    697844}
     
    700847 *
    701848 * @param entry Text entry
    702  */
    703 void ui_entry_seek_prev_char(ui_entry_t *entry)
     849 * @param shift @c true iff shift key is pressed
     850 */
     851void ui_entry_seek_prev_char(ui_entry_t *entry, bool shift)
    704852{
    705853        size_t off;
     
    709857            str_size(entry->text));
    710858        entry->pos = off;
     859
     860        if (!shift)
     861                entry->sel_start = entry->pos;
    711862        (void) ui_entry_paint(entry);
    712863}
     
    715866 *
    716867 * @param entry Text entry
    717  */
    718 void ui_entry_seek_next_char(ui_entry_t *entry)
     868 * @param shift @c true iff shift key is pressed
     869 */
     870void ui_entry_seek_next_char(ui_entry_t *entry, bool shift)
    719871{
    720872        size_t off;
     
    724876            str_size(entry->text));
    725877        entry->pos = off;
     878
     879        if (!shift)
     880                entry->sel_start = entry->pos;
    726881        (void) ui_entry_paint(entry);
    727882}
     
    741896
    742897        entry->active = false;
     898        entry->sel_start = entry->pos;
    743899        (void) ui_entry_paint(entry);
    744900
  • uspace/lib/ui/test/entry.c

    read72f2 r9eb8d12  
    190190}
    191191
     192/** ui_entry_delete_sel() deletes selected text */
     193PCUT_TEST(delete_sel)
     194{
     195        errno_t rc;
     196        ui_t *ui = NULL;
     197        ui_window_t *window = NULL;
     198        ui_wnd_params_t params;
     199        ui_entry_t *entry;
     200
     201        rc = ui_create_disp(NULL, &ui);
     202        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     203
     204        ui_wnd_params_init(&params);
     205        params.caption = "Hello";
     206
     207        rc = ui_window_create(ui, &params, &window);
     208        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     209        PCUT_ASSERT_NOT_NULL(window);
     210
     211        rc = ui_entry_create(window, "ABCDEF", &entry);
     212        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     213
     214        PCUT_ASSERT_STR_EQUALS("ABCDEF", entry->text);
     215
     216        ui_entry_activate(entry);
     217
     218        /* Select all but first and last character */
     219        ui_entry_seek_start(entry, false);
     220        ui_entry_seek_next_char(entry, false);
     221        ui_entry_seek_end(entry, true);
     222        ui_entry_seek_prev_char(entry, true);
     223
     224        ui_entry_delete_sel(entry);
     225
     226        PCUT_ASSERT_STR_EQUALS("AF", entry->text);
     227
     228        ui_entry_destroy(entry);
     229        ui_window_destroy(window);
     230        ui_destroy(ui);
     231}
     232
    192233/** ui_entry_insert_str() inserts string at cursor. */
    193234PCUT_TEST(insert_str)
     
    214255        PCUT_ASSERT_STR_EQUALS("A", entry->text);
    215256
    216         /* This moves the cursor to the end of the text */
    217257        ui_entry_activate(entry);
     258        ui_entry_seek_end(entry, false);
    218259
    219260        rc = ui_entry_insert_str(entry, "B");
     
    228269
    229270        entry->pos = 2;
     271        entry->sel_start = 2;
    230272        rc = ui_entry_insert_str(entry, "CD");
    231273        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    232274
    233275        PCUT_ASSERT_STR_EQUALS("ABCDEF", entry->text);
     276
     277        ui_entry_destroy(entry);
     278        ui_window_destroy(window);
     279        ui_destroy(ui);
     280}
     281
     282/** ui_entry_insert_str() deletes selection before inserting string */
     283PCUT_TEST(insert_str_with_sel)
     284{
     285        errno_t rc;
     286        ui_t *ui = NULL;
     287        ui_window_t *window = NULL;
     288        ui_wnd_params_t params;
     289        ui_entry_t *entry;
     290
     291        rc = ui_create_disp(NULL, &ui);
     292        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     293
     294        ui_wnd_params_init(&params);
     295        params.caption = "Hello";
     296
     297        rc = ui_window_create(ui, &params, &window);
     298        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     299        PCUT_ASSERT_NOT_NULL(window);
     300
     301        rc = ui_entry_create(window, "ABCDE", &entry);
     302        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     303
     304        PCUT_ASSERT_STR_EQUALS("ABCDE", entry->text);
     305
     306        /* Select all but the first and last character */
     307        ui_entry_activate(entry);
     308        ui_entry_seek_start(entry, false);
     309        ui_entry_seek_next_char(entry, false);
     310        ui_entry_seek_end(entry, true);
     311        ui_entry_seek_prev_char(entry, true);
     312
     313        rc = ui_entry_insert_str(entry, "123");
     314        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     315
     316        PCUT_ASSERT_STR_EQUALS("A123E", entry->text);
    234317
    235318        ui_entry_destroy(entry);
     
    262345        PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
    263346        entry->pos = 3;
     347        entry->sel_start = 3;
    264348
    265349        ui_entry_backspace(entry);
     
    280364}
    281365
     366/** ui_entry_backspace() with selected text deletes selection. */
     367PCUT_TEST(backspace_with_sel)
     368{
     369        errno_t rc;
     370        ui_t *ui = NULL;
     371        ui_window_t *window = NULL;
     372        ui_wnd_params_t params;
     373        ui_entry_t *entry;
     374
     375        rc = ui_create_disp(NULL, &ui);
     376        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     377
     378        ui_wnd_params_init(&params);
     379        params.caption = "Hello";
     380
     381        rc = ui_window_create(ui, &params, &window);
     382        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     383        PCUT_ASSERT_NOT_NULL(window);
     384
     385        rc = ui_entry_create(window, "ABCDE", &entry);
     386        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     387
     388        PCUT_ASSERT_STR_EQUALS("ABCDE", entry->text);
     389
     390        /* Select all but the first and last character */
     391        ui_entry_activate(entry);
     392        ui_entry_seek_start(entry, false);
     393        ui_entry_seek_next_char(entry, false);
     394        ui_entry_seek_end(entry, true);
     395        ui_entry_seek_prev_char(entry, true);
     396
     397        ui_entry_backspace(entry);
     398
     399        PCUT_ASSERT_STR_EQUALS("AE", entry->text);
     400
     401        ui_entry_destroy(entry);
     402        ui_window_destroy(window);
     403        ui_destroy(ui);
     404}
     405
    282406/** ui_entry_delete() deletes character after cursor. */
    283407PCUT_TEST(delete)
     
    304428        PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
    305429        entry->pos = 1;
     430        entry->sel_start = 1;
    306431
    307432        ui_entry_delete(entry);
     
    322447}
    323448
     449/** ui_entry_delete() with selected text deletes selection. */
     450PCUT_TEST(delete_with_sel)
     451{
     452        errno_t rc;
     453        ui_t *ui = NULL;
     454        ui_window_t *window = NULL;
     455        ui_wnd_params_t params;
     456        ui_entry_t *entry;
     457
     458        rc = ui_create_disp(NULL, &ui);
     459        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     460
     461        ui_wnd_params_init(&params);
     462        params.caption = "Hello";
     463
     464        rc = ui_window_create(ui, &params, &window);
     465        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     466        PCUT_ASSERT_NOT_NULL(window);
     467
     468        rc = ui_entry_create(window, "ABCDE", &entry);
     469        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     470
     471        PCUT_ASSERT_STR_EQUALS("ABCDE", entry->text);
     472
     473        /* Select all but the first and last character */
     474        ui_entry_activate(entry);
     475        ui_entry_seek_start(entry, false);
     476        ui_entry_seek_next_char(entry, false);
     477        ui_entry_seek_end(entry, true);
     478        ui_entry_seek_prev_char(entry, true);
     479
     480        ui_entry_delete(entry);
     481
     482        PCUT_ASSERT_STR_EQUALS("AE", entry->text);
     483
     484        ui_entry_destroy(entry);
     485        ui_window_destroy(window);
     486        ui_destroy(ui);
     487}
     488
    324489/** ui_entry_seek_start() moves cursor to beginning of text */
    325490PCUT_TEST(seek_start)
     
    346511        PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
    347512        entry->pos = 2;
    348 
    349         ui_entry_seek_start(entry);
     513        entry->sel_start = 2;
     514
     515        ui_entry_seek_start(entry, true);
    350516        PCUT_ASSERT_INT_EQUALS(0, entry->pos);
     517        PCUT_ASSERT_INT_EQUALS(2, entry->sel_start);
     518
     519        ui_entry_seek_start(entry, false);
     520        PCUT_ASSERT_INT_EQUALS(0, entry->pos);
     521        PCUT_ASSERT_INT_EQUALS(0, entry->sel_start);
    351522
    352523        ui_entry_destroy(entry);
     
    379550        PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
    380551        entry->pos = 2;
    381 
    382         ui_entry_seek_end(entry);
     552        entry->sel_start = 2;
     553
     554        ui_entry_seek_end(entry, true);
    383555        PCUT_ASSERT_INT_EQUALS(4, entry->pos);
     556        PCUT_ASSERT_INT_EQUALS(2, entry->sel_start);
     557        ui_entry_seek_end(entry, false);
     558        PCUT_ASSERT_INT_EQUALS(4, entry->pos);
     559        PCUT_ASSERT_INT_EQUALS(4, entry->sel_start);
    384560
    385561        ui_entry_destroy(entry);
     
    411587
    412588        PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
    413         entry->pos = 2;
    414 
    415         ui_entry_seek_prev_char(entry);
     589        entry->pos = 3;
     590        entry->sel_start = 3;
     591
     592        ui_entry_seek_prev_char(entry, true);
     593        PCUT_ASSERT_INT_EQUALS(2, entry->pos);
     594        PCUT_ASSERT_INT_EQUALS(3, entry->sel_start);
     595
     596        ui_entry_seek_prev_char(entry, false);
    416597        PCUT_ASSERT_INT_EQUALS(1, entry->pos);
     598        PCUT_ASSERT_INT_EQUALS(1, entry->sel_start);
    417599
    418600        ui_entry_destroy(entry);
     
    444626
    445627        PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
    446         entry->pos = 2;
    447 
    448         ui_entry_seek_next_char(entry);
     628        entry->pos = 1;
     629        entry->sel_start = 1;
     630
     631        ui_entry_seek_next_char(entry, true);
     632        PCUT_ASSERT_INT_EQUALS(2, entry->pos);
     633        PCUT_ASSERT_INT_EQUALS(1, entry->sel_start);
     634        ui_entry_seek_next_char(entry, false);
    449635        PCUT_ASSERT_INT_EQUALS(3, entry->pos);
     636        PCUT_ASSERT_INT_EQUALS(3, entry->sel_start);
    450637
    451638        ui_entry_destroy(entry);
Note: See TracChangeset for help on using the changeset viewer.