diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 230ce3d1b2e..c92827c2ea3 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -1068,8 +1068,8 @@ bool _OS::has_virtual_keyboard() const {
return OS::get_singleton()->has_virtual_keyboard();
}
-void _OS::show_virtual_keyboard(const String &p_existing_text) {
- OS::get_singleton()->show_virtual_keyboard(p_existing_text, Rect2());
+void _OS::show_virtual_keyboard(const String &p_existing_text, bool p_multiline) {
+ OS::get_singleton()->show_virtual_keyboard(p_existing_text, Rect2(), p_multiline);
}
void _OS::hide_virtual_keyboard() {
@@ -1372,7 +1372,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("dump_memory_to_file", "file"), &_OS::dump_memory_to_file);
ClassDB::bind_method(D_METHOD("dump_resources_to_file", "file"), &_OS::dump_resources_to_file);
ClassDB::bind_method(D_METHOD("has_virtual_keyboard"), &_OS::has_virtual_keyboard);
- ClassDB::bind_method(D_METHOD("show_virtual_keyboard", "existing_text"), &_OS::show_virtual_keyboard, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("show_virtual_keyboard", "existing_text", "multiline"), &_OS::show_virtual_keyboard, DEFVAL(""), DEFVAL(false));
ClassDB::bind_method(D_METHOD("hide_virtual_keyboard"), &_OS::hide_virtual_keyboard);
ClassDB::bind_method(D_METHOD("get_virtual_keyboard_height"), &_OS::get_virtual_keyboard_height);
ClassDB::bind_method(D_METHOD("print_resources_in_use", "short"), &_OS::print_resources_in_use, DEFVAL(false));
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 91457a2f206..ca6ca304db4 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -256,7 +256,7 @@ public:
void dump_resources_to_file(const String &p_file);
bool has_virtual_keyboard() const;
- void show_virtual_keyboard(const String &p_existing_text = "");
+ void show_virtual_keyboard(const String &p_existing_text = "", bool p_multiline = false);
void hide_virtual_keyboard();
int get_virtual_keyboard_height();
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 71db0e5b3a5..1ffa5c44972 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -226,7 +226,7 @@ bool OS::has_virtual_keyboard() const {
return false;
}
-void OS::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+void OS::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
}
void OS::hide_virtual_keyboard() {
diff --git a/core/os/os.h b/core/os/os.h
index c03c3229f05..160282042cf 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -388,7 +388,7 @@ public:
};
virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+ virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void hide_virtual_keyboard();
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index b089b03b6e5..838a443cc77 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -985,8 +985,12 @@
+
+
- Shows the virtual keyboard if the platform has one. The [code]existing_text[/code] parameter is useful for implementing your own LineEdit, as it tells the virtual keyboard what text has already been typed (the virtual keyboard uses it for auto-correct and predictions).
+ Shows the virtual keyboard if the platform has one.
+ The [code]existing_text[/code] parameter is useful for implementing your own [LineEdit] or [TextEdit], as it tells the virtual keyboard what text has already been typed (the virtual keyboard uses it for auto-correct and predictions).
+ The [code]multiline[/code] parameter needs to be set to [code]true[/code] to be able to enter multiple lines of text, as in [TextEdit].
[b]Note:[/b] This method is implemented on Android, iOS and UWP.
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index cf0766161ed..608901927df 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -493,9 +493,9 @@ public class GodotIO {
return (int)(metrics.density * 160f);
}
- public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+ public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (edit != null)
- edit.showKeyboard(p_existing_text, p_max_input_length, p_cursor_start, p_cursor_end);
+ edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
//InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
//inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index fe2847f04f3..b76a494a586 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
@@ -36,6 +36,7 @@ import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.InputFilter;
+import android.text.InputType;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
@@ -58,7 +59,8 @@ public class GodotEditText extends EditText {
private GodotTextInputWrapper mInputWrapper;
private EditHandler sHandler = new EditHandler(this);
private String mOriginText;
- private int mMaxInputLength;
+ private int mMaxInputLength = Integer.MAX_VALUE;
+ private boolean mMultiline = false;
private static class EditHandler extends Handler {
private final WeakReference mEdit;
@@ -95,7 +97,11 @@ public class GodotEditText extends EditText {
protected void initView() {
this.setPadding(0, 0, 0, 0);
- this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
+ this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE);
+ }
+
+ public boolean isMultiline() {
+ return mMultiline;
}
private void handleMessage(final Message msg) {
@@ -115,6 +121,12 @@ public class GodotEditText extends EditText {
edit.mInputWrapper.setSelection(false);
}
+ int inputType = InputType.TYPE_CLASS_TEXT;
+ if (edit.isMultiline()) {
+ inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
+ }
+ edit.setInputType(inputType);
+
edit.mInputWrapper.setOriginText(text);
edit.addTextChangedListener(edit.mInputWrapper);
final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -168,7 +180,7 @@ public class GodotEditText extends EditText {
// ===========================================================
// Methods
// ===========================================================
- public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+ public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length;
if (p_cursor_start == -1) { // cursor position not given
this.mOriginText = p_existing_text;
@@ -181,6 +193,8 @@ public class GodotEditText extends EditText {
this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end);
}
+ this.mMultiline = p_multiline;
+
final Message msg = new Message();
msg.what = HANDLER_OPEN_IME_KEYBOARD;
msg.obj = this;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index ce7eb1ff37f..89a9a0709a8 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -123,7 +123,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
public void run() {
for (int i = 0; i < count; ++i) {
int key = newChars[i];
- if (key == '\n') {
+ if ((key == '\n') && !mEdit.isMultiline()) {
// Return keys are handled through action events
continue;
}
@@ -151,7 +151,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
});
}
- if (pActionID == EditorInfo.IME_NULL) {
+ if (pActionID == EditorInfo.IME_ACTION_DONE) {
// Enter key has been pressed
GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, true);
GodotLib.key(KeyEvent.KEYCODE_ENTER, 0, false);
diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp
index cb2c9d144bf..6b261016885 100644
--- a/platform/android/java_godot_io_wrapper.cpp
+++ b/platform/android/java_godot_io_wrapper.cpp
@@ -53,7 +53,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
_get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
- _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;III)V");
+ _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;ZIII)V");
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;");
@@ -135,11 +135,11 @@ bool GodotIOJavaWrapper::has_vk() {
return (_show_keyboard != 0) && (_hide_keyboard != 0);
}
-void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (_show_keyboard) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
- env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length, p_cursor_start, p_cursor_end);
+ env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
}
}
diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h
index 1a9eea736a1..118939915a7 100644
--- a/platform/android/java_godot_io_wrapper.h
+++ b/platform/android/java_godot_io_wrapper.h
@@ -73,7 +73,7 @@ public:
int get_screen_dpi();
String get_unique_id();
bool has_vk();
- void show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end);
+ void show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end);
void hide_vk();
int get_vk_height();
void set_vk_height(int p_height);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 99dd216bc2f..cd4bc01a446 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -558,10 +558,10 @@ int OS_Android::get_virtual_keyboard_height() const {
// return 0;
}
-void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (godot_io_java->has_vk()) {
- godot_io_java->show_vk(p_existing_text, p_max_input_length, p_cursor_start, p_cursor_end);
+ godot_io_java->show_vk(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
} else {
ERR_PRINT("Virtual keyboard not available");
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 0c957ebdb0f..cacafb70ed1 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -158,7 +158,7 @@ public:
virtual bool has_touchscreen_ui_hint() const;
virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+ virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void hide_virtual_keyboard();
virtual int get_virtual_keyboard_height() const;
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 1b0f71a2254..db0aab06584 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -482,7 +482,7 @@ extern Error _shell_open(String p_uri);
extern void _set_keep_screen_on(bool p_enabled);
extern void _vibrate();
-void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
_show_keyboard(p_existing_text);
};
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 179085402d5..a09e1f1fcc0 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -165,7 +165,7 @@ public:
virtual bool can_draw() const;
virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+ virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void hide_virtual_keyboard();
virtual int get_virtual_keyboard_height() const;
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 35838acef1b..20be1dd0d3b 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -818,7 +818,7 @@ bool OS_UWP::has_virtual_keyboard() const {
return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
}
-void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
InputPane ^ pane = InputPane::GetForCurrentView();
pane->TryShow();
}
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 1ee1439ab23..3dbe056213a 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -239,7 +239,7 @@ public:
virtual bool has_touchscreen_ui_hint() const;
virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+ virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void hide_virtual_keyboard();
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index d752979a118..497d99488ef 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -129,9 +129,9 @@ void LineEdit::_gui_input(Ref p_event) {
if (OS::get_singleton()->has_virtual_keyboard()) {
if (selection.enabled) {
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length, selection.begin, selection.end);
+ OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), false, max_length, selection.begin, selection.end);
} else {
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length, cursor_pos);
+ OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), false, max_length, cursor_pos);
}
}
}
@@ -326,6 +326,7 @@ void LineEdit::_gui_input(Ref p_event) {
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard();
+ return;
} break;
case KEY_BACKSPACE: {
@@ -932,9 +933,9 @@ void LineEdit::_notification(int p_what) {
if (OS::get_singleton()->has_virtual_keyboard()) {
if (selection.enabled) {
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length, selection.begin, selection.end);
+ OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), false, max_length, selection.begin, selection.end);
} else {
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length, cursor_pos);
+ OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), false, max_length, cursor_pos);
}
}
} break;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index d6e56871ab2..e818f1ee980 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1741,7 +1741,7 @@ void TextEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect());
+ OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect(), true);
} break;
case NOTIFICATION_FOCUS_EXIT: {