|
@@ -6004,7 +6004,7 @@ int TextEdit::get_total_visible_line_count() const {
|
|
|
void TextEdit::adjust_viewport_to_caret(int p_caret) {
|
|
|
ERR_FAIL_INDEX(p_caret, carets.size());
|
|
|
|
|
|
- // Make sure Caret is visible on the screen.
|
|
|
+ // Move viewport so the caret is visible on the screen vertically.
|
|
|
scrolling = false;
|
|
|
minimap_clicked = false;
|
|
|
|
|
@@ -6024,105 +6024,19 @@ void TextEdit::adjust_viewport_to_caret(int p_caret) {
|
|
|
set_line_as_last_visible(cur_line, cur_wrap);
|
|
|
}
|
|
|
|
|
|
- int visible_width = get_size().width - theme_cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding;
|
|
|
- if (draw_minimap) {
|
|
|
- visible_width -= minimap_width;
|
|
|
- }
|
|
|
- if (v_scroll->is_visible_in_tree()) {
|
|
|
- visible_width -= v_scroll->get_combined_minimum_size().width;
|
|
|
- }
|
|
|
- visible_width -= 20; // Give it a little more space.
|
|
|
-
|
|
|
- if (visible_width <= 0) {
|
|
|
- // Not resized yet.
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- Vector2i caret_pos;
|
|
|
-
|
|
|
- // Get position of the start of caret.
|
|
|
- if (has_ime_text() && ime_selection.x != 0) {
|
|
|
- caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x, get_caret_line(p_caret), get_caret_column(p_caret) + ime_selection.x);
|
|
|
- } else {
|
|
|
- caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret), get_caret_line(p_caret), get_caret_column(p_caret));
|
|
|
- }
|
|
|
-
|
|
|
- // Get position of the end of caret.
|
|
|
- if (has_ime_text()) {
|
|
|
- if (ime_selection.y > 0) {
|
|
|
- caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x + ime_selection.y, get_caret_line(p_caret), get_caret_column(p_caret) + ime_selection.x + ime_selection.y);
|
|
|
- } else {
|
|
|
- caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_text.length(), get_caret_line(p_caret), get_caret_column(p_caret) + ime_text.length());
|
|
|
- }
|
|
|
- } else {
|
|
|
- caret_pos.y = caret_pos.x;
|
|
|
- }
|
|
|
-
|
|
|
- if (MAX(caret_pos.x, caret_pos.y) > (first_visible_col + visible_width)) {
|
|
|
- first_visible_col = MAX(caret_pos.x, caret_pos.y) - visible_width + 1;
|
|
|
- }
|
|
|
-
|
|
|
- if (MIN(caret_pos.x, caret_pos.y) < first_visible_col) {
|
|
|
- first_visible_col = MIN(caret_pos.x, caret_pos.y);
|
|
|
- }
|
|
|
- h_scroll->set_value(first_visible_col);
|
|
|
-
|
|
|
- queue_redraw();
|
|
|
+ _adjust_viewport_to_caret_horizontally(p_caret);
|
|
|
}
|
|
|
|
|
|
void TextEdit::center_viewport_to_caret(int p_caret) {
|
|
|
ERR_FAIL_INDEX(p_caret, carets.size());
|
|
|
|
|
|
- // Move viewport so the caret is in the center of the screen.
|
|
|
+ // Move viewport so the caret is in the center of the screen vertically.
|
|
|
scrolling = false;
|
|
|
minimap_clicked = false;
|
|
|
|
|
|
set_line_as_center_visible(get_caret_line(p_caret), get_caret_wrap_index(p_caret));
|
|
|
- int visible_width = get_size().width - theme_cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding;
|
|
|
- if (draw_minimap) {
|
|
|
- visible_width -= minimap_width;
|
|
|
- }
|
|
|
- if (v_scroll->is_visible_in_tree()) {
|
|
|
- visible_width -= v_scroll->get_combined_minimum_size().width;
|
|
|
- }
|
|
|
- visible_width -= 20; // Give it a little more space.
|
|
|
-
|
|
|
- if (get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE) {
|
|
|
- // Center x offset.
|
|
|
-
|
|
|
- Vector2i caret_pos;
|
|
|
|
|
|
- // Get position of the start of caret.
|
|
|
- if (has_ime_text() && ime_selection.x != 0) {
|
|
|
- caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x, get_caret_line(p_caret), get_caret_column(p_caret) + ime_selection.x);
|
|
|
- } else {
|
|
|
- caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret), get_caret_line(p_caret), get_caret_column(p_caret));
|
|
|
- }
|
|
|
-
|
|
|
- // Get position of the end of caret.
|
|
|
- if (has_ime_text()) {
|
|
|
- if (ime_selection.y > 0) {
|
|
|
- caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x + ime_selection.y, get_caret_line(p_caret), get_caret_column(p_caret) + ime_selection.x + ime_selection.y);
|
|
|
- } else {
|
|
|
- caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_text.length(), get_caret_line(p_caret), get_caret_column(p_caret) + ime_text.length());
|
|
|
- }
|
|
|
- } else {
|
|
|
- caret_pos.y = caret_pos.x;
|
|
|
- }
|
|
|
-
|
|
|
- if (MAX(caret_pos.x, caret_pos.y) > (first_visible_col + visible_width)) {
|
|
|
- first_visible_col = MAX(caret_pos.x, caret_pos.y) - visible_width + 1;
|
|
|
- }
|
|
|
-
|
|
|
- if (MIN(caret_pos.x, caret_pos.y) < first_visible_col) {
|
|
|
- first_visible_col = MIN(caret_pos.x, caret_pos.y);
|
|
|
- }
|
|
|
- } else {
|
|
|
- first_visible_col = 0;
|
|
|
- }
|
|
|
- h_scroll->set_value(first_visible_col);
|
|
|
-
|
|
|
- queue_redraw();
|
|
|
+ _adjust_viewport_to_caret_horizontally(p_caret);
|
|
|
}
|
|
|
|
|
|
/* Minimap */
|
|
@@ -8212,6 +8126,70 @@ void TextEdit::_scroll_lines_down() {
|
|
|
merge_overlapping_carets();
|
|
|
}
|
|
|
|
|
|
+void TextEdit::_adjust_viewport_to_caret_horizontally(int p_caret) {
|
|
|
+ if (get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE) {
|
|
|
+ first_visible_col = 0;
|
|
|
+ h_scroll->set_value(first_visible_col);
|
|
|
+ queue_redraw();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int visible_width = get_size().width - theme_cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding;
|
|
|
+ if (draw_minimap) {
|
|
|
+ visible_width -= minimap_width;
|
|
|
+ }
|
|
|
+ if (v_scroll->is_visible_in_tree()) {
|
|
|
+ visible_width -= v_scroll->get_combined_minimum_size().width;
|
|
|
+ }
|
|
|
+ visible_width -= 20; // Give it a little more space.
|
|
|
+
|
|
|
+ if (visible_width <= 0) {
|
|
|
+ // Not resized yet.
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int caret_start_pos;
|
|
|
+ int caret_end_pos;
|
|
|
+ bool prioritize_end = true;
|
|
|
+
|
|
|
+ // Get start and end position of the caret.
|
|
|
+ if (has_ime_text()) {
|
|
|
+ // Use the size of the IME.
|
|
|
+ int ime_start_column = get_caret_column(p_caret) + ime_selection.x;
|
|
|
+ caret_start_pos = _get_column_x_offset_for_line(ime_start_column, get_caret_line(p_caret), ime_start_column);
|
|
|
+ int ime_end_column = get_caret_column(p_caret) + (ime_selection.y > 0 ? ime_selection.x + ime_selection.y : ime_text.length());
|
|
|
+ caret_end_pos = _get_column_x_offset_for_line(ime_end_column, get_caret_line(p_caret), ime_end_column);
|
|
|
+ prioritize_end = false;
|
|
|
+ } else if (has_selection(p_caret) && get_selection_from_line(p_caret) == get_selection_to_line(p_caret)) {
|
|
|
+ // Use selection if it is on one line.
|
|
|
+ caret_start_pos = _get_column_x_offset_for_line(get_selection_from_column(p_caret), get_caret_line(p_caret), get_selection_from_column(p_caret));
|
|
|
+ caret_end_pos = _get_column_x_offset_for_line(get_selection_to_column(p_caret), get_caret_line(p_caret), get_selection_to_column(p_caret));
|
|
|
+ prioritize_end = is_caret_after_selection_origin();
|
|
|
+ } else {
|
|
|
+ caret_start_pos = _get_column_x_offset_for_line(get_caret_column(p_caret), get_caret_line(p_caret), get_caret_column(p_caret));
|
|
|
+ caret_end_pos = caret_start_pos;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (caret_start_pos > caret_end_pos) {
|
|
|
+ // For RTL text.
|
|
|
+ SWAP(caret_start_pos, caret_end_pos);
|
|
|
+ prioritize_end = !prioritize_end;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!prioritize_end && caret_end_pos > first_visible_col + visible_width) {
|
|
|
+ first_visible_col = caret_end_pos - visible_width + 1;
|
|
|
+ }
|
|
|
+ if (caret_start_pos < first_visible_col) {
|
|
|
+ first_visible_col = caret_start_pos;
|
|
|
+ }
|
|
|
+ if (prioritize_end && caret_end_pos > first_visible_col + visible_width) {
|
|
|
+ first_visible_col = caret_end_pos - visible_width + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ h_scroll->set_value(first_visible_col);
|
|
|
+ queue_redraw();
|
|
|
+}
|
|
|
+
|
|
|
// Minimap
|
|
|
|
|
|
void TextEdit::_update_minimap_hover() {
|