Browse Source

Improve breakpoints and breakpoint gutter API in TextEdit

Added breakpoint_gutter, is_breakpoint_gutter_enabled, set_breakpoint_gutter_enabled, get_breakpoints, remove_breakpoints.
Fixed breakpoint_toggled signal not fierd when text is edited.
Fixes #18026.
Gabriel Gavilan 7 years ago
parent
commit
b7b63fe034
4 changed files with 100 additions and 18 deletions
  1. 31 0
      doc/classes/TextEdit.xml
  2. 1 1
      editor/code_editor.cpp
  3. 64 15
      scene/gui/text_edit.cpp
  4. 4 2
      scene/gui/text_edit.h

+ 31 - 0
doc/classes/TextEdit.xml

@@ -132,6 +132,13 @@
 			<description>
 			</description>
 		</method>
+		<method name="get_breakpoints" qualifiers="const">
+			<return type="Array">
+			</return>
+			<description>
+				Return an array containing the line number of each breakpoint.
+			</description>
+		</method>
 		<method name="get_keyword_color" qualifiers="const">
 			<return type="Color">
 			</return>
@@ -220,6 +227,12 @@
 				Insert a given text at the cursor position.
 			</description>
 		</method>
+		<method name="is_breakpoint_gutter_enabled" qualifiers="const">
+			<return type="bool">
+			</return>
+			<description>
+			</description>
+		</method>
 		<method name="is_folded" qualifiers="const">
 			<return type="bool">
 			</return>
@@ -265,6 +278,13 @@
 				Perform redo operation.
 			</description>
 		</method>
+		<method name="remove_breakpoints">
+			<return type="void">
+			</return>
+			<description>
+				Removes all the breakpoints (without firing "breakpoint_toggled" signal).
+			</description>
+		</method>
 		<method name="search" qualifiers="const">
 			<return type="PoolIntArray">
 			</return>
@@ -302,6 +322,14 @@
 				Select all the text.
 			</description>
 		</method>
+		<method name="set_breakpoint_gutter_enabled">
+			<return type="void">
+			</return>
+			<argument index="0" name="enable" type="bool">
+			</argument>
+			<description>
+			</description>
+		</method>
 		<method name="set_line_as_hidden">
 			<return type="void">
 			</return>
@@ -344,6 +372,9 @@
 		</method>
 	</methods>
 	<members>
+		<member name="breakpoint_gutter" type="bool" setter="set_breakpoint_gutter_enabled" getter="is_breakpoint_gutter_enabled">
+			If [code]true[/code] the breakpoint gutter is visible.
+		</member>
 		<member name="caret_blink" type="bool" setter="cursor_set_blink_enabled" getter="cursor_get_blink_enabled">
 			If [code]true[/code] the caret (visual cursor) blinks.
 		</member>

+ 1 - 1
editor/code_editor.cpp

@@ -775,7 +775,7 @@ void CodeTextEditor::update_editor_settings() {
 	text_editor->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_current_line"));
 	text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink"));
 	text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
-	text_editor->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter"));
+	text_editor->set_breakpoint_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter"));
 	text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding"));
 	text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding"));
 	text_editor->set_wrap_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/word_wrap"));

+ 64 - 15
scene/gui/text_edit.cpp

@@ -1525,8 +1525,11 @@ void TextEdit::backspace_at_cursor() {
 
 	if (is_line_hidden(cursor.line))
 		set_line_as_hidden(prev_line, true);
-	if (is_line_set_as_breakpoint(cursor.line))
+	if (is_line_set_as_breakpoint(cursor.line)) {
+		if (!text.is_breakpoint(prev_line))
+			emit_signal("breakpoint_toggled", prev_line);
 		set_line_as_breakpoint(prev_line, true);
+	}
 
 	if (auto_brace_completion_enabled &&
 			cursor.column > 0 &&
@@ -3298,22 +3301,37 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
 	ERR_FAIL_INDEX(p_line, text.size());
 	ERR_FAIL_COND(p_char < 0);
 
-	/* STEP 1 add spaces if the char is greater than the end of the line */
+	/* STEP 1 remove \r from source text and separate in substrings */
+
+	Vector<String> substrings = p_text.replace("\r", "").split("\n");
+
+	/* STEP 2 fire breakpoint_toggled signals */
+
+	// Is this just a new empty line?
+	bool shift_first_line = p_char == 0 && p_text.replace("\r", "") == "\n";
+
+	int i = p_line + !shift_first_line;
+	int lines = substrings.size() - 1;
+	for (; i < text.size(); i++) {
+		if (text.is_breakpoint(i)) {
+			if ((i - lines < p_line || !text.is_breakpoint(i - lines)) || (i - lines == p_line && !shift_first_line))
+				emit_signal("breakpoint_toggled", i);
+			if (i + lines >= text.size() || !text.is_breakpoint(i + lines))
+				emit_signal("breakpoint_toggled", i + lines);
+		}
+	}
+
+	/* STEP 3 add spaces if the char is greater than the end of the line */
 	while (p_char > text[p_line].length()) {
 
 		text.set(p_line, text[p_line] + String::chr(' '));
 	}
 
-	/* STEP 2 separate dest string in pre and post text */
+	/* STEP 4 separate dest string in pre and post text */
 
 	String preinsert_text = text[p_line].substr(0, p_char);
 	String postinsert_text = text[p_line].substr(p_char, text[p_line].size());
 
-	/* STEP 3 remove \r from source text and separate in substrings */
-
-	//buh bye \r and split
-	Vector<String> substrings = p_text.replace("\r", "").split("\n");
-
 	for (int i = 0; i < substrings.size(); i++) {
 		//insert the substrings
 
@@ -3331,9 +3349,7 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
 		}
 	}
 
-	// if we are just making a new empty line, reset breakpoints and hidden status
-	if (p_char == 0 && p_text.replace("\r", "") == "\n") {
-
+	if (shift_first_line) {
 		text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line));
 		text.set_hidden(p_line + 1, text.is_hidden(p_line));
 		text.set_breakpoint(p_line, false);
@@ -3389,11 +3405,20 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
 	String pre_text = text[p_from_line].substr(0, p_from_column);
 	String post_text = text[p_to_line].substr(p_to_column, text[p_to_line].length());
 
-	for (int i = p_from_line; i < p_to_line; i++) {
+	int lines = p_to_line - p_from_line;
 
-		text.remove(p_from_line + 1);
+	for (int i = p_from_line + 1; i < text.size(); i++) {
+		if (text.is_breakpoint(i)) {
+			if (i + lines >= text.size() || !text.is_breakpoint(i + lines))
+				emit_signal("breakpoint_toggled", i);
+			if (i > p_to_line && (i - lines < 0 || !text.is_breakpoint(i - lines)))
+				emit_signal("breakpoint_toggled", i - lines);
+		}
 	}
 
+	for (int i = p_from_line; i < p_to_line; i++) {
+		text.remove(p_from_line + 1);
+	}
 	text.set(p_from_line, pre_text + post_text);
 
 	text.set_line_wrap_amount(p_from_line, -1);
@@ -4866,6 +4891,24 @@ void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
 	}
 }
 
+Array TextEdit::get_breakpoints_array() const {
+
+	Array arr;
+	for (int i = 0; i < text.size(); i++) {
+		if (text.is_breakpoint(i))
+			arr.append(i);
+	}
+	return arr;
+}
+
+void TextEdit::remove_breakpoints() {
+	for (int i = 0; i < text.size(); i++) {
+		if (text.is_breakpoint(i))
+			/* Should "breakpoint_toggled" be fired when breakpoints are removed this way? */
+			text.set_breakpoint(i, false);
+	}
+}
+
 void TextEdit::set_line_as_hidden(int p_line, bool p_hidden) {
 
 	ERR_FAIL_INDEX(p_line, text.size());
@@ -5854,12 +5897,12 @@ void TextEdit::set_line_length_guideline_column(int p_column) {
 	update();
 }
 
-void TextEdit::set_draw_breakpoint_gutter(bool p_draw) {
+void TextEdit::set_breakpoint_gutter_enabled(bool p_draw) {
 	draw_breakpoint_gutter = p_draw;
 	update();
 }
 
-bool TextEdit::is_drawing_breakpoint_gutter() const {
+bool TextEdit::is_breakpoint_gutter_enabled() const {
 	return draw_breakpoint_gutter;
 }
 
@@ -6042,6 +6085,8 @@ void TextEdit::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("set_show_line_numbers", "enable"), &TextEdit::set_show_line_numbers);
 	ClassDB::bind_method(D_METHOD("is_show_line_numbers_enabled"), &TextEdit::is_show_line_numbers_enabled);
+	ClassDB::bind_method(D_METHOD("set_breakpoint_gutter_enabled", "enable"), &TextEdit::set_breakpoint_gutter_enabled);
+	ClassDB::bind_method(D_METHOD("is_breakpoint_gutter_enabled"), &TextEdit::is_breakpoint_gutter_enabled);
 
 	ClassDB::bind_method(D_METHOD("set_hiding_enabled", "enable"), &TextEdit::set_hiding_enabled);
 	ClassDB::bind_method(D_METHOD("is_hiding_enabled"), &TextEdit::is_hiding_enabled);
@@ -6080,11 +6125,15 @@ void TextEdit::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option);
 	ClassDB::bind_method(D_METHOD("get_menu"), &TextEdit::get_menu);
 
+	ClassDB::bind_method(D_METHOD("get_breakpoints"), &TextEdit::get_breakpoints_array);
+	ClassDB::bind_method(D_METHOD("remove_breakpoints"), &TextEdit::remove_breakpoints);
+
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "readonly"), "set_readonly", "is_readonly");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "breakpoint_gutter"), "set_breakpoint_gutter_enabled", "is_breakpoint_gutter_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");

+ 4 - 2
scene/gui/text_edit.h

@@ -473,6 +473,8 @@ public:
 	void set_line_as_breakpoint(int p_line, bool p_breakpoint);
 	bool is_line_set_as_breakpoint(int p_line) const;
 	void get_breakpoints(List<int> *p_breakpoints) const;
+	Array get_breakpoints_array() const;
+	void remove_breakpoints();
 
 	void set_line_as_hidden(int p_line, bool p_hidden);
 	bool is_line_hidden(int p_line) const;
@@ -632,8 +634,8 @@ public:
 	void set_show_line_length_guideline(bool p_show);
 	void set_line_length_guideline_column(int p_column);
 
-	void set_draw_breakpoint_gutter(bool p_draw);
-	bool is_drawing_breakpoint_gutter() const;
+	void set_breakpoint_gutter_enabled(bool p_draw);
+	bool is_breakpoint_gutter_enabled() const;
 
 	void set_breakpoint_gutter_width(int p_gutter_width);
 	int get_breakpoint_gutter_width() const;