summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scene/gui/text_edit.cpp187
-rw-r--r--scene/gui/text_edit.h9
2 files changed, 137 insertions, 59 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index ee7762b668..7d200a799b 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -376,24 +376,116 @@ 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) {
+ 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();
+ }
+}
- Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position();
+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);
+ int row, col;
+ _get_mouse_pos(Point2i(mp.x, mp.y), row, col);
- select(selection.selecting_line, selection.selecting_column, row, col);
+ select(selection.selecting_line, selection.selecting_column, row, col);
- cursor_set_line(row);
- cursor_set_column(col);
- update();
+ 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);
- click_select_held->start();
+ 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);
- click_select_held->stop();
+ 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) {
@@ -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);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index b4b14d0139..81310b7c10 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -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();