Просмотр исходного кода

Merge pull request #106441 from jorgekorgut/fix-highlight-issues

Fix highlighting warning and error issues
Thaddeus Crews 3 месяцев назад
Родитель
Сommit
6414451ced

+ 49 - 27
editor/plugins/script_text_editor.cpp

@@ -601,6 +601,50 @@ void ScriptTextEditor::_update_color_constructor_options() {
 	}
 }
 
+void ScriptTextEditor::_update_background_color() {
+	// Clear background lines.
+	CodeEdit *te = code_editor->get_text_editor();
+	for (int i = 0; i < te->get_line_count(); i++) {
+		bool is_folded_code_region = te->is_line_code_region_start(i) && te->is_line_folded(i);
+		te->set_line_background_color(i, is_folded_code_region ? folded_code_region_color : Color(0, 0, 0, 0));
+	}
+
+	// Set the warning background.
+	if (warning_line_color.a != 0.0) {
+		for (const ScriptLanguage::Warning &warning : warnings) {
+			int folder_line_header = te->get_folded_line_header(warning.end_line - 2);
+			bool is_folded = folder_line_header != (warning.end_line - 2);
+
+			if (is_folded) {
+				te->set_line_background_color(folder_line_header, warning_line_color);
+			} else if (warning.end_line - warning.start_line > 0 && warning.end_line - warning.start_line < 20) {
+				// If the warning spans below 20 lines (arbitrary), set the background color for all lines.
+				// (W.end_line - W.start_line > 0) ensures that we set the background for single line warnings.
+				for (int i = warning.start_line - 1; i < warning.end_line - 1; i++) {
+					te->set_line_background_color(i, warning_line_color);
+				}
+			} else {
+				// Otherwise, just set the background color for the start line of the warning.
+				te->set_line_background_color(warning.start_line - 1, warning_line_color);
+			}
+		}
+	}
+
+	// Set the error background.
+	if (marked_line_color.a != 0.0) {
+		for (const ScriptLanguage::ScriptError &error : errors) {
+			int folder_line_header = te->get_folded_line_header(error.line - 1);
+			bool is_folded_code = folder_line_header != (error.line - 1);
+
+			if (is_folded_code) {
+				te->set_line_background_color(folder_line_header, marked_line_color);
+			} else {
+				te->set_line_background_color(error.line - 1, marked_line_color);
+			}
+		}
+	}
+}
+
 void ScriptTextEditor::_update_color_text() {
 	if (inline_color_line < 0) {
 		return;
@@ -802,6 +846,7 @@ void ScriptTextEditor::_validate_script() {
 	_update_connected_methods();
 	_update_warnings();
 	_update_errors();
+	_update_background_color();
 
 	emit_signal(SNAME("name_changed"));
 	emit_signal(SNAME("edited_script_changed"));
@@ -870,17 +915,6 @@ void ScriptTextEditor::_update_warnings() {
 		warnings_panel->pop(); // Cell.
 	}
 	warnings_panel->pop(); // Table.
-	if (warning_line_color.a != 0.0) {
-		CodeEdit *te = code_editor->get_text_editor();
-		for (int i = 0; i < te->get_line_count(); i++) {
-			for (const ScriptLanguage::Warning &W : warnings) {
-				if (i >= W.start_line - 1 && i < W.end_line) {
-					te->set_line_background_color(i, warning_line_color);
-					break;
-				}
-			}
-		}
-	}
 }
 
 void ScriptTextEditor::_update_errors() {
@@ -943,23 +977,11 @@ void ScriptTextEditor::_update_errors() {
 		errors_panel->pop(); // Indent.
 	}
 
-	CodeEdit *te = code_editor->get_text_editor();
 	bool highlight_safe = EDITOR_GET("text_editor/appearance/gutters/highlight_type_safe_lines");
 	bool last_is_safe = false;
-	for (int i = 0; i < te->get_line_count(); i++) {
-		if (errors.is_empty()) {
-			bool is_folded_code_region = te->is_line_code_region_start(i) && te->is_line_folded(i);
-			te->set_line_background_color(i, is_folded_code_region ? folded_code_region_color : Color(0, 0, 0, 0));
-		} else if (marked_line_color.a != 0) {
-			for (const ScriptLanguage::ScriptError &E : errors) {
-				bool error_line = i == E.line - 1;
-				te->set_line_background_color(i, error_line ? marked_line_color : Color(0, 0, 0, 0));
-				if (error_line) {
-					break;
-				}
-			}
-		}
+	CodeEdit *te = code_editor->get_text_editor();
 
+	for (int i = 0; i < te->get_line_count(); i++) {
 		if (highlight_safe) {
 			if (safe_lines.has(i + 1)) {
 				te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
@@ -1727,11 +1749,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
 		} break;
 		case EDIT_FOLD_ALL_LINES: {
 			tx->fold_all_lines();
-			tx->queue_redraw();
 		} break;
 		case EDIT_UNFOLD_ALL_LINES: {
 			tx->unfold_all_lines();
-			tx->queue_redraw();
 		} break;
 		case EDIT_CREATE_CODE_REGION: {
 			tx->create_code_region();
@@ -2031,6 +2051,7 @@ void ScriptTextEditor::_notification(int p_what) {
 			if (is_visible_in_tree()) {
 				_update_warnings();
 				_update_errors();
+				_update_background_color();
 			}
 			[[fallthrough]];
 		case NOTIFICATION_ENTER_TREE: {
@@ -2588,6 +2609,7 @@ void ScriptTextEditor::_enable_code_editor() {
 	code_editor->get_text_editor()->connect("gutter_added", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
 	code_editor->get_text_editor()->connect("gutter_removed", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
 	code_editor->get_text_editor()->connect("gutter_clicked", callable_mp(this, &ScriptTextEditor::_gutter_clicked));
+	code_editor->get_text_editor()->connect("_fold_line_updated", callable_mp(this, &ScriptTextEditor::_update_background_color));
 	code_editor->get_text_editor()->connect(SceneStringName(gui_input), callable_mp(this, &ScriptTextEditor::_text_edit_gui_input));
 	code_editor->show_toggle_files_button();
 	_update_gutter_indexes();

+ 1 - 0
editor/plugins/script_text_editor.h

@@ -211,6 +211,7 @@ protected:
 	String _picker_color_stringify(const Color &p_color, COLOR_MODE p_mode);
 	void _picker_color_changed(const Color &p_color);
 	void _update_color_constructor_options();
+	void _update_background_color();
 	void _update_color_text();
 
 	void _notification(int p_what);

+ 0 - 2
editor/plugins/text_editor.cpp

@@ -410,11 +410,9 @@ void TextEditor::_edit_option(int p_op) {
 		} break;
 		case EDIT_FOLD_ALL_LINES: {
 			tx->fold_all_lines();
-			tx->queue_redraw();
 		} break;
 		case EDIT_UNFOLD_ALL_LINES: {
 			tx->unfold_all_lines();
-			tx->queue_redraw();
 		} break;
 		case EDIT_TRIM_TRAILING_WHITESAPCE: {
 			trim_trailing_whitespace();

+ 56 - 10
scene/gui/code_edit.cpp

@@ -1672,10 +1672,10 @@ bool CodeEdit::can_fold_line(int p_line) const {
 	return false;
 }
 
-void CodeEdit::fold_line(int p_line) {
-	ERR_FAIL_INDEX(p_line, get_line_count());
+bool CodeEdit::_fold_line(int p_line) {
+	ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
 	if (!is_line_folding_enabled() || !can_fold_line(p_line)) {
-		return;
+		return false;
 	}
 
 	/* Find the last line to be hidden. */
@@ -1741,12 +1741,14 @@ void CodeEdit::fold_line(int p_line) {
 
 	// Collapse any carets in the hidden area.
 	collapse_carets(p_line, get_line(p_line).length(), end_line, get_line(end_line).length(), true);
+
+	return true;
 }
 
-void CodeEdit::unfold_line(int p_line) {
-	ERR_FAIL_INDEX(p_line, get_line_count());
+bool CodeEdit::_unfold_line(int p_line) {
+	ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
 	if (!is_line_folded(p_line) && !_is_line_hidden(p_line)) {
-		return;
+		return false;
 	}
 
 	int fold_start = p_line;
@@ -1766,18 +1768,47 @@ void CodeEdit::unfold_line(int p_line) {
 			set_line_background_color(i - 1, Color(0.0, 0.0, 0.0, 0.0));
 		}
 	}
-	queue_redraw();
+	return true;
 }
 
 void CodeEdit::fold_all_lines() {
+	bool any_line_folded = false;
+
 	for (int i = 0; i < get_line_count(); i++) {
-		fold_line(i);
+		any_line_folded |= _fold_line(i);
+	}
+
+	if (any_line_folded) {
+		emit_signal(SNAME("_fold_line_updated"));
+	}
+}
+
+void CodeEdit::fold_line(int p_line) {
+	bool line_folded = _fold_line(p_line);
+
+	if (line_folded) {
+		emit_signal(SNAME("_fold_line_updated"));
 	}
-	queue_redraw();
 }
 
 void CodeEdit::unfold_all_lines() {
-	_unhide_all_lines();
+	bool any_line_unfolded = false;
+
+	for (int i = 0; i < get_line_count(); i++) {
+		any_line_unfolded |= _unfold_line(i);
+	}
+
+	if (any_line_unfolded) {
+		emit_signal(SNAME("_fold_line_updated"));
+	}
+}
+
+void CodeEdit::unfold_line(int p_line) {
+	bool line_unfolded = _unfold_line(p_line);
+
+	if (line_unfolded) {
+		emit_signal(SNAME("_fold_line_updated"));
+	}
 }
 
 void CodeEdit::toggle_foldable_line(int p_line) {
@@ -1806,6 +1837,18 @@ void CodeEdit::toggle_foldable_lines_at_carets() {
 	end_multicaret_edit();
 }
 
+int CodeEdit::get_folded_line_header(int p_line) const {
+	ERR_FAIL_INDEX_V(p_line, get_line_count(), 0);
+	// Search for the first non hidden line.
+	while (p_line > 0) {
+		if (!_is_line_hidden(p_line)) {
+			break;
+		}
+		p_line--;
+	}
+	return p_line;
+}
+
 bool CodeEdit::is_line_folded(int p_line) const {
 	ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
 	return p_line + 1 < get_line_count() && !_is_line_hidden(p_line) && _is_line_hidden(p_line + 1);
@@ -3820,6 +3863,9 @@ CodeEdit::CodeEdit() {
 	symbol_tooltip_timer->connect("timeout", callable_mp(this, &CodeEdit::_on_symbol_tooltip_timer_timeout));
 	add_child(symbol_tooltip_timer, false, INTERNAL_MODE_FRONT);
 
+	/* Fold Lines Private signal */
+	add_user_signal(MethodInfo("_fold_line_updated"));
+
 	connect("lines_edited_from", callable_mp(this, &CodeEdit::_lines_edited_from));
 	connect("text_set", callable_mp(this, &CodeEdit::_text_set));
 	connect(SceneStringName(text_changed), callable_mp(this, &CodeEdit::_text_changed));

+ 3 - 0
scene/gui/code_edit.h

@@ -132,6 +132,8 @@ private:
 	String code_region_start_tag = "region";
 	String code_region_end_tag = "endregion";
 	void _update_code_region_tags();
+	bool _fold_line(int p_line);
+	bool _unfold_line(int p_line);
 
 	/* Delimiters */
 	enum DelimiterType {
@@ -426,6 +428,7 @@ public:
 	void toggle_foldable_line(int p_line);
 	void toggle_foldable_lines_at_carets();
 
+	int get_folded_line_header(int p_line) const;
 	bool is_line_folded(int p_line) const;
 	TypedArray<int> get_folded_lines() const;