diff options
Diffstat (limited to 'scene')
| -rw-r--r-- | scene/gui/rich_text_label.cpp | 3 | ||||
| -rw-r--r-- | scene/gui/text_edit.cpp | 187 | ||||
| -rw-r--r-- | scene/gui/text_edit.h | 9 | ||||
| -rw-r--r-- | scene/gui/tree.cpp | 20 | ||||
| -rw-r--r-- | scene/gui/tree.h | 1 |
5 files changed, 161 insertions, 59 deletions
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 65a8350bd3..798acb9d52 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -526,6 +526,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor); } else if (p_mode == PROCESS_POINTER) { _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, p_click_pos, r_click_item, r_click_char, r_outside); + if (r_click_item && *r_click_item) { + RETURN; // exit early + } } } 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(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 5c6f2b0d01..f2e5919b5f 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3332,6 +3332,26 @@ Point2 Tree::get_scroll() const { return ofs; } +void Tree::scroll_to_item(TreeItem *p_item) { + + if (!is_visible_in_tree()) { + + // hack to work around crash in get_item_rect() if Tree is not in tree. + return; + } + + // make sure the scrollbar min and max are up to date with latest changes. + update_scrollbars(); + + const Rect2 r = get_item_rect(p_item); + + if (r.position.y < v_scroll->get_value()) { + v_scroll->set_value(r.position.y); + } else if (r.position.y + r.size.y + 2 * cache.vseparation > v_scroll->get_value() + get_size().y) { + v_scroll->set_value(r.position.y + r.size.y + 2 * cache.vseparation - get_size().y); + } +} + TreeItem *Tree::_search_item_text(TreeItem *p_at, const String &p_find, int *r_col, bool p_selectable, bool p_backwards) { while (p_at) { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 2ee91a8b73..64d6016942 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -570,6 +570,7 @@ public: TreeItem *search_item_text(const String &p_find, int *r_col = NULL, bool p_selectable = false); Point2 get_scroll() const; + void scroll_to_item(TreeItem *p_item); void set_cursor_can_exit_tree(bool p_enable); bool can_cursor_exit_tree() const; |