From 55ecf31ccda3b1e7a9805fb66a9d4a8ff1539124 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Mon, 15 Feb 2016 22:54:12 +0000 Subject: [PATCH] [editor] double click and triple do selections double for a word (space or tab delimited for now) triple selects whole line. --- NEWS | 1 + elm_code/src/lib/widget/elm_code_widget.c | 15 ++++- .../lib/widget/elm_code_widget_selection.c | 65 ++++++++++++++++++ .../lib/widget/elm_code_widget_selection.h | 4 ++ .../widget/elm_code_test_widget_selection.c | 66 +++++++++++++++++++ 5 files changed, 149 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index ad8171d..935a2de 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ Features: * Option to inserts spaces instead of tabs * Update to EFL 1.17 release for better toolbar handling * Add file filtering for hunting down files in the list + * Double click to select word, triple click to select line Bug fixes: diff --git a/elm_code/src/lib/widget/elm_code_widget.c b/elm_code/src/lib/widget/elm_code_widget.c index a6cde05..a5ef0de 100644 --- a/elm_code/src/lib/widget/elm_code_widget.c +++ b/elm_code/src/lib/widget/elm_code_widget.c @@ -678,7 +678,7 @@ _elm_code_widget_clicked_readonly_cb(Elm_Code_Widget *widget, unsigned int row) static void _elm_code_widget_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, - void *event_info) + void *event_info) { Elm_Code_Widget *widget; Elm_Code_Widget_Data *pd; @@ -689,12 +689,23 @@ _elm_code_widget_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj widget = (Elm_Code_Widget *)data; pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); event = (Evas_Event_Mouse_Down *)event_info; + _elm_code_widget_position_at_coordinates_get(widget, pd, event->canvas.x, event->canvas.y, &row, &col); elm_code_widget_selection_clear(widget); + if (event->flags & EVAS_BUTTON_TRIPLE_CLICK) + { + elm_code_widget_selection_select_line(widget, row); + return; + } + else if (event->flags & EVAS_BUTTON_DOUBLE_CLICK) + { + elm_code_widget_selection_select_word(widget, row, col); + return; + } + if (!pd->editable) return; - _elm_code_widget_position_at_coordinates_get(widget, pd, event->canvas.x, event->canvas.y, &row, &col); if (col > 0 && row <= elm_code_file_lines_get(pd->code->file)) elm_code_widget_selection_start(widget, row, col); } diff --git a/elm_code/src/lib/widget/elm_code_widget_selection.c b/elm_code/src/lib/widget/elm_code_widget_selection.c index dd3ee74..ae2d122 100644 --- a/elm_code/src/lib/widget/elm_code_widget_selection.c +++ b/elm_code/src/lib/widget/elm_code_widget_selection.c @@ -226,6 +226,71 @@ elm_code_widget_selection_delete(Evas_Object *widget) eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET_EVENT_SELECTION_CLEARED, widget)); } +EAPI void +elm_code_widget_selection_select_line(Evas_Object *widget, unsigned int line) +{ + Elm_Code_Widget_Data *pd; + Elm_Code_Line *lineobj; + + pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); + lineobj = elm_code_file_line_get(pd->code->file, line); + + if (!lineobj) + return; + + elm_code_widget_selection_start(widget, line, 1); + elm_code_widget_selection_end(widget, line, lineobj->length); +} + +static Eina_Bool +_elm_code_widget_selection_char_breaks(char chr) +{ + if (chr == 0) + return EINA_TRUE; + else if (chr == ' ') + return EINA_TRUE; + else if (chr == '\t') + return EINA_TRUE; + + return EINA_FALSE; +} + +EAPI void +elm_code_widget_selection_select_word(Evas_Object *widget, unsigned int line, unsigned int col) +{ + Elm_Code_Widget_Data *pd; + Elm_Code_Line *lineobj; + unsigned int colpos, length, pos; + const char *content; + + pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); + lineobj = elm_code_file_line_get(pd->code->file, line); + content = elm_code_line_text_get(lineobj, &length); + + _elm_code_widget_selection_limit(widget, pd, &line, &col); + colpos = elm_code_widget_line_text_position_for_column_get(widget, lineobj, col); + + pos = colpos; + while (pos > 0) + { + if (_elm_code_widget_selection_char_breaks(content[pos - 1])) + break; + pos--; + } + elm_code_widget_selection_start(widget, line, + elm_code_widget_line_text_column_width_to_position(widget, lineobj, pos)); + + pos = colpos; + while (pos < length - 1) + { + if (_elm_code_widget_selection_char_breaks(content[pos + 1])) + break; + pos++; + } + elm_code_widget_selection_end(widget, line, + elm_code_widget_line_text_column_width_to_position(widget, lineobj, pos)); +} + static char * _elm_code_widget_selection_text_single_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd) { diff --git a/elm_code/src/lib/widget/elm_code_widget_selection.h b/elm_code/src/lib/widget/elm_code_widget_selection.h index 0e476a2..b79abc7 100644 --- a/elm_code/src/lib/widget/elm_code_widget_selection.h +++ b/elm_code/src/lib/widget/elm_code_widget_selection.h @@ -23,6 +23,10 @@ EAPI void elm_code_widget_selection_clear(Evas_Object *widget); EAPI void elm_code_widget_selection_delete(Evas_Object *widget); +EAPI void elm_code_widget_selection_select_line(Evas_Object *widget, unsigned int line); + +EAPI void elm_code_widget_selection_select_word(Evas_Object *widget, unsigned int line, unsigned int col); + EAPI char *elm_code_widget_selection_text_get(Evas_Object *widget); EAPI void elm_code_widget_selection_cut(Evas_Object *widget); diff --git a/elm_code/src/tests/widget/elm_code_test_widget_selection.c b/elm_code/src/tests/widget/elm_code_test_widget_selection.c index 7135e4a..71e63bf 100644 --- a/elm_code/src/tests/widget/elm_code_test_widget_selection.c +++ b/elm_code/src/tests/widget/elm_code_test_widget_selection.c @@ -475,6 +475,70 @@ START_TEST (elm_code_test_widget_selection_reverse_delete_multiline) elm_shutdown(); } END_TEST + +START_TEST (elm_code_test_widget_selection_select_line) +{ + Elm_Code *code; + Elm_Code_File *file; + Elm_Code_Widget *widget; + Evas_Object *win; + char *selection; + + elm_init(1, NULL); + code = elm_code_create(); + file = elm_code_file_new(code); + elm_code_file_line_append(file, "line selection", 14, NULL); + elm_code_file_line_append(file, "line2", 5, NULL); + + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + widget = elm_code_widget_add(win, code); + + elm_code_widget_selection_select_line(widget, 1); + selection = elm_code_widget_selection_text_get(widget); + ck_assert_str_eq("line selection", selection); + free(selection); + + elm_code_widget_selection_select_line(widget, 2); + selection = elm_code_widget_selection_text_get(widget); + ck_assert_str_eq("line2", selection); + free(selection); +} +END_TEST + +START_TEST (elm_code_test_widget_selection_select_word) +{ + Elm_Code *code; + Elm_Code_File *file; + Elm_Code_Widget *widget; + Evas_Object *win; + char *selection; + + elm_init(1, NULL); + code = elm_code_create(); + file = elm_code_file_new(code); + elm_code_file_line_append(file, "word selection test", 19, NULL); + elm_code_file_line_append(file, "more stuff\tto test", 18, NULL); + + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + widget = elm_code_widget_add(win, code); + + elm_code_widget_selection_select_word(widget, 1, 3); + selection = elm_code_widget_selection_text_get(widget); + ck_assert_str_eq("word", selection); + free(selection); + + elm_code_widget_selection_select_word(widget, 1, 16); + selection = elm_code_widget_selection_text_get(widget); + ck_assert_str_eq("test", selection); + free(selection); + + elm_code_widget_selection_select_word(widget, 2, 9); + selection = elm_code_widget_selection_text_get(widget); + ck_assert_str_eq("stuff", selection); + free(selection); +} +END_TEST + void elm_code_test_widget_selection(TCase *tc) { tcase_add_test(tc, elm_code_test_widget_selection_set); @@ -491,5 +555,7 @@ void elm_code_test_widget_selection(TCase *tc) tcase_add_test(tc, elm_code_test_widget_selection_reverse_delete_twoline); tcase_add_test(tc, elm_code_test_widget_selection_delete_multiline); tcase_add_test(tc, elm_code_test_widget_selection_reverse_delete_multiline); + tcase_add_test(tc, elm_code_test_widget_selection_select_line); + tcase_add_test(tc, elm_code_test_widget_selection_select_word); }