Add mutliple Caret support to TextEdit
This commit is contained in:
parent
7dd3857f7e
commit
4a9d4e3dad
5 changed files with 2694 additions and 1339 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
void set_caret_column(int p_col, bool p_adjust_viewport = true);
|
||||
int get_caret_column() 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);
|
||||
|
||||
int get_caret_wrap_index() const;
|
||||
bool is_caret_visible(int p_caret = 0) const;
|
||||
Point2 get_caret_draw_pos(int p_caret = 0) const;
|
||||
|
||||
String get_word_under_caret() 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 p_caret = 0);
|
||||
int get_caret_column(int p_caret = 0) const;
|
||||
|
||||
int get_caret_wrap_index(int p_caret = 0) 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);
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue