Browse Source

Fix center viewport not working horizontally

kit 1 year ago
parent
commit
46fa85891b
2 changed files with 70 additions and 94 deletions
  1. 68 90
      scene/gui/text_edit.cpp
  2. 2 4
      scene/gui/text_edit.h

+ 68 - 90
scene/gui/text_edit.cpp

@@ -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() {

+ 2 - 4
scene/gui/text_edit.h

@@ -191,9 +191,6 @@ private:
 		int gutter_count = 0;
 		bool indent_wrapped_lines = false;
 
-		void _calculate_line_height() const;
-		void _calculate_max_line_width() const;
-
 	public:
 		void set_tab_size(int p_tab_size);
 		int get_tab_size() const;
@@ -216,7 +213,6 @@ private:
 		void set_use_custom_word_separators(bool p_enabled);
 		bool is_custom_word_separators_enabled() const;
 
-		void set_word_separators(const String &p_separators);
 		void set_custom_word_separators(const String &p_separators);
 		String get_enabled_word_separators() const;
 		String get_custom_word_separators() const;
@@ -538,6 +534,8 @@ private:
 	void _scroll_lines_up();
 	void _scroll_lines_down();
 
+	void _adjust_viewport_to_caret_horizontally(int p_caret = 0);
+
 	// Minimap.
 	bool draw_minimap = false;