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

Changeset 0f24c57 in mainline


Ignore:
Timestamp:
2009-12-04T19:19:22Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
0902edfe
Parents:
3041fef1
Message:

Implement basis of selections in editor.

File:
1 edited

Legend:

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

    r3041fef1 r0f24c57  
    7474        tag_t caret_pos;
    7575
     76        /** Start of selection */
     77        tag_t sel_start;
     78
    7679        /**
    7780         * Ideal column where the caret should try to get. This is used
     
    107110static void key_handle_unmod(console_event_t const *ev);
    108111static void key_handle_ctrl(console_event_t const *ev);
     112static void key_handle_shift(console_event_t const *ev);
     113static void key_handle_movement(unsigned int key, bool shift);
     114
    109115static int file_save(char const *fname);
    110116static void file_save_as(void);
     
    113119    spt_t const *epos);
    114120static char *filename_prompt(char const *prompt, char const *init_value);
     121
    115122static void pane_text_display(void);
    116123static void pane_row_display(void);
     
    118125static void pane_status_display(void);
    119126static void pane_caret_display(void);
     127
    120128static void insert_char(wchar_t c);
    121129static void delete_char_before(void);
     
    123131static void caret_update(void);
    124132static void caret_move(int drow, int dcolumn, enum dir_spec align_dir);
     133
     134static bool selection_active(void);
     135static void selection_delete(void);
     136
    125137static void pt_get_sof(spt_t *pt);
    126138static void pt_get_eof(spt_t *pt);
     139static int tag_cmp(tag_t const *a, tag_t const *b);
     140static int spt_cmp(spt_t const *a, spt_t const *b);
     141static int coord_cmp(coord_t const *a, coord_t const *b);
     142
    127143static void status_display(char const *str);
    128144
     
    172188        caret_move(-ED_INFTY, -ED_INFTY, dir_before);
    173189
     190        /* Place selection start tag. */
     191        tag_get_pt(&pane.caret_pos, &pt);
     192        sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
     193
    174194        /* Initial display */
    175195        console_clear(con);
     
    190210                        /* Handle key press. */
    191211                        if (((ev.mods & KM_ALT) == 0) &&
     212                            ((ev.mods & KM_SHIFT) == 0) &&
    192213                             (ev.mods & KM_CTRL) != 0) {
    193214                                key_handle_ctrl(&ev);
    194                         } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {
     215                        } else if (((ev.mods & KM_ALT) == 0) &&
     216                            ((ev.mods & KM_CTRL) == 0) &&
     217                             (ev.mods & KM_SHIFT) != 0) {
     218                                key_handle_shift(&ev);
     219                        } else if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
    195220                                key_handle_unmod(&ev);
    196221                        }
     
    207232                if (pane.rflags & REDRAW_CARET)
    208233                        pane_caret_display();
    209                        
    210234        }
    211235
     
    220244        switch (ev->key) {
    221245        case KC_ENTER:
     246                selection_delete();
    222247                insert_char('\n');
    223248                caret_update();
    224249                break;
    225250        case KC_LEFT:
    226                 caret_move(0, -1, dir_before);
    227                 break;
    228251        case KC_RIGHT:
    229                 caret_move(0, 0, dir_after);
    230                 break;
    231252        case KC_UP:
    232                 caret_move(-1, 0, dir_before);
    233                 break;
    234253        case KC_DOWN:
    235                 caret_move(+1, 0, dir_before);
    236                 break;
    237254        case KC_HOME:
    238                 caret_move(0, -ED_INFTY, dir_before);
    239                 break;
    240255        case KC_END:
    241                 caret_move(0, +ED_INFTY, dir_before);
    242                 break;
    243256        case KC_PAGE_UP:
    244                 caret_move(-pane.rows, 0, dir_before);
    245                 break;
    246257        case KC_PAGE_DOWN:
    247                 caret_move(+pane.rows, 0, dir_before);
     258                key_handle_movement(ev->key, false);
    248259                break;
    249260        case KC_BACKSPACE:
    250                 delete_char_before();
     261                if (selection_active())
     262                        selection_delete();
     263                else
     264                        delete_char_before();
    251265                caret_update();
    252266                break;
    253267        case KC_DELETE:
    254                 delete_char_after();
     268                if (selection_active())
     269                        selection_delete();
     270                else
     271                        delete_char_after();
    255272                caret_update();
    256273                break;
    257274        default:
    258275                if (ev->c >= 32 || ev->c == '\t') {
     276                        selection_delete();
     277                        insert_char(ev->c);
     278                        caret_update();
     279                }
     280                break;
     281        }
     282}
     283
     284/** Handle Shift-key combination. */
     285static void key_handle_shift(console_event_t const *ev)
     286{
     287        switch (ev->key) {
     288        case KC_LEFT:
     289        case KC_RIGHT:
     290        case KC_UP:
     291        case KC_DOWN:
     292        case KC_HOME:
     293        case KC_END:
     294        case KC_PAGE_UP:
     295        case KC_PAGE_DOWN:
     296                key_handle_movement(ev->key, true);
     297                break;
     298        default:
     299                if (ev->c >= 32 || ev->c == '\t') {
     300                        selection_delete();
    259301                        insert_char(ev->c);
    260302                        caret_update();
     
    282324        default:
    283325                break;
     326        }
     327}
     328
     329static void key_handle_movement(unsigned int key, bool select)
     330{
     331        spt_t pt;
     332        spt_t caret_pt;
     333        coord_t c_old, c_new;
     334        bool had_sel;
     335
     336        /* Check if we had selection before. */
     337        tag_get_pt(&pane.caret_pos, &caret_pt);
     338        tag_get_pt(&pane.sel_start, &pt);
     339        had_sel = !spt_equal(&caret_pt, &pt);
     340
     341        switch (key) {
     342        case KC_LEFT:
     343                caret_move(0, -1, dir_before);
     344                break;
     345        case KC_RIGHT:
     346                caret_move(0, 0, dir_after);
     347                break;
     348        case KC_UP:
     349                caret_move(-1, 0, dir_before);
     350                break;
     351        case KC_DOWN:
     352                caret_move(+1, 0, dir_before);
     353                break;
     354        case KC_HOME:
     355                caret_move(0, -ED_INFTY, dir_before);
     356                break;
     357        case KC_END:
     358                caret_move(0, +ED_INFTY, dir_before);
     359                break;
     360        case KC_PAGE_UP:
     361                caret_move(-pane.rows, 0, dir_before);
     362                break;
     363        case KC_PAGE_DOWN:
     364                caret_move(+pane.rows, 0, dir_before);
     365                break;
     366        default:
     367                break;
     368        }
     369
     370        if (select == false) {
     371                /* Move sel_start to the same point as caret. */
     372                sheet_remove_tag(&doc.sh, &pane.sel_start);
     373                tag_get_pt(&pane.caret_pos, &pt);
     374                sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
     375        }
     376
     377        if (select) {
     378                tag_get_pt(&pane.caret_pos, &pt);
     379                spt_get_coord(&caret_pt, &c_old);
     380                spt_get_coord(&pt, &c_new);
     381
     382                if (c_old.row == c_new.row)
     383                        pane.rflags |= REDRAW_ROW;
     384                else
     385                        pane.rflags |= REDRAW_TEXT;
     386
     387        } else if (had_sel == true) {
     388                /* Redraw because text was unselected. */
     389                pane.rflags |= REDRAW_TEXT;
    284390        }
    285391}
     
    517623{
    518624        int i, j, fill;
    519         spt_t rb, re, dep;
     625        spt_t rb, re, dep, pt;
    520626        coord_t rbc, rec;
    521627        char row_buf[ROW_BUF_SIZE];
     
    523629        size_t pos, size;
    524630        unsigned s_column;
     631        coord_t csel_start, csel_end, ctmp;
     632
     633        /* Determine selection start and end. */
     634
     635        tag_get_pt(&pane.sel_start, &pt);
     636        spt_get_coord(&pt, &csel_start);
     637
     638        tag_get_pt(&pane.caret_pos, &pt);
     639        spt_get_coord(&pt, &csel_end);
     640
     641        if (coord_cmp(&csel_start, &csel_end) > 0) {
     642                ctmp = csel_start;
     643                csel_start = csel_end;
     644                csel_end = ctmp;
     645        }
    525646
    526647        /* Draw rows from the sheet. */
     
    543664                /* Display text from the buffer. */
    544665
     666                if (coord_cmp(&csel_start, &rbc) <= 0 &&
     667                    coord_cmp(&rbc, &csel_end) < 0) {
     668                        fflush(stdout);
     669                        console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
     670                        fflush(stdout);
     671                }
     672
    545673                console_goto(con, 0, i);
    546674                size = str_size(row_buf);
     
    548676                s_column = 1;
    549677                while (pos < size) {
     678                        if (csel_start.row == rbc.row && csel_start.column == s_column) {
     679                                fflush(stdout);
     680                                console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
     681                                fflush(stdout);
     682                        }
     683       
     684                        if (csel_end.row == rbc.row && csel_end.column == s_column) {
     685                                fflush(stdout);
     686                                console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
     687                                fflush(stdout);
     688                        }
     689       
    550690                        c = str_decode(row_buf, &pos, size);
    551691                        if (c != '\t') {
     
    562702                }
    563703
     704                if (csel_end.row == rbc.row && csel_end.column == s_column) {
     705                        fflush(stdout);
     706                        console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
     707                        fflush(stdout);
     708                }
     709
    564710                /* Fill until the end of display area. */
    565711
     
    572718                        putchar(' ');
    573719                fflush(stdout);
     720                console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    574721        }
    575722
     
    760907}
    761908
     909/** Check for non-empty selection. */
     910static bool selection_active(void)
     911{
     912        return (tag_cmp(&pane.caret_pos, &pane.sel_start) != 0);
     913}
     914
     915/** Delete selected text. */
     916static void selection_delete(void)
     917{
     918        spt_t pa, pb;
     919        coord_t ca, cb;
     920        int rel;
     921
     922        tag_get_pt(&pane.sel_start, &pa);
     923        tag_get_pt(&pane.caret_pos, &pb);
     924        spt_get_coord(&pa, &ca);
     925        spt_get_coord(&pb, &cb);
     926        rel = coord_cmp(&ca, &cb);
     927
     928        if (rel == 0)
     929                return;
     930
     931        if (rel < 0)
     932                sheet_delete(&doc.sh, &pa, &pb);
     933        else
     934                sheet_delete(&doc.sh, &pb, &pa);
     935
     936        if (ca.row == cb.row)
     937                pane.rflags |= REDRAW_ROW;
     938        else
     939                pane.rflags |= REDRAW_TEXT;
     940}
    762941
    763942/** Get start-of-file s-point. */
     
    781960
    782961        sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
     962}
     963
     964/** Compare tags. */
     965static int tag_cmp(tag_t const *a, tag_t const *b)
     966{
     967        spt_t pa, pb;
     968
     969        tag_get_pt(a, &pa);
     970        tag_get_pt(b, &pb);
     971
     972        return spt_cmp(&pa, &pb);
     973}
     974
     975/** Compare s-points. */
     976static int spt_cmp(spt_t const *a, spt_t const *b)
     977{
     978        coord_t ca, cb;
     979
     980        spt_get_coord(a, &ca);
     981        spt_get_coord(b, &cb);
     982
     983        return coord_cmp(&ca, &cb);
     984}
     985
     986/** Compare coordinats. */
     987static int coord_cmp(coord_t const *a, coord_t const *b)
     988{
     989        if (a->row - b->row != 0)
     990                return a->row - b->row;
     991
     992        return a->column - b->column;
    783993}
    784994
Note: See TracChangeset for help on using the changeset viewer.