Fix Android LineEdit editing bugs
(cherry picked from commit cc473b948f
)
This commit is contained in:
parent
3d8cc49ec5
commit
2197ef0566
14 changed files with 71 additions and 36 deletions
|
@ -221,7 +221,7 @@ bool OS::has_virtual_keyboard() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
|
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::hide_virtual_keyboard() {
|
void OS::hide_virtual_keyboard() {
|
||||||
|
|
|
@ -377,7 +377,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool has_virtual_keyboard() 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);
|
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 hide_virtual_keyboard();
|
virtual void hide_virtual_keyboard();
|
||||||
|
|
||||||
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
|
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
|
||||||
|
|
|
@ -493,9 +493,9 @@ public class GodotIO {
|
||||||
return (int)(metrics.density * 160f);
|
return (int)(metrics.density * 160f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showKeyboard(String p_existing_text, int p_max_input_length) {
|
public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
|
||||||
if (edit != null)
|
if (edit != null)
|
||||||
edit.showKeyboard(p_existing_text, p_max_input_length);
|
edit.showKeyboard(p_existing_text, p_max_input_length, p_cursor_start, p_cursor_end);
|
||||||
|
|
||||||
//InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
//InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
//inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
|
//inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
|
||||||
|
|
|
@ -58,6 +58,7 @@ public class GodotEditText extends EditText {
|
||||||
private GodotTextInputWrapper mInputWrapper;
|
private GodotTextInputWrapper mInputWrapper;
|
||||||
private EditHandler sHandler = new EditHandler(this);
|
private EditHandler sHandler = new EditHandler(this);
|
||||||
private String mOriginText;
|
private String mOriginText;
|
||||||
|
private int mMaxInputLength;
|
||||||
|
|
||||||
private static class EditHandler extends Handler {
|
private static class EditHandler extends Handler {
|
||||||
private final WeakReference<GodotEditText> mEdit;
|
private final WeakReference<GodotEditText> mEdit;
|
||||||
|
@ -104,11 +105,18 @@ public class GodotEditText extends EditText {
|
||||||
String text = edit.mOriginText;
|
String text = edit.mOriginText;
|
||||||
if (edit.requestFocus()) {
|
if (edit.requestFocus()) {
|
||||||
edit.removeTextChangedListener(edit.mInputWrapper);
|
edit.removeTextChangedListener(edit.mInputWrapper);
|
||||||
|
setMaxInputLength(edit);
|
||||||
edit.setText("");
|
edit.setText("");
|
||||||
edit.append(text);
|
edit.append(text);
|
||||||
|
if (msg.arg2 != -1) {
|
||||||
|
edit.setSelection(msg.arg1, msg.arg2);
|
||||||
|
edit.mInputWrapper.setSelection(true);
|
||||||
|
} else {
|
||||||
|
edit.mInputWrapper.setSelection(false);
|
||||||
|
}
|
||||||
|
|
||||||
edit.mInputWrapper.setOriginText(text);
|
edit.mInputWrapper.setOriginText(text);
|
||||||
edit.addTextChangedListener(edit.mInputWrapper);
|
edit.addTextChangedListener(edit.mInputWrapper);
|
||||||
setMaxInputLength(edit, msg.arg1);
|
|
||||||
final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
imm.showSoftInput(edit, 0);
|
imm.showSoftInput(edit, 0);
|
||||||
}
|
}
|
||||||
|
@ -125,14 +133,10 @@ public class GodotEditText extends EditText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMaxInputLength(EditText p_edit_text, int p_max_input_length) {
|
private void setMaxInputLength(EditText p_edit_text) {
|
||||||
if (p_max_input_length > 0) {
|
InputFilter[] filters = new InputFilter[1];
|
||||||
InputFilter[] filters = new InputFilter[1];
|
filters[0] = new InputFilter.LengthFilter(this.mMaxInputLength);
|
||||||
filters[0] = new InputFilter.LengthFilter(p_max_input_length);
|
p_edit_text.setFilters(filters);
|
||||||
p_edit_text.setFilters(filters);
|
|
||||||
} else {
|
|
||||||
p_edit_text.setFilters(new InputFilter[] {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
|
@ -164,13 +168,24 @@ public class GodotEditText extends EditText {
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
// Methods
|
// Methods
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
public void showKeyboard(String p_existing_text, int p_max_input_length) {
|
public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
|
||||||
this.mOriginText = p_existing_text;
|
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;
|
||||||
|
this.mMaxInputLength = maxInputLength;
|
||||||
|
} else if (p_cursor_end == -1) { // not text selection
|
||||||
|
this.mOriginText = p_existing_text.substring(0, p_cursor_start);
|
||||||
|
this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_start);
|
||||||
|
} else {
|
||||||
|
this.mOriginText = p_existing_text.substring(0, p_cursor_end);
|
||||||
|
this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end);
|
||||||
|
}
|
||||||
|
|
||||||
final Message msg = new Message();
|
final Message msg = new Message();
|
||||||
msg.what = HANDLER_OPEN_IME_KEYBOARD;
|
msg.what = HANDLER_OPEN_IME_KEYBOARD;
|
||||||
msg.obj = this;
|
msg.obj = this;
|
||||||
msg.arg1 = p_max_input_length;
|
msg.arg1 = p_cursor_start;
|
||||||
|
msg.arg2 = p_cursor_end;
|
||||||
sHandler.sendMessage(msg);
|
sHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||||
private final GodotView mView;
|
private final GodotView mView;
|
||||||
private final GodotEditText mEdit;
|
private final GodotEditText mEdit;
|
||||||
private String mOriginText;
|
private String mOriginText;
|
||||||
|
private boolean mHasSelection;
|
||||||
|
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
// Constructors
|
// Constructors
|
||||||
|
@ -77,6 +78,10 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||||
this.mOriginText = originText;
|
this.mOriginText = originText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelection(boolean selection) {
|
||||||
|
mHasSelection = selection;
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
// Methods for/from SuperClass/Interfaces
|
// Methods for/from SuperClass/Interfaces
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
|
@ -95,6 +100,11 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true);
|
GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true);
|
||||||
GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false);
|
GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false);
|
||||||
|
|
||||||
|
if (mHasSelection) {
|
||||||
|
mHasSelection = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
|
||||||
_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
|
_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
|
||||||
_get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
|
_get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
|
||||||
_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;I)V");
|
_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;III)V");
|
||||||
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
|
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
|
||||||
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
|
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
|
||||||
_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;");
|
_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);
|
return (_show_keyboard != 0) && (_hide_keyboard != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length) {
|
void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
|
||||||
if (_show_keyboard) {
|
if (_show_keyboard) {
|
||||||
JNIEnv *env = ThreadAndroid::get_env();
|
JNIEnv *env = ThreadAndroid::get_env();
|
||||||
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
|
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
|
||||||
env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length);
|
env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length, p_cursor_start, p_cursor_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ public:
|
||||||
int get_screen_dpi();
|
int get_screen_dpi();
|
||||||
String get_unique_id();
|
String get_unique_id();
|
||||||
bool has_vk();
|
bool has_vk();
|
||||||
void show_vk(const String &p_existing, int p_max_input_length);
|
void show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end);
|
||||||
void hide_vk();
|
void hide_vk();
|
||||||
int get_vk_height();
|
int get_vk_height();
|
||||||
void set_vk_height(int p_height);
|
void set_vk_height(int p_height);
|
||||||
|
|
|
@ -558,10 +558,10 @@ int OS_Android::get_virtual_keyboard_height() const {
|
||||||
// return 0;
|
// return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
|
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) {
|
||||||
|
|
||||||
if (godot_io_java->has_vk()) {
|
if (godot_io_java->has_vk()) {
|
||||||
godot_io_java->show_vk(p_existing_text, p_max_input_length);
|
godot_io_java->show_vk(p_existing_text, p_max_input_length, p_cursor_start, p_cursor_end);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ERR_PRINT("Virtual keyboard not available");
|
ERR_PRINT("Virtual keyboard not available");
|
||||||
|
|
|
@ -158,7 +158,7 @@ public:
|
||||||
virtual bool has_touchscreen_ui_hint() const;
|
virtual bool has_touchscreen_ui_hint() const;
|
||||||
|
|
||||||
virtual bool has_virtual_keyboard() 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);
|
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 hide_virtual_keyboard();
|
virtual void hide_virtual_keyboard();
|
||||||
virtual int get_virtual_keyboard_height() const;
|
virtual int get_virtual_keyboard_height() const;
|
||||||
|
|
||||||
|
|
|
@ -482,7 +482,7 @@ extern Error _shell_open(String p_uri);
|
||||||
extern void _set_keep_screen_on(bool p_enabled);
|
extern void _set_keep_screen_on(bool p_enabled);
|
||||||
extern void _vibrate();
|
extern void _vibrate();
|
||||||
|
|
||||||
void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
|
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) {
|
||||||
_show_keyboard(p_existing_text);
|
_show_keyboard(p_existing_text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ public:
|
||||||
virtual bool can_draw() const;
|
virtual bool can_draw() const;
|
||||||
|
|
||||||
virtual bool has_virtual_keyboard() 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);
|
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 hide_virtual_keyboard();
|
virtual void hide_virtual_keyboard();
|
||||||
virtual int get_virtual_keyboard_height() const;
|
virtual int get_virtual_keyboard_height() const;
|
||||||
|
|
||||||
|
|
|
@ -801,8 +801,7 @@ bool OS_UWP::has_virtual_keyboard() const {
|
||||||
return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
|
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) {
|
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) {
|
||||||
|
|
||||||
InputPane ^ pane = InputPane::GetForCurrentView();
|
InputPane ^ pane = InputPane::GetForCurrentView();
|
||||||
pane->TryShow();
|
pane->TryShow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ public:
|
||||||
virtual bool has_touchscreen_ui_hint() const;
|
virtual bool has_touchscreen_ui_hint() const;
|
||||||
|
|
||||||
virtual bool has_virtual_keyboard() 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);
|
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 hide_virtual_keyboard();
|
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);
|
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
|
||||||
|
|
|
@ -127,8 +127,13 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
||||||
selection.creating = false;
|
selection.creating = false;
|
||||||
selection.doubleclick = false;
|
selection.doubleclick = false;
|
||||||
|
|
||||||
if (OS::get_singleton()->has_virtual_keyboard())
|
if (OS::get_singleton()->has_virtual_keyboard()) {
|
||||||
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length);
|
if (selection.enabled) {
|
||||||
|
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length, selection.begin, selection.end);
|
||||||
|
} else {
|
||||||
|
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length, cursor_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
@ -903,13 +908,19 @@ void LineEdit::_notification(int p_what) {
|
||||||
draw_caret = true;
|
draw_caret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS::get_singleton()->set_ime_active(true);
|
{
|
||||||
Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height;
|
OS::get_singleton()->set_ime_active(true);
|
||||||
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
|
Point2 cursor_pos2 = Point2(get_cursor_position(), 1) * get_minimum_size().height;
|
||||||
|
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos2);
|
||||||
if (OS::get_singleton()->has_virtual_keyboard())
|
}
|
||||||
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length);
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length, cursor_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_FOCUS_EXIT: {
|
case NOTIFICATION_FOCUS_EXIT: {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue