1/**************************************************************************/
2/* text_edit.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef TEXT_EDIT_H
32#define TEXT_EDIT_H
33
34#include "scene/gui/control.h"
35#include "scene/gui/popup_menu.h"
36#include "scene/gui/scroll_bar.h"
37#include "scene/main/timer.h"
38#include "scene/resources/syntax_highlighter.h"
39#include "scene/resources/text_paragraph.h"
40
41class TextEdit : public Control {
42 GDCLASS(TextEdit, Control);
43
44 friend class CodeHighlighter;
45
46public:
47 /* Edit Actions. */
48 enum EditAction {
49 ACTION_NONE,
50 ACTION_TYPING,
51 ACTION_BACKSPACE,
52 ACTION_DELETE,
53 };
54
55 /* Caret. */
56 enum CaretType {
57 CARET_TYPE_LINE,
58 CARET_TYPE_BLOCK
59 };
60
61 /* Selection */
62 enum SelectionMode {
63 SELECTION_MODE_NONE,
64 SELECTION_MODE_SHIFT,
65 SELECTION_MODE_POINTER,
66 SELECTION_MODE_WORD,
67 SELECTION_MODE_LINE
68 };
69
70 /* Line Wrapping.*/
71 enum LineWrappingMode {
72 LINE_WRAPPING_NONE,
73 LINE_WRAPPING_BOUNDARY
74 };
75
76 /* Gutters. */
77 enum GutterType {
78 GUTTER_TYPE_STRING,
79 GUTTER_TYPE_ICON,
80 GUTTER_TYPE_CUSTOM
81 };
82
83 /* Context Menu. */
84 enum MenuItems {
85 MENU_CUT,
86 MENU_COPY,
87 MENU_PASTE,
88 MENU_CLEAR,
89 MENU_SELECT_ALL,
90 MENU_UNDO,
91 MENU_REDO,
92 MENU_SUBMENU_TEXT_DIR,
93 MENU_DIR_INHERITED,
94 MENU_DIR_AUTO,
95 MENU_DIR_LTR,
96 MENU_DIR_RTL,
97 MENU_DISPLAY_UCC,
98 MENU_SUBMENU_INSERT_UCC,
99 MENU_INSERT_LRM,
100 MENU_INSERT_RLM,
101 MENU_INSERT_LRE,
102 MENU_INSERT_RLE,
103 MENU_INSERT_LRO,
104 MENU_INSERT_RLO,
105 MENU_INSERT_PDF,
106 MENU_INSERT_ALM,
107 MENU_INSERT_LRI,
108 MENU_INSERT_RLI,
109 MENU_INSERT_FSI,
110 MENU_INSERT_PDI,
111 MENU_INSERT_ZWJ,
112 MENU_INSERT_ZWNJ,
113 MENU_INSERT_WJ,
114 MENU_INSERT_SHY,
115 MENU_MAX
116
117 };
118
119 /* Search. */
120 enum SearchFlags {
121 SEARCH_MATCH_CASE = 1,
122 SEARCH_WHOLE_WORDS = 2,
123 SEARCH_BACKWARDS = 4
124 };
125
126private:
127 struct GutterInfo {
128 GutterType type = GutterType::GUTTER_TYPE_STRING;
129 String name = "";
130 int width = 24;
131 bool draw = true;
132 bool clickable = false;
133 bool overwritable = false;
134
135 Callable custom_draw_callback;
136 };
137
138 class Text {
139 public:
140 struct Gutter {
141 Variant metadata;
142 bool clickable = false;
143
144 Ref<Texture2D> icon = Ref<Texture2D>();
145 String text = "";
146 Color color = Color(1, 1, 1);
147 };
148
149 struct Line {
150 Vector<Gutter> gutters;
151
152 String data;
153 Array bidi_override;
154 Ref<TextParagraph> data_buf;
155
156 Color background_color = Color(0, 0, 0, 0);
157 bool hidden = false;
158 int height = 0;
159 int width = 0;
160
161 Line() {
162 data_buf.instantiate();
163 }
164 };
165
166 private:
167 bool is_dirty = false;
168 bool tab_size_dirty = false;
169
170 mutable Vector<Line> text;
171 Ref<Font> font;
172 int font_size = -1;
173 int font_height = 0;
174
175 String language;
176 TextServer::Direction direction = TextServer::DIRECTION_AUTO;
177 BitField<TextServer::LineBreakFlag> brk_flags = TextServer::BREAK_MANDATORY;
178 bool draw_control_chars = false;
179
180 int line_height = -1;
181 int max_width = -1;
182 int width = -1;
183
184 int tab_size = 4;
185 int gutter_count = 0;
186
187 void _calculate_line_height();
188 void _calculate_max_line_width();
189
190 public:
191 void set_tab_size(int p_tab_size);
192 int get_tab_size() const;
193 void set_font(const Ref<Font> &p_font);
194 void set_font_size(int p_font_size);
195 void set_direction_and_language(TextServer::Direction p_direction, const String &p_language);
196 void set_draw_control_chars(bool p_enabled);
197
198 int get_line_height() const;
199 int get_line_width(int p_line, int p_wrap_index = -1) const;
200 int get_max_width() const;
201
202 void set_width(float p_width);
203 float get_width() const;
204 void set_brk_flags(BitField<TextServer::LineBreakFlag> p_flags);
205 BitField<TextServer::LineBreakFlag> get_brk_flags() const;
206 int get_line_wrap_amount(int p_line) const;
207
208 Vector<Vector2i> get_line_wrap_ranges(int p_line) const;
209 const Ref<TextParagraph> get_line_data(int p_line) const;
210
211 void set(int p_line, const String &p_text, const Array &p_bidi_override);
212 void set_hidden(int p_line, bool p_hidden) {
213 if (text[p_line].hidden == p_hidden) {
214 return;
215 }
216 text.write[p_line].hidden = p_hidden;
217 if (!p_hidden && text[p_line].width > max_width) {
218 max_width = text[p_line].width;
219 } else if (p_hidden && text[p_line].width == max_width) {
220 _calculate_max_line_width();
221 }
222 }
223 bool is_hidden(int p_line) const { return text[p_line].hidden; }
224 void insert(int p_at, const Vector<String> &p_text, const Vector<Array> &p_bidi_override);
225 void remove_range(int p_from_line, int p_to_line);
226 int size() const { return text.size(); }
227 void clear();
228
229 void invalidate_cache(int p_line, int p_column = -1, bool p_text_changed = false, const String &p_ime_text = String(), const Array &p_bidi_override = Array());
230 void invalidate_font();
231 void invalidate_all();
232 void invalidate_all_lines();
233
234 _FORCE_INLINE_ const String &operator[](int p_line) const;
235
236 /* Gutters. */
237 void add_gutter(int p_at);
238 void remove_gutter(int p_gutter);
239 void move_gutters(int p_from_line, int p_to_line);
240
241 void set_line_gutter_metadata(int p_line, int p_gutter, const Variant &p_metadata) { text.write[p_line].gutters.write[p_gutter].metadata = p_metadata; }
242 const Variant &get_line_gutter_metadata(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].metadata; }
243
244 void set_line_gutter_text(int p_line, int p_gutter, const String &p_text) { text.write[p_line].gutters.write[p_gutter].text = p_text; }
245 const String &get_line_gutter_text(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].text; }
246
247 void set_line_gutter_icon(int p_line, int p_gutter, const Ref<Texture2D> &p_icon) { text.write[p_line].gutters.write[p_gutter].icon = p_icon; }
248 const Ref<Texture2D> &get_line_gutter_icon(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].icon; }
249
250 void set_line_gutter_item_color(int p_line, int p_gutter, const Color &p_color) { text.write[p_line].gutters.write[p_gutter].color = p_color; }
251 const Color &get_line_gutter_item_color(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].color; }
252
253 void set_line_gutter_clickable(int p_line, int p_gutter, bool p_clickable) { text.write[p_line].gutters.write[p_gutter].clickable = p_clickable; }
254 bool is_line_gutter_clickable(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].clickable; }
255
256 /* Line style. */
257 void set_line_background_color(int p_line, const Color &p_color) { text.write[p_line].background_color = p_color; }
258 const Color get_line_background_color(int p_line) const { return text[p_line].background_color; }
259 };
260
261 /* Text */
262 Text text;
263
264 bool setting_text = false;
265
266 bool alt_start = false;
267 uint32_t alt_code = 0;
268
269 // Text properties.
270 String ime_text = "";
271 Point2 ime_selection;
272
273 // Placeholder
274 String placeholder_text = "";
275 Array placeholder_bidi_override;
276 Ref<TextParagraph> placeholder_data_buf;
277 int placeholder_line_height = -1;
278 int placeholder_max_width = -1;
279
280 Vector<String> placeholder_wraped_rows;
281
282 void _update_placeholder();
283
284 /* Initialize to opposite first, so we get past the early-out in set_editable. */
285 bool editable = false;
286
287 TextDirection text_direction = TEXT_DIRECTION_AUTO;
288 TextDirection input_direction = TEXT_DIRECTION_LTR;
289
290 String language = "";
291
292 TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
293 Array st_args;
294
295 void _clear();
296 void _update_caches();
297
298 // User control.
299 bool overtype_mode = false;
300 bool context_menu_enabled = true;
301 bool shortcut_keys_enabled = true;
302 bool virtual_keyboard_enabled = true;
303 bool middle_mouse_paste_enabled = true;
304
305 // Overridable actions.
306 String cut_copy_line = "";
307
308 // Context menu.
309 PopupMenu *menu = nullptr;
310 PopupMenu *menu_dir = nullptr;
311 PopupMenu *menu_ctl = nullptr;
312
313 Key _get_menu_action_accelerator(const String &p_action);
314 void _generate_context_menu();
315 void _update_context_menu();
316
317 /* Versioning */
318 struct Caret;
319 struct TextOperation {
320 enum Type {
321 TYPE_NONE,
322 TYPE_INSERT,
323 TYPE_REMOVE
324 };
325 Vector<Caret> start_carets;
326 Vector<Caret> end_carets;
327
328 Type type = TYPE_NONE;
329 int from_line = 0;
330 int from_column = 0;
331 int to_line = 0;
332 int to_column = 0;
333 String text;
334 uint32_t prev_version = 0;
335 uint32_t version = 0;
336 bool chain_forward = false;
337 bool chain_backward = false;
338 };
339
340 bool undo_enabled = true;
341 int undo_stack_max_size = 50;
342
343 EditAction current_action = EditAction::ACTION_NONE;
344 bool pending_action_end = false;
345 bool in_action = false;
346
347 int complex_operation_count = 0;
348 bool next_operation_is_complex = false;
349
350 TextOperation current_op;
351 List<TextOperation> undo_stack;
352 List<TextOperation>::Element *undo_stack_pos = nullptr;
353
354 Timer *idle_detect = nullptr;
355
356 uint32_t version = 0;
357 uint32_t saved_version = 0;
358
359 void _push_current_op();
360 void _do_text_op(const TextOperation &p_op, bool p_reverse);
361 void _clear_redo();
362
363 /* Search */
364 String search_text = "";
365 uint32_t search_flags = 0;
366
367 int _get_column_pos_of_word(const String &p_key, const String &p_search, uint32_t p_search_flags, int p_from_column) const;
368
369 /* Tooltip. */
370 Callable tooltip_callback;
371
372 /* Mouse */
373 struct LineDrawingCache {
374 int y_offset = 0;
375 Vector<int> first_visible_chars;
376 Vector<int> last_visible_chars;
377 };
378
379 HashMap<int, LineDrawingCache> line_drawing_cache;
380
381 int _get_char_pos_for_line(int p_px, int p_line, int p_wrap_index = 0) const;
382
383 /* Caret. */
384 struct Selection {
385 bool active = false;
386 bool shiftclick_left = false;
387
388 int selecting_line = 0;
389 int selecting_column = 0;
390 int selected_word_beg = 0;
391 int selected_word_end = 0;
392 int selected_word_origin = 0;
393
394 int from_line = 0;
395 int from_column = 0;
396 int to_line = 0;
397 int to_column = 0;
398 };
399
400 struct Caret {
401 Selection selection;
402
403 Point2 draw_pos;
404 bool visible = false;
405 int last_fit_x = 0;
406 int line = 0;
407 int column = 0;
408 };
409
410 // Vector containing all the carets, index '0' is the "main caret" and should never be removed.
411 Vector<Caret> carets;
412 Vector<int> caret_index_edit_order;
413
414 bool setting_caret_line = false;
415 bool caret_pos_dirty = false;
416 bool caret_index_edit_dirty = true;
417
418 CaretType caret_type = CaretType::CARET_TYPE_LINE;
419
420 bool draw_caret = true;
421 bool draw_caret_when_editable_disabled = false;
422
423 bool caret_blink_enabled = false;
424 Timer *caret_blink_timer = nullptr;
425
426 bool move_caret_on_right_click = true;
427
428 bool caret_mid_grapheme_enabled = false;
429
430 bool multi_carets_enabled = true;
431
432 bool drag_action = false;
433 bool drag_caret_force_displayed = false;
434
435 void _emit_caret_changed();
436
437 void _reset_caret_blink_timer();
438 void _toggle_draw_caret();
439
440 int _get_column_x_offset_for_line(int p_char, int p_line, int p_column) const;
441
442 /* Selection. */
443 SelectionMode selecting_mode = SelectionMode::SELECTION_MODE_NONE;
444
445 bool selecting_enabled = true;
446 bool deselect_on_focus_loss_enabled = true;
447 bool drag_and_drop_selection_enabled = true;
448
449 bool use_selected_font_color = false;
450
451 bool selection_drag_attempt = false;
452 bool dragging_selection = false;
453
454 Timer *click_select_held = nullptr;
455 uint64_t last_dblclk = 0;
456 Vector2 last_dblclk_pos;
457 void _click_selection_held();
458
459 void _update_selection_mode_pointer();
460 void _update_selection_mode_word();
461 void _update_selection_mode_line();
462
463 void _pre_shift_selection(int p_caret);
464 void _post_shift_selection(int p_caret);
465
466 /* Line wrapping. */
467 LineWrappingMode line_wrapping_mode = LineWrappingMode::LINE_WRAPPING_NONE;
468 TextServer::AutowrapMode autowrap_mode = TextServer::AUTOWRAP_WORD_SMART;
469
470 int wrap_at_column = 0;
471 int wrap_right_offset = 10;
472
473 void _update_wrap_at_column(bool p_force = false);
474
475 /* Viewport. */
476 HScrollBar *h_scroll = nullptr;
477 VScrollBar *v_scroll = nullptr;
478
479 float content_height_cache = 0.0;
480 bool fit_content_height = false;
481 bool scroll_past_end_of_file_enabled = false;
482
483 // Smooth scrolling.
484 bool smooth_scroll_enabled = false;
485 float target_v_scroll = 0.0;
486 float v_scroll_speed = 80.0;
487
488 // Scrolling.
489 int first_visible_line = 0;
490 int first_visible_line_wrap_ofs = 0;
491 int first_visible_col = 0;
492
493 bool scrolling = false;
494 bool updating_scrolls = false;
495
496 void _update_scrollbars();
497 int _get_control_height() const;
498
499 void _v_scroll_input();
500 void _scroll_moved(double p_to_val);
501
502 double _get_visible_lines_offset() const;
503 double _get_v_scroll_offset() const;
504
505 void _scroll_up(real_t p_delta);
506 void _scroll_down(real_t p_delta);
507
508 void _scroll_lines_up();
509 void _scroll_lines_down();
510
511 // Minimap.
512 bool draw_minimap = false;
513
514 int minimap_width = 80;
515 Point2 minimap_char_size = Point2(1, 2);
516 int minimap_line_spacing = 1;
517
518 // Minimap scroll.
519 bool minimap_clicked = false;
520 bool hovering_minimap = false;
521 bool dragging_minimap = false;
522 bool can_drag_minimap = false;
523
524 double minimap_scroll_ratio = 0.0;
525 double minimap_scroll_click_pos = 0.0;
526
527 void _update_minimap_hover();
528 void _update_minimap_click();
529 void _update_minimap_drag();
530
531 /* Gutters. */
532 Vector<GutterInfo> gutters;
533 int gutters_width = 0;
534 int gutter_padding = 0;
535 Vector2i hovered_gutter = Vector2i(-1, -1); // X = gutter index, Y = row.
536
537 void _update_gutter_width();
538
539 /* Syntax highlighting. */
540 Ref<SyntaxHighlighter> syntax_highlighter;
541
542 Dictionary _get_line_syntax_highlighting(int p_line);
543
544 /* Visual. */
545 struct ThemeCache {
546 float base_scale = 1.0;
547
548 /* Search */
549 Color search_result_color = Color(1, 1, 1);
550 Color search_result_border_color = Color(1, 1, 1);
551
552 /* Caret */
553 int caret_width = 1;
554 Color caret_color = Color(1, 1, 1);
555 Color caret_background_color = Color(0, 0, 0);
556
557 /* Selection */
558 Color font_selected_color = Color(0, 0, 0, 0);
559 Color selection_color = Color(1, 1, 1);
560
561 /* Other visuals */
562 Ref<StyleBox> style_normal;
563 Ref<StyleBox> style_focus;
564 Ref<StyleBox> style_readonly;
565
566 Ref<Texture2D> tab_icon;
567 Ref<Texture2D> space_icon;
568
569 Ref<Font> font;
570 int font_size = 16;
571 Color font_color = Color(1, 1, 1);
572 Color font_readonly_color = Color(1, 1, 1);
573 Color font_placeholder_color = Color(1, 1, 1, 0.6);
574
575 int outline_size = 0;
576 Color outline_color = Color(1, 1, 1);
577
578 int line_spacing = 1;
579
580 Color background_color = Color(1, 1, 1);
581 Color current_line_color = Color(1, 1, 1);
582 Color word_highlighted_color = Color(1, 1, 1);
583 } theme_cache;
584
585 bool window_has_focus = true;
586 bool first_draw = true;
587
588 bool highlight_current_line = false;
589 bool highlight_all_occurrences = false;
590 bool draw_control_chars = false;
591 bool draw_tabs = false;
592 bool draw_spaces = false;
593
594 /*** Super internal Core API. Everything builds on it. ***/
595 bool text_changed_dirty = false;
596 void _text_changed_emit();
597
598 void _insert_text(int p_line, int p_char, const String &p_text, int *r_end_line = nullptr, int *r_end_char = nullptr);
599 void _remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column);
600
601 void _base_insert_text(int p_line, int p_char, const String &p_text, int &r_end_line, int &r_end_column);
602 String _base_get_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) const;
603 void _base_remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column);
604
605 /* Input actions. */
606 void _swap_current_input_direction();
607 void _new_line(bool p_split_current = true, bool p_above = false);
608 void _move_caret_left(bool p_select, bool p_move_by_word = false);
609 void _move_caret_right(bool p_select, bool p_move_by_word = false);
610 void _move_caret_up(bool p_select);
611 void _move_caret_down(bool p_select);
612 void _move_caret_to_line_start(bool p_select);
613 void _move_caret_to_line_end(bool p_select);
614 void _move_caret_page_up(bool p_select);
615 void _move_caret_page_down(bool p_select);
616 void _do_backspace(bool p_word = false, bool p_all_to_left = false);
617 void _delete(bool p_word = false, bool p_all_to_right = false);
618 void _move_caret_document_start(bool p_select);
619 void _move_caret_document_end(bool p_select);
620 bool _clear_carets_and_selection();
621
622 // Used in add_caret_at_carets
623 void _get_above_below_caret_line_column(int p_old_line, int p_old_wrap_index, int p_old_column, bool p_below, int &p_new_line, int &p_new_column, int p_last_fit_x = -1) const;
624
625protected:
626 void _notification(int p_what);
627 static void _bind_methods();
628
629 virtual void _update_theme_item_cache() override;
630
631 /* Internal API for CodeEdit, pending public API. */
632 // Brace matching.
633 struct BraceMatchingData {
634 int open_match_line = -1;
635 int open_match_column = -1;
636 bool open_matching = false;
637 bool open_mismatch = false;
638 int close_match_line = -1;
639 int close_match_column = -1;
640 bool close_matching = false;
641 bool close_mismatch = false;
642 };
643
644 bool highlight_matching_braces_enabled = false;
645
646 // Line hiding.
647 bool hiding_enabled = false;
648
649 void _set_hiding_enabled(bool p_enabled);
650 bool _is_hiding_enabled() const;
651
652 void _set_line_as_hidden(int p_line, bool p_hidden);
653 bool _is_line_hidden(int p_line) const;
654
655 void _unhide_all_lines();
656
657 // Symbol lookup.
658 String lookup_symbol_word;
659 void _set_symbol_lookup_word(const String &p_symbol);
660
661 // Theme items.
662 virtual Color _get_brace_mismatch_color() const { return Color(); };
663 virtual Color _get_code_folding_color() const { return Color(); };
664 virtual Ref<Texture2D> _get_folded_eol_icon() const { return Ref<Texture2D>(); };
665
666 /* Text manipulation */
667
668 // Overridable actions
669 virtual void _handle_unicode_input_internal(const uint32_t p_unicode, int p_caret);
670 virtual void _backspace_internal(int p_caret);
671
672 virtual void _cut_internal(int p_caret);
673 virtual void _copy_internal(int p_caret);
674 virtual void _paste_internal(int p_caret);
675 virtual void _paste_primary_clipboard_internal(int p_caret);
676
677 GDVIRTUAL2(_handle_unicode_input, int, int)
678 GDVIRTUAL1(_backspace, int)
679 GDVIRTUAL1(_cut, int)
680 GDVIRTUAL1(_copy, int)
681 GDVIRTUAL1(_paste, int)
682 GDVIRTUAL1(_paste_primary_clipboard, int)
683
684public:
685 /* General overrides. */
686 virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
687 virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
688 bool alt_input(const Ref<InputEvent> &p_gui_input);
689 virtual Size2 get_minimum_size() const override;
690 virtual bool is_text_field() const override;
691 virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override;
692 virtual Variant get_drag_data(const Point2 &p_point) override;
693 virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;
694 virtual void drop_data(const Point2 &p_point, const Variant &p_data) override;
695 virtual String get_tooltip(const Point2 &p_pos) const override;
696 void set_tooltip_request_func(const Callable &p_tooltip_callback);
697
698 /* Text */
699 // Text properties.
700 bool has_ime_text() const;
701
702 void set_editable(const bool p_editable);
703 bool is_editable() const;
704
705 void set_text_direction(TextDirection p_text_direction);
706 TextDirection get_text_direction() const;
707
708 void set_language(const String &p_language);
709 String get_language() const;
710
711 void set_structured_text_bidi_override(TextServer::StructuredTextParser p_parser);
712 TextServer::StructuredTextParser get_structured_text_bidi_override() const;
713 void set_structured_text_bidi_override_options(Array p_args);
714 Array get_structured_text_bidi_override_options() const;
715
716 void set_tab_size(const int p_size);
717 int get_tab_size() const;
718
719 // User controls
720 void set_overtype_mode_enabled(const bool p_enabled);
721 bool is_overtype_mode_enabled() const;
722
723 void set_context_menu_enabled(bool p_enabled);
724 bool is_context_menu_enabled() const;
725
726 void set_shortcut_keys_enabled(bool p_enabled);
727 bool is_shortcut_keys_enabled() const;
728
729 void set_virtual_keyboard_enabled(bool p_enabled);
730 bool is_virtual_keyboard_enabled() const;
731
732 void set_middle_mouse_paste_enabled(bool p_enabled);
733 bool is_middle_mouse_paste_enabled() const;
734
735 // Text manipulation
736 void clear();
737
738 void set_text(const String &p_text);
739 String get_text() const;
740
741 int get_line_count() const;
742
743 void set_placeholder(const String &p_text);
744 String get_placeholder() const;
745
746 void set_line(int p_line, const String &p_new_text);
747 String get_line(int p_line) const;
748
749 int get_line_width(int p_line, int p_wrap_index = -1) const;
750 int get_line_height() const;
751
752 int get_indent_level(int p_line) const;
753 int get_first_non_whitespace_column(int p_line) const;
754
755 void swap_lines(int p_from_line, int p_to_line);
756
757 void insert_line_at(int p_at, const String &p_text);
758 void insert_text_at_caret(const String &p_text, int p_caret = -1);
759
760 void remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column);
761
762 int get_last_unhidden_line() const;
763 int get_next_visible_line_offset_from(int p_line_from, int p_visible_amount) const;
764 Point2i get_next_visible_line_index_offset_from(int p_line_from, int p_wrap_index_from, int p_visible_amount) const;
765
766 // Overridable actions
767 void handle_unicode_input(const uint32_t p_unicode, int p_caret = -1);
768 void backspace(int p_caret = -1);
769
770 void cut(int p_caret = -1);
771 void copy(int p_caret = -1);
772 void paste(int p_caret = -1);
773 void paste_primary_clipboard(int p_caret = -1);
774
775 // Context menu.
776 PopupMenu *get_menu() const;
777 bool is_menu_visible() const;
778 void menu_option(int p_option);
779
780 /* Versioning */
781 void start_action(EditAction p_action);
782 void end_action();
783 EditAction get_current_action() const;
784
785 void begin_complex_operation();
786 void end_complex_operation();
787
788 bool has_undo() const;
789 bool has_redo() const;
790 void undo();
791 void redo();
792 void clear_undo_history();
793
794 bool is_insert_text_operation() const;
795
796 void tag_saved_version();
797
798 uint32_t get_version() const;
799 uint32_t get_saved_version() const;
800
801 /* Search */
802 void set_search_text(const String &p_search_text);
803 void set_search_flags(uint32_t p_flags);
804
805 Point2i search(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const;
806
807 /* Mouse */
808 Point2 get_local_mouse_pos() const;
809
810 String get_word_at_pos(const Vector2 &p_pos) const;
811
812 Point2i get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_of_bounds = true) const;
813 Point2i get_pos_at_line_column(int p_line, int p_column) const;
814 Rect2i get_rect_at_line_column(int p_line, int p_column) const;
815
816 int get_minimap_line_at_pos(const Point2i &p_pos) const;
817
818 bool is_dragging_cursor() const;
819 bool is_mouse_over_selection(bool p_edges = true, int p_caret = -1) const;
820
821 /* Caret */
822 void set_caret_type(CaretType p_type);
823 CaretType get_caret_type() const;
824
825 void set_caret_blink_enabled(const bool p_enabled);
826 bool is_caret_blink_enabled() const;
827
828 void set_caret_blink_interval(const float p_interval);
829 float get_caret_blink_interval() const;
830
831 void set_draw_caret_when_editable_disabled(bool p_enable);
832 bool is_drawing_caret_when_editable_disabled() const;
833
834 void set_move_caret_on_right_click_enabled(const bool p_enabled);
835 bool is_move_caret_on_right_click_enabled() const;
836
837 void set_caret_mid_grapheme_enabled(const bool p_enabled);
838 bool is_caret_mid_grapheme_enabled() const;
839
840 void set_multiple_carets_enabled(bool p_enabled);
841 bool is_multiple_carets_enabled() const;
842
843 int add_caret(int p_line, int p_col);
844 void remove_caret(int p_caret);
845 void remove_secondary_carets();
846 void merge_overlapping_carets();
847 int get_caret_count() const;
848 void add_caret_at_carets(bool p_below);
849
850 Vector<int> get_caret_index_edit_order();
851 void adjust_carets_after_edit(int p_caret, int p_from_line, int p_from_col, int p_to_line, int p_to_col);
852
853 bool is_caret_visible(int p_caret = 0) const;
854 Point2 get_caret_draw_pos(int p_caret = 0) const;
855
856 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);
857 int get_caret_line(int p_caret = 0) const;
858
859 void set_caret_column(int p_col, bool p_adjust_viewport = true, int p_caret = 0);
860 int get_caret_column(int p_caret = 0) const;
861
862 int get_caret_wrap_index(int p_caret = 0) const;
863
864 String get_word_under_caret(int p_caret = -1) const;
865
866 /* Selection. */
867 void set_selecting_enabled(const bool p_enabled);
868 bool is_selecting_enabled() const;
869
870 void set_deselect_on_focus_loss_enabled(const bool p_enabled);
871 bool is_deselect_on_focus_loss_enabled() const;
872
873 void set_drag_and_drop_selection_enabled(const bool p_enabled);
874 bool is_drag_and_drop_selection_enabled() const;
875
876 void set_selection_mode(SelectionMode p_mode, int p_line = -1, int p_column = -1, int p_caret = 0);
877 SelectionMode get_selection_mode() const;
878
879 void select_all();
880 void select_word_under_caret(int p_caret = -1);
881 void add_selection_for_next_occurrence();
882 void select(int p_from_line, int p_from_column, int p_to_line, int p_to_column, int p_caret = 0);
883
884 bool has_selection(int p_caret = -1) const;
885
886 String get_selected_text(int p_caret = -1);
887
888 int get_selection_line(int p_caret = 0) const;
889 int get_selection_column(int p_caret = 0) const;
890
891 int get_selection_from_line(int p_caret = 0) const;
892 int get_selection_from_column(int p_caret = 0) const;
893 int get_selection_to_line(int p_caret = 0) const;
894 int get_selection_to_column(int p_caret = 0) const;
895
896 void deselect(int p_caret = -1);
897 void delete_selection(int p_caret = -1);
898
899 /* Line wrapping. */
900 void set_line_wrapping_mode(LineWrappingMode p_wrapping_mode);
901 LineWrappingMode get_line_wrapping_mode() const;
902
903 void set_autowrap_mode(TextServer::AutowrapMode p_mode);
904 TextServer::AutowrapMode get_autowrap_mode() const;
905
906 bool is_line_wrapped(int p_line) const;
907 int get_line_wrap_count(int p_line) const;
908 int get_line_wrap_index_at_column(int p_line, int p_column) const;
909
910 Vector<String> get_line_wrapped_text(int p_line) const;
911
912 /* Viewport. */
913 // Scrolling.
914 void set_smooth_scroll_enabled(const bool p_enabled);
915 bool is_smooth_scroll_enabled() const;
916
917 void set_scroll_past_end_of_file_enabled(const bool p_enabled);
918 bool is_scroll_past_end_of_file_enabled() const;
919
920 VScrollBar *get_v_scroll_bar() const;
921 HScrollBar *get_h_scroll_bar() const;
922
923 void set_v_scroll(double p_scroll);
924 double get_v_scroll() const;
925
926 void set_h_scroll(int p_scroll);
927 int get_h_scroll() const;
928
929 void set_v_scroll_speed(float p_speed);
930 float get_v_scroll_speed() const;
931
932 void set_fit_content_height_enabled(const bool p_enabled);
933 bool is_fit_content_height_enabled() const;
934
935 double get_scroll_pos_for_line(int p_line, int p_wrap_index = 0) const;
936
937 // Visible lines.
938 void set_line_as_first_visible(int p_line, int p_wrap_index = 0);
939 int get_first_visible_line() const;
940
941 void set_line_as_center_visible(int p_line, int p_wrap_index = 0);
942
943 void set_line_as_last_visible(int p_line, int p_wrap_index = 0);
944 int get_last_full_visible_line() const;
945 int get_last_full_visible_line_wrap_index() const;
946
947 int get_visible_line_count() const;
948 int get_visible_line_count_in_range(int p_from, int p_to) const;
949 int get_total_visible_line_count() const;
950
951 // Auto Adjust
952 void adjust_viewport_to_caret(int p_caret = 0);
953 void center_viewport_to_caret(int p_caret = 0);
954
955 // Minimap
956 void set_draw_minimap(bool p_enabled);
957 bool is_drawing_minimap() const;
958
959 void set_minimap_width(int p_minimap_width);
960 int get_minimap_width() const;
961
962 int get_minimap_visible_lines() const;
963
964 /* Gutters. */
965 void add_gutter(int p_at = -1);
966 void remove_gutter(int p_gutter);
967 int get_gutter_count() const;
968
969 void set_gutter_name(int p_gutter, const String &p_name);
970 String get_gutter_name(int p_gutter) const;
971
972 void set_gutter_type(int p_gutter, GutterType p_type);
973 GutterType get_gutter_type(int p_gutter) const;
974
975 void set_gutter_width(int p_gutter, int p_width);
976 int get_gutter_width(int p_gutter) const;
977 int get_total_gutter_width() const;
978
979 void set_gutter_draw(int p_gutter, bool p_draw);
980 bool is_gutter_drawn(int p_gutter) const;
981
982 void set_gutter_clickable(int p_gutter, bool p_clickable);
983 bool is_gutter_clickable(int p_gutter) const;
984
985 void set_gutter_overwritable(int p_gutter, bool p_overwritable);
986 bool is_gutter_overwritable(int p_gutter) const;
987
988 void merge_gutters(int p_from_line, int p_to_line);
989
990 void set_gutter_custom_draw(int p_gutter, const Callable &p_draw_callback);
991
992 // Line gutters.
993 void set_line_gutter_metadata(int p_line, int p_gutter, const Variant &p_metadata);
994 Variant get_line_gutter_metadata(int p_line, int p_gutter) const;
995
996 void set_line_gutter_text(int p_line, int p_gutter, const String &p_text);
997 String get_line_gutter_text(int p_line, int p_gutter) const;
998
999 void set_line_gutter_icon(int p_line, int p_gutter, const Ref<Texture2D> &p_icon);
1000 Ref<Texture2D> get_line_gutter_icon(int p_line, int p_gutter) const;
1001
1002 void set_line_gutter_item_color(int p_line, int p_gutter, const Color &p_color);
1003 Color get_line_gutter_item_color(int p_line, int p_gutter) const;
1004
1005 void set_line_gutter_clickable(int p_line, int p_gutter, bool p_clickable);
1006 bool is_line_gutter_clickable(int p_line, int p_gutter) const;
1007
1008 // Line style
1009 void set_line_background_color(int p_line, const Color &p_color);
1010 Color get_line_background_color(int p_line) const;
1011
1012 /* Syntax Highlighting. */
1013 void set_syntax_highlighter(Ref<SyntaxHighlighter> p_syntax_highlighter);
1014 Ref<SyntaxHighlighter> get_syntax_highlighter() const;
1015
1016 /* Visual. */
1017 void set_highlight_current_line(bool p_enabled);
1018 bool is_highlight_current_line_enabled() const;
1019
1020 void set_highlight_all_occurrences(const bool p_enabled);
1021 bool is_highlight_all_occurrences_enabled() const;
1022
1023 void set_draw_control_chars(bool p_enabled);
1024 bool get_draw_control_chars() const;
1025
1026 void set_draw_tabs(bool p_enabled);
1027 bool is_drawing_tabs() const;
1028
1029 void set_draw_spaces(bool p_enabled);
1030 bool is_drawing_spaces() const;
1031
1032 TextEdit(const String &p_placeholder = String());
1033};
1034
1035VARIANT_ENUM_CAST(TextEdit::EditAction);
1036VARIANT_ENUM_CAST(TextEdit::CaretType);
1037VARIANT_ENUM_CAST(TextEdit::LineWrappingMode);
1038VARIANT_ENUM_CAST(TextEdit::SelectionMode);
1039VARIANT_ENUM_CAST(TextEdit::GutterType);
1040VARIANT_ENUM_CAST(TextEdit::MenuItems);
1041VARIANT_ENUM_CAST(TextEdit::SearchFlags);
1042
1043#endif // TEXT_EDIT_H
1044