Преглед изворни кода

Add mutliple Caret support to TextEdit

Paulb23 пре 3 година
родитељ
комит
4a9d4e3dad
5 измењених фајлова са 1179 додато и 722 уклоњено
  1. 2 2
      scene/gui/code_edit.cpp
  2. 2 2
      scene/gui/code_edit.h
  3. 722 566
      scene/gui/text_edit.cpp
  4. 97 47
      scene/gui/text_edit.h
  5. 356 105
      tests/scene/test_text_edit.h

+ 2 - 2
scene/gui/code_edit.cpp

@@ -609,7 +609,7 @@ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
 /* Text manipulation */
 
 // Overridable actions
-void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
+void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode, int p_caret) {
 	bool had_selection = has_selection();
 	String selection_text = (had_selection ? get_selected_text() : "");
 
@@ -674,7 +674,7 @@ void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
 	}
 }
 
-void CodeEdit::_backspace_internal() {
+void CodeEdit::_backspace_internal(int p_caret) {
 	if (!is_editable()) {
 		return;
 	}

+ 2 - 2
scene/gui/code_edit.h

@@ -261,8 +261,8 @@ protected:
 	/* Text manipulation */
 
 	// Overridable actions
-	virtual void _handle_unicode_input_internal(const uint32_t p_unicode) override;
-	virtual void _backspace_internal() override;
+	virtual void _handle_unicode_input_internal(const uint32_t p_unicode, int p_caret) override;
+	virtual void _backspace_internal(int p_caret) override;
 
 	GDVIRTUAL1(_confirm_code_completion, bool)
 	GDVIRTUAL1(_request_code_completion, bool)

Разлика између датотеке није приказан због своје велике величине
+ 722 - 566
scene/gui/text_edit.cpp


+ 97 - 47
scene/gui/text_edit.h

@@ -42,6 +42,14 @@ class TextEdit : public Control {
 	GDCLASS(TextEdit, Control);
 
 public:
+	/* Edit Actions. */
+	enum EditAction {
+		ACTION_NONE,
+		ACTION_TYPING,
+		ACTION_BACKSPACE,
+		ACTION_DELETE,
+	};
+
 	/* Caret. */
 	enum CaretType {
 		CARET_TYPE_LINE,
@@ -299,12 +307,15 @@ private:
 	Key _get_menu_action_accelerator(const String &p_action);
 
 	/* Versioning */
+	struct Caret;
 	struct TextOperation {
 		enum Type {
 			TYPE_NONE,
 			TYPE_INSERT,
 			TYPE_REMOVE
 		};
+		Vector<Caret> start_carets;
+		Vector<Caret> end_carets;
 
 		Type type = TYPE_NONE;
 		int from_line = 0;
@@ -321,6 +332,10 @@ private:
 	bool undo_enabled = true;
 	int undo_stack_max_size = 50;
 
+	EditAction current_action = EditAction::ACTION_NONE;
+	bool pending_action_end = false;
+	bool in_action = false;
+
 	int complex_operation_count = 0;
 	bool next_operation_is_complex = false;
 
@@ -385,10 +400,15 @@ private:
 		int last_fit_x = 0;
 		int line = 0;
 		int column = 0;
-	} caret;
+	};
+
+	// Vector containing all the carets, index '0' is the "main caret" and should never be removed.
+	Vector<Caret> carets;
+	Vector<int> caret_index_edit_order;
 
 	bool setting_caret_line = false;
 	bool caret_pos_dirty = false;
+	bool caret_index_edit_dirty = true;
 
 	Color caret_color = Color(1, 1, 1);
 	Color caret_background_color = Color(0, 0, 0);
@@ -404,6 +424,8 @@ private:
 
 	bool caret_mid_grapheme_enabled = true;
 
+	bool multi_carets_enabled = true;
+
 	bool drag_action = false;
 	bool drag_caret_force_displayed = false;
 
@@ -412,7 +434,7 @@ private:
 	void _reset_caret_blink_timer();
 	void _toggle_draw_caret();
 
-	int _get_column_x_offset_for_line(int p_char, int p_line) const;
+	int _get_column_x_offset_for_line(int p_char, int p_line, int p_column) const;
 
 	/* Selection. */
 	SelectionMode selecting_mode = SelectionMode::SELECTION_MODE_NONE;
@@ -437,8 +459,8 @@ private:
 	void _update_selection_mode_word();
 	void _update_selection_mode_line();
 
-	void _pre_shift_selection();
-	void _post_shift_selection();
+	void _pre_shift_selection(int p_caret);
+	void _post_shift_selection(int p_caret);
 
 	/* Line wrapping. */
 	LineWrappingMode line_wrapping_mode = LineWrappingMode::LINE_WRAPPING_NONE;
@@ -583,6 +605,17 @@ protected:
 
 	/* Internal API for CodeEdit, pending public API. */
 	// brace matching
+	struct BraceMatchingData {
+		int open_match_line = -1;
+		int open_match_column = -1;
+		bool open_matching = false;
+		bool open_mismatch = false;
+		int close_match_line = -1;
+		int close_match_column = -1;
+		bool close_matching = false;
+		bool close_mismatch = false;
+	};
+
 	bool highlight_matching_braces_enabled = false;
 	Color brace_mismatch_color;
 
@@ -607,20 +640,20 @@ protected:
 	/* Text manipulation */
 
 	// Overridable actions
-	virtual void _handle_unicode_input_internal(const uint32_t p_unicode);
-	virtual void _backspace_internal();
+	virtual void _handle_unicode_input_internal(const uint32_t p_unicode, int p_caret);
+	virtual void _backspace_internal(int p_caret);
 
-	virtual void _cut_internal();
-	virtual void _copy_internal();
-	virtual void _paste_internal();
-	virtual void _paste_primary_clipboard_internal();
+	virtual void _cut_internal(int p_caret);
+	virtual void _copy_internal(int p_caret);
+	virtual void _paste_internal(int p_caret);
+	virtual void _paste_primary_clipboard_internal(int p_caret);
 
-	GDVIRTUAL1(_handle_unicode_input, int)
-	GDVIRTUAL0(_backspace)
-	GDVIRTUAL0(_cut)
-	GDVIRTUAL0(_copy)
-	GDVIRTUAL0(_paste)
-	GDVIRTUAL0(_paste_primary_clipboard)
+	GDVIRTUAL2(_handle_unicode_input, int, int)
+	GDVIRTUAL1(_backspace, int)
+	GDVIRTUAL1(_cut, int)
+	GDVIRTUAL1(_copy, int)
+	GDVIRTUAL1(_paste, int)
+	GDVIRTUAL1(_paste_primary_clipboard, int)
 
 public:
 	/* General overrides. */
@@ -696,7 +729,7 @@ public:
 	void swap_lines(int p_from_line, int p_to_line);
 
 	void insert_line_at(int p_at, const String &p_text);
-	void insert_text_at_caret(const String &p_text);
+	void insert_text_at_caret(const String &p_text, int p_caret = -1);
 
 	void remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column);
 
@@ -705,13 +738,13 @@ public:
 	Point2i get_next_visible_line_index_offset_from(int p_line_from, int p_wrap_index_from, int p_visible_amount) const;
 
 	// Overridable actions
-	void handle_unicode_input(const uint32_t p_unicode);
-	void backspace();
+	void handle_unicode_input(const uint32_t p_unicode, int p_caret = -1);
+	void backspace(int p_caret = -1);
 
-	void cut();
-	void copy();
-	void paste();
-	void paste_primary_clipboard();
+	void cut(int p_caret = -1);
+	void copy(int p_caret = -1);
+	void paste(int p_caret = -1);
+	void paste_primary_clipboard(int p_caret = -1);
 
 	// Context menu.
 	PopupMenu *get_menu() const;
@@ -719,6 +752,10 @@ public:
 	void menu_option(int p_option);
 
 	/* Versioning */
+	void start_action(EditAction p_action);
+	void end_action();
+	EditAction get_current_action() const;
+
 	void begin_complex_operation();
 	void end_complex_operation();
 
@@ -753,7 +790,7 @@ public:
 	int get_minimap_line_at_pos(const Point2i &p_pos) const;
 
 	bool is_dragging_cursor() const;
-	bool is_mouse_over_selection(bool p_edges = true) const;
+	bool is_mouse_over_selection(bool p_edges = true, int p_caret = -1) const;
 
 	/* Caret */
 	void set_caret_type(CaretType p_type);
@@ -771,18 +808,30 @@ public:
 	void set_caret_mid_grapheme_enabled(const bool p_enabled);
 	bool is_caret_mid_grapheme_enabled() const;
 
-	bool is_caret_visible() const;
-	Point2 get_caret_draw_pos() const;
+	void set_multiple_carets_enabled(bool p_enabled);
+	bool is_multiple_carets_enabled() const;
+
+	int add_caret(int p_line, int p_col);
+	void remove_caret(int p_caret);
+	void remove_secondary_carets();
+	void merge_overlapping_carets();
+	int get_caret_count() const;
+
+	Vector<int> get_caret_index_edit_order();
+	void adjust_carets_after_edit(int p_caret, int p_from_line, int p_from_col, int p_to_line, int p_to_col);
+
+	bool is_caret_visible(int p_caret = 0) const;
+	Point2 get_caret_draw_pos(int p_caret = 0) const;
 
-	void set_caret_line(int p_line, bool p_adjust_viewport = true, bool p_can_be_hidden = true, int p_wrap_index = 0);
-	int get_caret_line() const;
+	void set_caret_line(int p_line, bool p_adjust_viewport = true, bool p_can_be_hidden = true, int p_wrap_index = 0, int p_caret = 0);
+	int get_caret_line(int p_caret = 0) const;
 
-	void set_caret_column(int p_col, bool p_adjust_viewport = true);
-	int get_caret_column() const;
+	void set_caret_column(int p_col, bool p_adjust_viewport = true, int p_caret = 0);
+	int get_caret_column(int p_caret = 0) const;
 
-	int get_caret_wrap_index() const;
+	int get_caret_wrap_index(int p_caret = 0) const;
 
-	String get_word_under_caret() const;
+	String get_word_under_caret(int p_caret = -1) const;
 
 	/* Selection. */
 	void set_selecting_enabled(const bool p_enabled);
@@ -797,27 +846,27 @@ public:
 	void set_override_selected_font_color(bool p_override_selected_font_color);
 	bool is_overriding_selected_font_color() const;
 
-	void set_selection_mode(SelectionMode p_mode, int p_line = -1, int p_column = -1);
+	void set_selection_mode(SelectionMode p_mode, int p_line = -1, int p_column = -1, int p_caret = 0);
 	SelectionMode get_selection_mode() const;
 
 	void select_all();
-	void select_word_under_caret();
-	void select(int p_from_line, int p_from_column, int p_to_line, int p_to_column);
+	void select_word_under_caret(int p_caret = -1);
+	void select(int p_from_line, int p_from_column, int p_to_line, int p_to_column, int p_caret = 0);
 
-	bool has_selection() const;
+	bool has_selection(int p_caret = -1) const;
 
-	String get_selected_text() const;
+	String get_selected_text(int p_caret = -1);
 
-	int get_selection_line() const;
-	int get_selection_column() const;
+	int get_selection_line(int p_caret = 0) const;
+	int get_selection_column(int p_caret = 0) const;
 
-	int get_selection_from_line() const;
-	int get_selection_from_column() const;
-	int get_selection_to_line() const;
-	int get_selection_to_column() const;
+	int get_selection_from_line(int p_caret = 0) const;
+	int get_selection_from_column(int p_caret = 0) const;
+	int get_selection_to_line(int p_caret = 0) const;
+	int get_selection_to_column(int p_caret = 0) const;
 
-	void deselect();
-	void delete_selection();
+	void deselect(int p_caret = -1);
+	void delete_selection(int p_caret = -1);
 
 	/* Line wrapping. */
 	void set_line_wrapping_mode(LineWrappingMode p_wrapping_mode);
@@ -866,8 +915,8 @@ public:
 	int get_total_visible_line_count() const;
 
 	// Auto Adjust
-	void adjust_viewport_to_caret();
-	void center_viewport_to_caret();
+	void adjust_viewport_to_caret(int p_caret = 0);
+	void center_viewport_to_caret(int p_caret = 0);
 
 	// Minimap
 	void set_draw_minimap(bool p_enabled);
@@ -949,6 +998,7 @@ public:
 	TextEdit(const String &p_placeholder = String());
 };
 
+VARIANT_ENUM_CAST(TextEdit::EditAction);
 VARIANT_ENUM_CAST(TextEdit::CaretType);
 VARIANT_ENUM_CAST(TextEdit::LineWrappingMode);
 VARIANT_ENUM_CAST(TextEdit::SelectionMode);

Разлика између датотеке није приказан због своје велике величине
+ 356 - 105
tests/scene/test_text_edit.h


Неке датотеке нису приказане због велике количине промена