Merge pull request #12662 from Paulb23/text_edit_mouse_selection

Changed line and word mouse selection
This commit is contained in:
Rémi Verschelde 2017-11-06 09:43:22 +01:00 committed by GitHub
commit d4e37ef198
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 143 additions and 65 deletions

View File

@ -376,26 +376,118 @@ void TextEdit::_update_scrollbars() {
void TextEdit::_click_selection_held() {
if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) {
Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position();
int row, col;
_get_mouse_pos(Point2i(mp.x, mp.y), row, col);
select(selection.selecting_line, selection.selecting_column, row, col);
cursor_set_line(row);
cursor_set_column(col);
update();
click_select_held->start();
switch (selection.selecting_mode) {
case Selection::MODE_POINTER: {
_update_selection_mode_pointer();
} break;
case Selection::MODE_WORD: {
_update_selection_mode_word();
} break;
case Selection::MODE_LINE: {
_update_selection_mode_line();
} break;
default: {
break;
}
}
} else {
click_select_held->stop();
}
}
void TextEdit::_update_selection_mode_pointer() {
Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position();
int row, col;
_get_mouse_pos(Point2i(mp.x, mp.y), row, col);
select(selection.selecting_line, selection.selecting_column, row, col);
cursor_set_line(row);
cursor_set_column(col);
update();
click_select_held->start();
}
void TextEdit::_update_selection_mode_word() {
Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position();
int row, col;
_get_mouse_pos(Point2i(mp.x, mp.y), row, col);
String line = text[row];
int beg = CLAMP(col, 0, line.length());
// if its the first selection and on whitespace make sure we grab the word instead..
if (!selection.active) {
while (beg > 0 && line[beg] <= 32) {
beg--;
}
}
int end = beg;
bool symbol = beg < line.length() && _is_symbol(line[beg]);
// get the word end and begin points
while (beg > 0 && line[beg - 1] > 32 && (symbol == _is_symbol(line[beg - 1]))) {
beg--;
}
while (end < line.length() && line[end + 1] > 32 && (symbol == _is_symbol(line[end + 1]))) {
end++;
}
if (end < line.length()) {
end += 1;
}
// inital selection
if (!selection.active) {
select(row, beg, row, end);
selection.selecting_column = beg;
selection.selected_word_beg = beg;
selection.selected_word_end = end;
selection.selected_word_origin = beg;
cursor_set_column(selection.to_column);
} else {
if ((col <= selection.selected_word_origin && row == selection.selecting_line) || row < selection.selecting_line) {
selection.selecting_column = selection.selected_word_end;
select(row, beg, selection.selecting_line, selection.selected_word_end);
cursor_set_column(selection.from_column);
} else {
selection.selecting_column = selection.selected_word_beg;
select(selection.selecting_line, selection.selected_word_beg, row, end);
cursor_set_column(selection.to_column);
}
}
cursor_set_line(row);
update();
click_select_held->start();
}
void TextEdit::_update_selection_mode_line() {
Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position();
int row, col;
_get_mouse_pos(Point2i(mp.x, mp.y), row, col);
col = 0;
if (row < selection.selecting_line) {
// cursor is above us
cursor_set_line(row - 1);
selection.selecting_column = text[selection.selecting_line].length();
} else {
// cursor is below us
cursor_set_line(row + 1);
selection.selecting_column = 0;
col = text[row].length();
}
cursor_set_column(0);
select(selection.selecting_line, selection.selecting_column, row, col);
update();
click_select_held->start();
}
void TextEdit::_notification(int p_what) {
switch (p_what) {
@ -1759,36 +1851,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (!mb->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
//tripleclick select line
select(cursor.line, 0, cursor.line, text[cursor.line].length());
selection.selecting_column = 0;
selection.selecting_mode = Selection::MODE_LINE;
_update_selection_mode_line();
last_dblclk = 0;
} else if (mb->is_doubleclick() && text[cursor.line].length()) {
//doubleclick select world
String s = text[cursor.line];
int beg = CLAMP(cursor.column, 0, s.length());
int end = beg;
if (s[beg] > 32 || beg == s.length()) {
bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
while (beg > 0 && s[beg - 1] > 32 && (symbol == _is_symbol(s[beg - 1]))) {
beg--;
}
while (end < s.length() && s[end + 1] > 32 && (symbol == _is_symbol(s[end + 1]))) {
end++;
}
if (end < s.length())
end += 1;
select(cursor.line, beg, cursor.line, end);
selection.selecting_column = beg;
}
selection.selecting_mode = Selection::MODE_WORD;
_update_selection_mode_word();
last_dblclk = OS::get_singleton()->get_ticks_msec();
}
@ -1833,21 +1904,21 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { //ignore if dragging
_reset_caret_blink_timer();
if (selection.selecting_mode != Selection::MODE_NONE) {
_reset_caret_blink_timer();
int row, col;
_get_mouse_pos(mm->get_position(), row, col);
select(selection.selecting_line, selection.selecting_column, row, col);
cursor_set_line(row);
cursor_set_column(col);
update();
click_select_held->start();
switch (selection.selecting_mode) {
case Selection::MODE_POINTER: {
_update_selection_mode_pointer();
} break;
case Selection::MODE_WORD: {
_update_selection_mode_word();
} break;
case Selection::MODE_LINE: {
_update_selection_mode_line();
} break;
default: {
break;
}
}
}
}
@ -2847,19 +2918,19 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (scancode_handled)
accept_event();
/*
if (!scancode_handled && !k->get_command() && !k->get_alt()) {
if (!scancode_handled && !k->get_command() && !k->get_alt()) {
if (k->get_unicode()>=32) {
if (readonly)
if (readonly)
break;
accept_event();
accept_event();
} else {
break;
break;
}
}
}
*/
if (k->get_scancode() == KEY_INSERT) {
set_insert_mode(!insert_mode);
@ -3251,11 +3322,11 @@ void TextEdit::adjust_viewport_to_cursor() {
update();
/*
get_range()->set_max(text.size());
get_range()->set_max(text.size());
get_range()->set_page(get_visible_rows());
get_range()->set_page(get_visible_rows());
get_range()->set((int)cursor.line_ofs);
get_range()->set((int)cursor.line_ofs);
*/
}
@ -4815,8 +4886,8 @@ void TextEdit::_bind_methods() {
BIND_ENUM_CONSTANT(SEARCH_BACKWARDS);
/*
ClassDB::bind_method(D_METHOD("delete_char"),&TextEdit::delete_char);
ClassDB::bind_method(D_METHOD("delete_line"),&TextEdit::delete_line);
ClassDB::bind_method(D_METHOD("delete_char"),&TextEdit::delete_char);
ClassDB::bind_method(D_METHOD("delete_line"),&TextEdit::delete_line);
*/
ClassDB::bind_method(D_METHOD("set_text", "text"), &TextEdit::set_text);

View File

@ -51,11 +51,14 @@ class TextEdit : public Control {
MODE_NONE,
MODE_SHIFT,
MODE_POINTER
MODE_POINTER,
MODE_WORD,
MODE_LINE
};
Mode selecting_mode;
int selecting_line, selecting_column;
int selected_word_beg, selected_word_end, selected_word_origin;
bool selecting_text;
bool active;
@ -305,6 +308,10 @@ class TextEdit : public Control {
void _v_scroll_input();
void _click_selection_held();
void _update_selection_mode_pointer();
void _update_selection_mode_word();
void _update_selection_mode_line();
void _pre_shift_selection();
void _post_shift_selection();