diff options
Diffstat (limited to 'scene/gui/line_edit.cpp')
| -rw-r--r-- | scene/gui/line_edit.cpp | 103 | 
1 files changed, 78 insertions, 25 deletions
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 97f740a4ba..1ceb3f0a8b 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -30,6 +30,7 @@  #include "line_edit.h"  #include "label.h" +#include "message_queue.h"  #include "os/keyboard.h"  #include "os/os.h"  #include "print_string.h" @@ -214,6 +215,12 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {  				case (KEY_A): { //Select All  					select();  				} break; +				case (KEY_LEFT): { // Go to start of text - like HOME key +					set_cursor_position(0); +				} break; +				case (KEY_RIGHT): { // Go to end of text - like END key +					set_cursor_position(text.length()); +				} break;  				default: { handled = false; }  			} @@ -372,12 +379,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {  				case KEY_UP: {  					shift_selection_check_pre(k->get_shift()); +					if (get_cursor_position() == 0) handled = false;  					set_cursor_position(0);  					shift_selection_check_post(k->get_shift());  				} break;  				case KEY_DOWN: {  					shift_selection_check_pre(k->get_shift()); +					if (get_cursor_position() == text.length()) handled = false;  					set_cursor_position(text.length());  					shift_selection_check_post(k->get_shift());  				} break; @@ -599,6 +608,7 @@ void LineEdit::_notification(int p_what) {  			}  			int x_ofs = 0; +			int cached_text_width = text.empty() ? cached_placeholder_width : cached_width;  			switch (align) { @@ -612,15 +622,15 @@ void LineEdit::_notification(int p_what) {  					if (window_pos != 0)  						x_ofs = style->get_offset().x;  					else -						x_ofs = int(size.width - (cached_width)) / 2; +						x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - (cached_text_width)) / 2);  				} break;  				case ALIGN_RIGHT: { -					x_ofs = int(size.width - style->get_offset().x - (cached_width)); +					x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_text_width)));  				} break;  			} -			int ofs_max = width - style->get_minimum_size().width; +			int ofs_max = width - style->get_margin(MARGIN_RIGHT);  			int char_ofs = window_pos;  			int y_area = height - style->get_minimum_size().height; @@ -659,8 +669,8 @@ void LineEdit::_notification(int p_what) {  							if (ofs >= ime_text.length())  								break; -							CharType cchar = (pass && !text.empty()) ? '*' : ime_text[ofs]; -							CharType next = (pass && !text.empty()) ? '*' : ime_text[ofs + 1]; +							CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs]; +							CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];  							int im_char_width = font->get_char_size(cchar, next).width;  							if ((x_ofs + im_char_width) > ofs_max) @@ -681,8 +691,8 @@ void LineEdit::_notification(int p_what) {  					}  				} -				CharType cchar = (pass && !text.empty()) ? '*' : t[char_ofs]; -				CharType next = (pass && !text.empty()) ? '*' : t[char_ofs + 1]; +				CharType cchar = (pass && !text.empty()) ? secret_character[0] : t[char_ofs]; +				CharType next = (pass && !text.empty()) ? secret_character[0] : t[char_ofs + 1];  				int char_width = font->get_char_size(cchar, next).width;  				// end of widget, break! @@ -713,8 +723,8 @@ void LineEdit::_notification(int p_what) {  						if (ofs >= ime_text.length())  							break; -						CharType cchar = (pass && !text.empty()) ? '*' : ime_text[ofs]; -						CharType next = (pass && !text.empty()) ? '*' : ime_text[ofs + 1]; +						CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs]; +						CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];  						int im_char_width = font->get_char_size(cchar, next).width;  						if ((x_ofs + im_char_width) > ofs_max) @@ -800,7 +810,12 @@ void LineEdit::paste_text() {  		if (selection.enabled) selection_delete();  		append_at_cursor(paste_buffer); -		_text_changed(); +		if (!text_changed_dirty) { +			if (is_inside_tree()) { +				MessageQueue::get_singleton()->push_call(this, "_text_changed"); +			} +			text_changed_dirty = true; +		}  	}  } @@ -873,7 +888,7 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {  		} break;  		case ALIGN_RIGHT: { -			pixel_ofs = int(size.width - style->get_offset().x - (cached_width)); +			pixel_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_width));  		} break;  	} @@ -974,7 +989,12 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {  		window_pos = cursor_pos;  	} -	_text_changed(); +	if (!text_changed_dirty) { +		if (is_inside_tree()) { +			MessageQueue::get_singleton()->push_call(this, "_text_changed"); +		} +		text_changed_dirty = true; +	}  }  void LineEdit::set_text(String p_text) { @@ -1001,6 +1021,15 @@ String LineEdit::get_text() const {  void LineEdit::set_placeholder(String p_text) {  	placeholder = tr(p_text); +	if ((max_length <= 0) || (placeholder.length() <= max_length)) { +		Ref<Font> font = get_font("font"); +		cached_placeholder_width = 0; +		if (font != NULL) { +			for (int i = 0; i < placeholder.length(); i++) { +				cached_placeholder_width += font->get_char_size(placeholder[i]).width; +			} +		} +	}  	update();  } @@ -1201,6 +1230,7 @@ void LineEdit::select_all() {  	selection.enabled = true;  	update();  } +  void LineEdit::set_editable(bool p_editable) {  	editable = p_editable; @@ -1217,11 +1247,27 @@ void LineEdit::set_secret(bool p_secret) {  	pass = p_secret;  	update();  } +  bool LineEdit::is_secret() const {  	return pass;  } +void LineEdit::set_secret_character(const String &p_string) { + +	// An empty string as the secret character would crash the engine +	// It also wouldn't make sense to use multiple characters as the secret character +	ERR_EXPLAIN("Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given)"); +	ERR_FAIL_COND(p_string.length() != 1); + +	secret_character = p_string; +	update(); +} + +String LineEdit::get_secret_character() const { +	return secret_character; +} +  void LineEdit::select(int p_from, int p_to) {  	if (p_from == 0 && p_to == 0) { @@ -1303,12 +1349,12 @@ PopupMenu *LineEdit::get_menu() const {  	return menu;  } -#ifdef TOOLS_ENABLED  void LineEdit::_editor_settings_changed() { +#ifdef TOOLS_ENABLED  	cursor_set_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false));  	cursor_set_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65)); -}  #endif +}  void LineEdit::set_expand_to_text_length(bool p_enabled) { @@ -1341,6 +1387,7 @@ void LineEdit::_text_changed() {  void LineEdit::_emit_text_change() {  	emit_signal("text_changed", text);  	_change_notify("text"); +	text_changed_dirty = false;  }  void LineEdit::_clear_redo() { @@ -1373,11 +1420,10 @@ void LineEdit::_create_undo_state() {  void LineEdit::_bind_methods() { +	ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);  	ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &LineEdit::_toggle_draw_caret); -#ifdef TOOLS_ENABLED  	ClassDB::bind_method("_editor_settings_changed", &LineEdit::_editor_settings_changed); -#endif  	ClassDB::bind_method(D_METHOD("set_align", "align"), &LineEdit::set_align);  	ClassDB::bind_method(D_METHOD("get_align"), &LineEdit::get_align); @@ -1408,6 +1454,8 @@ void LineEdit::_bind_methods() {  	ClassDB::bind_method(D_METHOD("is_editable"), &LineEdit::is_editable);  	ClassDB::bind_method(D_METHOD("set_secret", "enabled"), &LineEdit::set_secret);  	ClassDB::bind_method(D_METHOD("is_secret"), &LineEdit::is_secret); +	ClassDB::bind_method(D_METHOD("set_secret_character", "character"), &LineEdit::set_secret_character); +	ClassDB::bind_method(D_METHOD("get_secret_character"), &LineEdit::get_secret_character);  	ClassDB::bind_method(D_METHOD("menu_option", "option"), &LineEdit::menu_option);  	ClassDB::bind_method(D_METHOD("get_menu"), &LineEdit::get_menu);  	ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &LineEdit::set_context_menu_enabled); @@ -1435,15 +1483,17 @@ void LineEdit::_bind_methods() {  	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "max_length"), "set_max_length", "get_max_length");  	ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");  	ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret"); +	ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "secret_character"), "set_secret_character", "get_secret_character");  	ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length", "get_expand_to_text_length");  	ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode"); +	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");  	ADD_GROUP("Placeholder", "placeholder_");  	ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");  	ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");  	ADD_GROUP("Caret", "caret_");  	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled"); -	ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.1"), "cursor_set_blink_speed", "cursor_get_blink_speed"); -	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); +	ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); +	ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_position"), "set_cursor_position", "get_cursor_position");  }  LineEdit::LineEdit() { @@ -1452,11 +1502,14 @@ LineEdit::LineEdit() {  	_create_undo_state();  	align = ALIGN_LEFT;  	cached_width = 0; +	cached_placeholder_width = 0;  	cursor_pos = 0;  	window_pos = 0;  	window_has_focus = true;  	max_length = 0;  	pass = false; +	secret_character = "*"; +	text_changed_dirty = false;  	placeholder_alpha = 0.6;  	deselect(); @@ -1476,15 +1529,15 @@ LineEdit::LineEdit() {  	context_menu_enabled = true;  	menu = memnew(PopupMenu);  	add_child(menu); -	menu->add_item(TTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X); -	menu->add_item(TTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C); -	menu->add_item(TTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V); +	menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X); +	menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C); +	menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);  	menu->add_separator(); -	menu->add_item(TTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A); -	menu->add_item(TTR("Clear"), MENU_CLEAR); +	menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A); +	menu->add_item(RTR("Clear"), MENU_CLEAR);  	menu->add_separator(); -	menu->add_item(TTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z); -	menu->add_item(TTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z); +	menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z); +	menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);  	menu->connect("id_pressed", this, "menu_option");  	expand_to_text_length = false;  }  |