1/**************************************************************************/
2/* line_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 LINE_EDIT_H
32#define LINE_EDIT_H
33
34#include "scene/gui/control.h"
35#include "scene/gui/popup_menu.h"
36
37class LineEdit : public Control {
38 GDCLASS(LineEdit, Control);
39
40public:
41 enum MenuItems {
42 MENU_CUT,
43 MENU_COPY,
44 MENU_PASTE,
45 MENU_CLEAR,
46 MENU_SELECT_ALL,
47 MENU_UNDO,
48 MENU_REDO,
49 MENU_SUBMENU_TEXT_DIR,
50 MENU_DIR_INHERITED,
51 MENU_DIR_AUTO,
52 MENU_DIR_LTR,
53 MENU_DIR_RTL,
54 MENU_DISPLAY_UCC,
55 MENU_SUBMENU_INSERT_UCC,
56 MENU_INSERT_LRM,
57 MENU_INSERT_RLM,
58 MENU_INSERT_LRE,
59 MENU_INSERT_RLE,
60 MENU_INSERT_LRO,
61 MENU_INSERT_RLO,
62 MENU_INSERT_PDF,
63 MENU_INSERT_ALM,
64 MENU_INSERT_LRI,
65 MENU_INSERT_RLI,
66 MENU_INSERT_FSI,
67 MENU_INSERT_PDI,
68 MENU_INSERT_ZWJ,
69 MENU_INSERT_ZWNJ,
70 MENU_INSERT_WJ,
71 MENU_INSERT_SHY,
72 MENU_MAX
73 };
74
75 enum VirtualKeyboardType {
76 KEYBOARD_TYPE_DEFAULT,
77 KEYBOARD_TYPE_MULTILINE,
78 KEYBOARD_TYPE_NUMBER,
79 KEYBOARD_TYPE_NUMBER_DECIMAL,
80 KEYBOARD_TYPE_PHONE,
81 KEYBOARD_TYPE_EMAIL_ADDRESS,
82 KEYBOARD_TYPE_PASSWORD,
83 KEYBOARD_TYPE_URL
84 };
85
86private:
87 HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
88
89 bool editable = false;
90 bool pass = false;
91 bool text_changed_dirty = false;
92
93 bool alt_start = false;
94 uint32_t alt_code = 0;
95
96 String undo_text;
97 String text;
98 String placeholder;
99 String placeholder_translated;
100 String secret_character = U"•";
101 String ime_text;
102 Point2 ime_selection;
103
104 RID text_rid;
105 float full_width = 0.0;
106
107 bool selecting_enabled = true;
108 bool deselect_on_focus_loss_enabled = true;
109 bool drag_and_drop_selection_enabled = true;
110
111 bool context_menu_enabled = true;
112 PopupMenu *menu = nullptr;
113 PopupMenu *menu_dir = nullptr;
114 PopupMenu *menu_ctl = nullptr;
115
116 bool caret_mid_grapheme_enabled = false;
117
118 int caret_column = 0;
119 float scroll_offset = 0.0;
120 int max_length = 0; // 0 for no maximum.
121
122 String language;
123 TextDirection text_direction = TEXT_DIRECTION_AUTO;
124 TextDirection input_direction = TEXT_DIRECTION_LTR;
125 TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
126 Array st_args;
127 bool draw_control_chars = false;
128
129 bool expand_to_text_length = false;
130 bool window_has_focus = true;
131
132 bool clear_button_enabled = false;
133
134 bool shortcut_keys_enabled = true;
135
136 bool virtual_keyboard_enabled = true;
137 VirtualKeyboardType virtual_keyboard_type = KEYBOARD_TYPE_DEFAULT;
138
139 bool middle_mouse_paste_enabled = true;
140
141 bool drag_action = false;
142 bool drag_caret_force_displayed = false;
143
144 Ref<Texture2D> right_icon;
145 bool flat = false;
146
147 struct Selection {
148 int begin = 0;
149 int end = 0;
150 int start_column = 0;
151 bool enabled = false;
152 bool creating = false;
153 bool double_click = false;
154 bool drag_attempt = false;
155 } selection;
156
157 struct TextOperation {
158 int caret_column = 0;
159 float scroll_offset = 0.0;
160 String text;
161 };
162 List<TextOperation> undo_stack;
163 List<TextOperation>::Element *undo_stack_pos = nullptr;
164
165 struct ClearButtonStatus {
166 bool press_attempt = false;
167 bool pressing_inside = false;
168 } clear_button_status;
169
170 uint64_t last_dblclk = 0;
171 Vector2 last_dblclk_pos;
172
173 bool caret_blink_enabled = false;
174 bool caret_force_displayed = false;
175 bool draw_caret = true;
176 float caret_blink_interval = 0.65;
177 double caret_blink_timer = 0.0;
178 bool caret_can_draw = false;
179
180 bool pending_select_all_on_focus = false;
181 bool select_all_on_focus = false;
182
183 struct ThemeCache {
184 Ref<StyleBox> normal;
185 Ref<StyleBox> read_only;
186 Ref<StyleBox> focus;
187
188 Ref<Font> font;
189 int font_size = 0;
190 Color font_color;
191 Color font_uneditable_color;
192 Color font_selected_color;
193 int font_outline_size;
194 Color font_outline_color;
195 Color font_placeholder_color;
196 int caret_width = 0;
197 Color caret_color;
198 int minimum_character_width = 0;
199 Color selection_color;
200
201 Ref<Texture2D> clear_icon;
202 Color clear_button_color;
203 Color clear_button_color_pressed;
204
205 float base_scale = 1.0;
206 } theme_cache;
207
208 void _clear_undo_stack();
209 void _clear_redo();
210 void _create_undo_state();
211
212 Key _get_menu_action_accelerator(const String &p_action);
213 void _generate_context_menu();
214 void _update_context_menu();
215
216 void _shape();
217 void _fit_to_width();
218 void _text_changed();
219 void _emit_text_change();
220
221 void shift_selection_check_pre(bool);
222 void shift_selection_check_post(bool);
223
224 void selection_fill_at_caret();
225 void set_scroll_offset(float p_pos);
226 float get_scroll_offset() const;
227
228 void set_caret_at_pixel_pos(int p_x);
229 Vector2 get_caret_pixel_pos();
230
231 void _reset_caret_blink_timer();
232 void _toggle_draw_caret();
233 void _validate_caret_can_draw();
234
235 void clear_internal();
236
237 void _editor_settings_changed();
238
239 void _swap_current_input_direction();
240 void _move_caret_left(bool p_select, bool p_move_by_word = false);
241 void _move_caret_right(bool p_select, bool p_move_by_word = false);
242 void _move_caret_start(bool p_select);
243 void _move_caret_end(bool p_select);
244 void _backspace(bool p_word = false, bool p_all_to_left = false);
245 void _delete(bool p_word = false, bool p_all_to_right = false);
246
247protected:
248 bool _is_over_clear_button(const Point2 &p_pos) const;
249
250 virtual void _update_theme_item_cache() override;
251
252 void _notification(int p_what);
253 void _validate_property(PropertyInfo &p_property) const;
254 static void _bind_methods();
255
256 virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
257 virtual void gui_input(const Ref<InputEvent> &p_event) override;
258
259public:
260 void set_horizontal_alignment(HorizontalAlignment p_alignment);
261 HorizontalAlignment get_horizontal_alignment() const;
262
263 virtual Variant get_drag_data(const Point2 &p_point) override;
264 virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;
265 virtual void drop_data(const Point2 &p_point, const Variant &p_data) override;
266
267 virtual CursorShape get_cursor_shape(const Point2 &p_pos) const override;
268
269 void menu_option(int p_option);
270 void set_context_menu_enabled(bool p_enable);
271 bool is_context_menu_enabled();
272 PopupMenu *get_menu() const;
273 bool is_menu_visible() const;
274
275 void select(int p_from = 0, int p_to = -1);
276 void select_all();
277 void selection_delete();
278 void deselect();
279 bool has_selection() const;
280 String get_selected_text();
281 int get_selection_from_column() const;
282 int get_selection_to_column() const;
283
284 void delete_char();
285 void delete_text(int p_from_column, int p_to_column);
286
287 void set_text(String p_text);
288 String get_text() const;
289 void set_text_with_selection(const String &p_text); // Set text, while preserving selection.
290
291 void set_text_direction(TextDirection p_text_direction);
292 TextDirection get_text_direction() const;
293
294 void set_language(const String &p_language);
295 String get_language() const;
296
297 void set_draw_control_chars(bool p_draw_control_chars);
298 bool get_draw_control_chars() const;
299
300 void set_structured_text_bidi_override(TextServer::StructuredTextParser p_parser);
301 TextServer::StructuredTextParser get_structured_text_bidi_override() const;
302
303 void set_structured_text_bidi_override_options(Array p_args);
304 Array get_structured_text_bidi_override_options() const;
305
306 void set_placeholder(String p_text);
307 String get_placeholder() const;
308
309 void set_caret_column(int p_column);
310 int get_caret_column() const;
311
312 void set_max_length(int p_max_length);
313 int get_max_length() const;
314
315 void insert_text_at_caret(String p_text);
316 void clear();
317
318 void set_caret_mid_grapheme_enabled(const bool p_enabled);
319 bool is_caret_mid_grapheme_enabled() const;
320
321 bool is_caret_blink_enabled() const;
322 void set_caret_blink_enabled(const bool p_enabled);
323
324 float get_caret_blink_interval() const;
325 void set_caret_blink_interval(const float p_interval);
326
327 void set_caret_force_displayed(const bool p_enabled);
328 bool is_caret_force_displayed() const;
329
330 void copy_text();
331 void cut_text();
332 void paste_text();
333 bool has_undo() const;
334 bool has_redo() const;
335 void undo();
336 void redo();
337
338 void set_editable(bool p_editable);
339 bool is_editable() const;
340
341 void set_secret(bool p_secret);
342 bool is_secret() const;
343
344 void set_secret_character(const String &p_string);
345 String get_secret_character() const;
346
347 virtual Size2 get_minimum_size() const override;
348
349 void set_expand_to_text_length_enabled(bool p_enabled);
350 bool is_expand_to_text_length_enabled() const;
351
352 void set_clear_button_enabled(bool p_enabled);
353 bool is_clear_button_enabled() const;
354
355 void set_shortcut_keys_enabled(bool p_enabled);
356 bool is_shortcut_keys_enabled() const;
357
358 void set_virtual_keyboard_enabled(bool p_enable);
359 bool is_virtual_keyboard_enabled() const;
360
361 void set_virtual_keyboard_type(VirtualKeyboardType p_type);
362 VirtualKeyboardType get_virtual_keyboard_type() const;
363
364 void set_middle_mouse_paste_enabled(bool p_enabled);
365 bool is_middle_mouse_paste_enabled() const;
366
367 void set_selecting_enabled(bool p_enabled);
368 bool is_selecting_enabled() const;
369
370 void set_deselect_on_focus_loss_enabled(const bool p_enabled);
371 bool is_deselect_on_focus_loss_enabled() const;
372
373 void set_drag_and_drop_selection_enabled(const bool p_enabled);
374 bool is_drag_and_drop_selection_enabled() const;
375
376 void set_right_icon(const Ref<Texture2D> &p_icon);
377 Ref<Texture2D> get_right_icon();
378
379 void set_flat(bool p_enabled);
380 bool is_flat() const;
381
382 void set_select_all_on_focus(bool p_enabled);
383 bool is_select_all_on_focus() const;
384 void clear_pending_select_all_on_focus(); // For other controls, e.g. SpinBox.
385
386 virtual bool is_text_field() const override;
387
388 void show_virtual_keyboard();
389
390 LineEdit(const String &p_placeholder = String());
391 ~LineEdit();
392};
393
394VARIANT_ENUM_CAST(LineEdit::MenuItems);
395VARIANT_ENUM_CAST(LineEdit::VirtualKeyboardType);
396
397#endif // LINE_EDIT_H
398