1 /*************************************************************************/
2 /*  GodotEditText.java                                                   */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
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 package org.godotengine.godot.input;
31 import android.content.Context;
32 import android.util.AttributeSet;
33 import android.view.KeyEvent;
34 import android.widget.EditText;
35 import org.godotengine.godot.*;
36 import android.os.Handler;
37 import android.os.Message;
38 import android.view.inputmethod.InputMethodManager;
39 import android.view.inputmethod.EditorInfo;
40 
41 public class GodotEditText extends EditText {
42 	// ===========================================================
43 	// Constants
44 	// ===========================================================
45 	private final static int HANDLER_OPEN_IME_KEYBOARD = 2;
46 	private final static int HANDLER_CLOSE_IME_KEYBOARD = 3;
47 
48 	// ===========================================================
49 	// Fields
50 	// ===========================================================
51 	private GodotView mView;
52 	private GodotTextInputWrapper mInputWrapper;
53 	private static Handler sHandler;
54 	private String mOriginText;
55 
56 	// ===========================================================
57 	// Constructors
58 	// ===========================================================
GodotEditText(final Context context)59 	public GodotEditText(final Context context) {
60 		super(context);
61 		this.initView();
62 	}
63 
GodotEditText(final Context context, final AttributeSet attrs)64 	public GodotEditText(final Context context, final AttributeSet attrs) {
65 		super(context, attrs);
66 		this.initView();
67 	}
68 
GodotEditText(final Context context, final AttributeSet attrs, final int defStyle)69 	public GodotEditText(final Context context, final AttributeSet attrs, final int defStyle) {
70 		super(context, attrs, defStyle);
71 		this.initView();
72 	}
73 
initView()74 	protected void initView() {
75 		this.setPadding(0, 0, 0, 0);
76 		this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
77 
78 		sHandler = new Handler() {
79 			@Override
80 			public void handleMessage(final Message msg) {
81 				switch (msg.what) {
82 					case HANDLER_OPEN_IME_KEYBOARD: {
83 						GodotEditText edit = (GodotEditText)msg.obj;
84 						String text = edit.mOriginText;
85 						if (edit.requestFocus()) {
86 							edit.removeTextChangedListener(edit.mInputWrapper);
87 							edit.setText("");
88 							edit.append(text);
89 							edit.mInputWrapper.setOriginText(text);
90 							edit.addTextChangedListener(edit.mInputWrapper);
91 							final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
92 							imm.showSoftInput(edit, 0);
93 						}
94 					} break;
95 
96 					case HANDLER_CLOSE_IME_KEYBOARD: {
97 						GodotEditText edit = (GodotEditText)msg.obj;
98 
99 						edit.removeTextChangedListener(mInputWrapper);
100 						final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
101 						imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
102 						edit.mView.requestFocus();
103 					} break;
104 				}
105 			}
106 		};
107 	}
108 
109 	// ===========================================================
110 	// Getter & Setter
111 	// ===========================================================
setView(final GodotView view)112 	public void setView(final GodotView view) {
113 		this.mView = view;
114 		if (mInputWrapper == null)
115 			mInputWrapper = new GodotTextInputWrapper(mView, this);
116 		this.setOnEditorActionListener(mInputWrapper);
117 		view.requestFocus();
118 	}
119 
120 	// ===========================================================
121 	// Methods for/from SuperClass/Interfaces
122 	// ===========================================================
123 	@Override
onKeyDown(final int keyCode, final KeyEvent keyEvent)124 	public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
125 		super.onKeyDown(keyCode, keyEvent);
126 
127 		/* Let GlSurfaceView get focus if back key is input. */
128 		if (keyCode == KeyEvent.KEYCODE_BACK) {
129 			this.mView.requestFocus();
130 		}
131 
132 		return true;
133 	}
134 
135 	// ===========================================================
136 	// Methods
137 	// ===========================================================
showKeyboard(String p_existing_text)138 	public void showKeyboard(String p_existing_text) {
139 		this.mOriginText = p_existing_text;
140 
141 		final Message msg = new Message();
142 		msg.what = HANDLER_OPEN_IME_KEYBOARD;
143 		msg.obj = this;
144 		sHandler.sendMessage(msg);
145 	}
146 
hideKeyboard()147 	public void hideKeyboard() {
148 		final Message msg = new Message();
149 		msg.what = HANDLER_CLOSE_IME_KEYBOARD;
150 		msg.obj = this;
151 		sHandler.sendMessage(msg);
152 	}
153 
154 	// ===========================================================
155 	// Inner and Anonymous Classes
156 	// ===========================================================
157 }
158