elm_code_widget: fix keyboard and scrolling with active selection.

Summary:
This adds some attributes to the selectiont type in elm_code.
Including the type (whether it is mouse or keyboard) and also whether
a selection is in progress. Thus we can reliably select around the
file and also move/scroll when there is an active selection.

Test Plan:
Drag and select text with mouse. Also the same with keyboard (hold shift and select).
Leave selection active and scroll around the file. The selection should remain and
full movement is possible while retaining the active selection. This could really
be refactored for a next major release.

Reviewers: #committers, ajwillia.ms, cedric

Reviewed By: ajwillia.ms

Subscribers: zmike

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D6676
This commit is contained in:
Alastair Poole 2018-07-27 15:20:24 +01:00 committed by Andy Williams
parent 49554b2b6c
commit ad379ce04f
3 changed files with 67 additions and 1 deletions

View File

@ -344,6 +344,16 @@ _elm_code_widget_fill_cursor(Elm_Code_Widget *widget, unsigned int number, int g
if (pd->cursor_col + gutter - 1 >= (unsigned int) w)
return;
if (pd->selection && !pd->selection->in_progress)
{
Elm_Code_Line *line = elm_code_file_line_get(pd->code->file, number);
if (!line)
return;
if (!elm_code_widget_line_visible_get(widget, line))
return;
}
_elm_code_widget_cursor_update(widget, pd);
}
}
@ -451,6 +461,9 @@ _elm_code_widget_cursor_selection_set(Elm_Code_Widget *widget, Elm_Code_Widget_D
end_line = pd->selection->end_line;
end_col = pd->selection->end_col;
if (pd->selection->type == ELM_CODE_WIDGET_SELECTION_KEYBOARD)
return;
if ((pd->selection->start_line == pd->selection->end_line && pd->selection->end_col > pd->selection->start_col) ||
(pd->selection->start_line < pd->selection->end_line))
{
@ -700,7 +713,8 @@ _elm_code_widget_cursor_move(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd,
pd->cursor_col = elm_code_widget_line_text_column_width_to_position(widget, line_obj, position);
efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CURSOR_CHANGED, widget);
_elm_code_widget_cursor_ensure_visible(widget);
if (!pd->selection || (pd->selection && pd->selection->in_progress))
_elm_code_widget_cursor_ensure_visible(widget);
if (oldrow != pd->cursor_line)
_elm_code_widget_refresh(widget, line_obj);
@ -1158,6 +1172,11 @@ _elm_code_widget_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj
if (!pd->selection)
if (col > 0 && row <= elm_code_file_lines_get(pd->code->file))
elm_code_widget_selection_start(widget, row, col);
_elm_code_widget_selection_type_set(widget, ELM_CODE_WIDGET_SELECTION_MOUSE);
_elm_code_widget_selection_in_progress_set(widget, EINA_TRUE);
elm_code_widget_selection_end(widget, row, col);
}
@ -1179,6 +1198,8 @@ _elm_code_widget_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj E
if (pd->selection)
{
_elm_code_widget_selection_in_progress_set(widget, EINA_FALSE);
if (pd->selection->start_line == pd->selection->end_line &&
pd->selection->start_col == pd->selection->end_col)
elm_code_widget_selection_clear(widget);
@ -1736,6 +1757,9 @@ _elm_code_widget_key_down_cb(void *data, Evas *evas EINA_UNUSED,
if (!pd->selection)
elm_code_widget_selection_start(widget, pd->cursor_line, pd->cursor_col - (backwards?1:0));
_elm_code_widget_selection_type_set(widget, ELM_CODE_WIDGET_SELECTION_KEYBOARD);
_elm_code_widget_selection_in_progress_set(widget, EINA_TRUE);
if (pd->selection && pd->selection->start_line == pd->selection->end_line)
{
if ((pd->selection->end_col == pd->selection->start_col && !backwards) ||
@ -1776,6 +1800,7 @@ _elm_code_widget_key_down_cb(void *data, Evas *evas EINA_UNUSED,
adjust = (pd->selection->end_line > pd->selection->start_line);
elm_code_widget_selection_end(widget, pd->cursor_line, pd->cursor_col - (adjust?1:0));
_elm_code_widget_selection_in_progress_set(widget, EINA_FALSE);
}
}

View File

@ -4,10 +4,18 @@
/**
* Structure holding the info about a selected region.
*/
typedef enum
{
ELM_CODE_WIDGET_SELECTION_KEYBOARD,
ELM_CODE_WIDGET_SELECTION_MOUSE,
} Elm_Code_Widget_Selection_Type;
typedef struct
{
unsigned int start_line, end_line;
unsigned int start_col, end_col;
Elm_Code_Widget_Selection_Type type;
Eina_Bool in_progress;
} Elm_Code_Widget_Selection_Data;
typedef struct
@ -68,4 +76,8 @@ void _elm_code_widget_undo_change_add(Evas_Object *widget, Elm_Code_Widget_Chang
void _elm_code_widget_change_selection_add(Evas_Object *widget);
void _elm_code_widget_selection_in_progress_set(Evas_Object *widget, Eina_Bool state);
void _elm_code_widget_selection_type_set(Evas_Object *widget, Elm_Code_Widget_Selection_Type type);
#endif

View File

@ -58,6 +58,8 @@ elm_code_widget_selection_start(Evas_Object *widget,
pd->selection = selection;
}
_elm_code_widget_selection_in_progress_set(widget, EINA_TRUE);
pd->selection->start_line = line;
pd->selection->start_col = col;
efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_SELECTION_START, widget);
@ -464,3 +466,30 @@ elm_code_widget_selection_is_empty(Evas_Object *widget)
return ret;
}
void
_elm_code_widget_selection_in_progress_set(Evas_Object *widget, Eina_Bool state)
{
Elm_Code_Widget_Data *pd;
pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd || !pd->selection)
return;
pd->selection->in_progress = state;
}
void
_elm_code_widget_selection_type_set(Evas_Object *widget, Elm_Code_Widget_Selection_Type type)
{
Elm_Code_Widget_Data *pd;
pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd || !pd->selection)
return;
pd->selection->type = type;
}