From eccf5906168bda65854636a7e84c063342261999 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 12 Feb 2013 12:58:12 +0000 Subject: Triple click selects paragraph in textarea widget. --- desktop/mouse.h | 34 ++++++++++++++++++++------------- desktop/textarea.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 13 deletions(-) diff --git a/desktop/mouse.h b/desktop/mouse.h index 042db23a9..9a3a16702 100644 --- a/desktop/mouse.h +++ b/desktop/mouse.h @@ -32,8 +32,8 @@ typedef enum { * May be used to indicate * hover or end of drag. */ - BROWSER_MOUSE_PRESS_1 = (1 << 0), /* button 1 pressed */ - BROWSER_MOUSE_PRESS_2 = (1 << 1), /* button 2 pressed */ + BROWSER_MOUSE_PRESS_1 = (1 << 0), /* button 1 pressed */ + BROWSER_MOUSE_PRESS_2 = (1 << 1), /* button 2 pressed */ /* note: click meaning is different for * different front ends. On RISC OS, it @@ -45,27 +45,35 @@ typedef enum { * is released, if the operation wasn't * a drag. */ - BROWSER_MOUSE_CLICK_1 = (1 << 2), /* button 1 clicked. */ - BROWSER_MOUSE_CLICK_2 = (1 << 3), /* button 2 clicked. */ + BROWSER_MOUSE_CLICK_1 = (1 << 2), /* button 1 clicked. */ + BROWSER_MOUSE_CLICK_2 = (1 << 3), /* button 2 clicked. */ - BROWSER_MOUSE_DOUBLE_CLICK = (1 << 4), /* button 1 double clicked */ + BROWSER_MOUSE_DOUBLE_CLICK = (1 << 4), /* button double clicked */ + BROWSER_MOUSE_TRIPLE_CLICK = (1 << 5), /* button triple clicked */ - BROWSER_MOUSE_DRAG_1 = (1 << 5), /* start of button 1 drag */ - BROWSER_MOUSE_DRAG_2 = (1 << 6), /* start of button 2 drag */ + /* note: double and triple clicks are + * fired alongside a + * BROWSER_MOUSE_CLICK_[1|2] + * to indicate which button + * is used. + */ - BROWSER_MOUSE_DRAG_ON = (1 << 7), /* a drag operation was started + BROWSER_MOUSE_DRAG_1 = (1 << 6), /* start of button 1 drag */ + BROWSER_MOUSE_DRAG_2 = (1 << 7), /* start of button 2 drag */ + + BROWSER_MOUSE_DRAG_ON = (1 << 8), /* a drag operation was started * and a mouse button is still * pressed */ - BROWSER_MOUSE_HOLDING_1 = (1 << 8), /* during button 1 drag */ - BROWSER_MOUSE_HOLDING_2 = (1 << 9), /* during button 2 drag */ + BROWSER_MOUSE_HOLDING_1 = (1 << 9), /* during button 1 drag */ + BROWSER_MOUSE_HOLDING_2 = (1 << 10), /* during button 2 drag */ - BROWSER_MOUSE_MOD_1 = (1 << 10), /* 1st modifier key pressed + BROWSER_MOUSE_MOD_1 = (1 << 11), /* 1st modifier key pressed * (eg. Shift) */ - BROWSER_MOUSE_MOD_2 = (1 << 11), /* 2nd modifier key pressed + BROWSER_MOUSE_MOD_2 = (1 << 12), /* 2nd modifier key pressed * (eg. Ctrl) */ - BROWSER_MOUSE_MOD_3 = (1 << 12) /* 3rd modifier key pressed + BROWSER_MOUSE_MOD_3 = (1 << 13) /* 3rd modifier key pressed * (eg. Alt) */ } browser_mouse_state; diff --git a/desktop/textarea.c b/desktop/textarea.c index a1c422202..15ef80169 100644 --- a/desktop/textarea.c +++ b/desktop/textarea.c @@ -257,6 +257,57 @@ static bool textarea_select_fragment(struct textarea * ta) } +/** + * Selects paragraph, at current caret position. + * + * \param ta textarea widget + * \return True on success, false otherwise + */ +static bool textarea_select_paragraph(struct textarea * ta) +{ + int caret_pos, index; + int sel_start = 0; + int sel_end = ta->show->utf8_len; + size_t b_start, b_end; + + caret_pos = textarea_get_caret(ta); + if (caret_pos < 0) { + return false; + } + + /* Work through text up to caret, looking for a place to start + * selection */ + for (b_start = 0, index = 0; index < caret_pos; + b_start = utf8_next(ta->show->data, ta->show->len, + b_start), + index++) { + /* Set selection start as character after any new line found */ + if (ta->show->data[b_start] == '\n') { + /* Add one to start to skip over separator */ + sel_start = index + 1; + } + } + + /* Search for end of selection */ + for (b_end = b_start; b_end < ta->show->len; + b_end = utf8_next(ta->show->data, ta->show->len, + b_end), + index++) { + if (ta->show->data[b_end] == '\n') { + sel_end = index; + break; + } + } + + if (sel_start < sel_end) { + textarea_select(ta, sel_start, sel_end, false); + return true; + } + + return false; +} + + /** * Scrolls a textarea to make the caret visible (doesn't perform a redraw) * @@ -2196,6 +2247,11 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse, textarea_set_caret_xy(ta, x, y); return textarea_select_fragment(ta); + } else if (mouse & BROWSER_MOUSE_TRIPLE_CLICK) { + /* Select paragraph */ + textarea_set_caret_xy(ta, x, y); + return textarea_select_paragraph(ta); + } else if (mouse & BROWSER_MOUSE_PRESS_1) { if (!(ta->flags & TEXTAREA_READONLY)) { /* Place caret */ -- cgit v1.2.3