Skip to content

Commit 0a9ff36

Browse files
committed
Text input improvements for Android
1 parent db1f4c9 commit 0a9ff36

File tree

9 files changed

+46
-32
lines changed

9 files changed

+46
-32
lines changed

engine/core/System.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ sg_context_desc System::getSokolContext(){
5959
return {};
6060
}
6161

62-
void System::showVirtualKeyboard(){
62+
void System::showVirtualKeyboard(std::wstring text){
6363

6464
}
6565

engine/core/System.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace Supernova {
3636
virtual int getScreenWidth() = 0;
3737
virtual int getScreenHeight() = 0;
3838

39-
virtual void showVirtualKeyboard();
39+
virtual void showVirtualKeyboard(std::wstring text = L"");
4040
virtual void hideVirtualKeyboard();
4141

4242
virtual bool isFullscreen();

engine/core/subsystem/UISystem.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,13 @@ void UISystem::eventOnPointerDown(float x, float y){
10861086
}
10871087

10881088
if (signature.test(scene->getComponentType<TextEditComponent>())){
1089-
System::instance().showVirtualKeyboard();
1089+
TextEditComponent& textedit = scene->getComponent<TextEditComponent>(entity);
1090+
TextComponent& text = scene->getComponent<TextComponent>(textedit.text);
1091+
1092+
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
1093+
std::wstring utf16Text = convert.from_bytes(text.text);
1094+
1095+
System::instance().showVirtualKeyboard(utf16Text);
10901096
}else{
10911097
System::instance().hideVirtualKeyboard();
10921098
}

platform/android/NativeEngine.cpp

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ static NativeEngine *_singleton = NULL;
6060
// workaround for internal bug b/149866792
6161
static NativeEngineSavedState appState = {false};
6262

63-
static std::string textInputBuffer;
64-
static bool firstInput;
63+
static std::wstring textInputBuffer;
6564

6665

6766
NativeEngine::NativeEngine(struct android_app *app) {
@@ -92,8 +91,7 @@ NativeEngine::NativeEngine(struct android_app *app) {
9291
// https://developer.android.com/reference/android/view/inputmethod/EditorInfo
9392
constexpr int IME_ACTION_NONE = 1;
9493
constexpr int IME_FLAG_NO_FULLSCREEN = 33554432;
95-
96-
//TODO: add support to input suggestions
94+
9795
GameActivity_setImeEditorInfo(app->activity, InputType_dot_TYPE_CLASS_TEXT, IME_ACTION_NONE, IME_FLAG_NO_FULLSCREEN);
9896

9997
if (app->savedState != NULL) {
@@ -168,14 +166,16 @@ int NativeEngine::getScreenDensity(){
168166
return mScreenDensity;
169167
}
170168

171-
void NativeEngine::showSoftInput(){
172-
textInputBuffer = "";
173-
firstInput = true;
169+
void NativeEngine::showSoftInput(std::wstring text){
170+
textInputBuffer = text;
171+
172+
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
173+
std::string strInputBuffer = convert.to_bytes(textInputBuffer);
174174

175-
mGameTextInputState.text_UTF8 = textInputBuffer.data();
176-
mGameTextInputState.text_length = textInputBuffer.length();
177-
mGameTextInputState.selection.start = textInputBuffer.length();
178-
mGameTextInputState.selection.end = textInputBuffer.length();
175+
mGameTextInputState.text_UTF8 = strInputBuffer.data();
176+
mGameTextInputState.text_length = strInputBuffer.length();
177+
mGameTextInputState.selection.start = strInputBuffer.length();
178+
mGameTextInputState.selection.end = strInputBuffer.length();
179179
mGameTextInputState.composingRegion.start = -1;
180180
mGameTextInputState.composingRegion.end = -1;
181181

@@ -248,20 +248,28 @@ void NativeEngine::gameLoop() {
248248
if (mApp->textInputState) {
249249
GameActivity_getTextInputState(mApp->activity, [](void *context, const GameTextInputState *state) {
250250
if (!context || !state) return;
251-
if (textInputBuffer.length() < state->text_length) {
252-
// text_length is different from utf16Text.length and state->(selection or composingRegion) with unicode chars
253-
if (state->text_length > 0) {
254-
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > convert;
255-
std::wstring utf16Text = convert.from_bytes(state->text_UTF8);
256-
257-
// getting only the last character
258-
Supernova::Engine::systemCharInput(utf16Text.back());
259-
}
260-
}else if (!firstInput){
251+
252+
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
253+
std::wstring utf16Text = convert.from_bytes(state->text_UTF8);
254+
255+
while (textInputBuffer.length() > utf16Text.length()){
256+
textInputBuffer.pop_back();
261257
Supernova::Engine::systemCharInput('\b');
262258
}
263-
textInputBuffer = std::string(state->text_UTF8, state->text_length);
264-
firstInput = false;
259+
260+
int pos = 0;
261+
while (textInputBuffer[pos] == utf16Text[pos] and pos < textInputBuffer.length()){
262+
pos++;
263+
}
264+
265+
for (int i = pos; i < textInputBuffer.length(); i++){
266+
Supernova::Engine::systemCharInput('\b');
267+
}
268+
for (int i = pos; i < utf16Text.length(); i++){
269+
Supernova::Engine::systemCharInput(utf16Text[i]);
270+
}
271+
textInputBuffer = utf16Text;
272+
265273
}, this);
266274
mApp->textInputState = 0;
267275
}

platform/android/NativeEngine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class NativeEngine {
124124
int getSurfHeight();
125125
int getScreenDensity();
126126

127-
void showSoftInput();
127+
void showSoftInput(std::wstring text);
128128
void hideSoftInput();
129129

130130
std::string getInternalDataPath();

platform/android/SupernovaAndroid.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ int SupernovaAndroid::getScreenHeight(){
3535
return NativeEngine::getInstance()->getSurfHeight();
3636
}
3737

38-
void SupernovaAndroid::showVirtualKeyboard(){
39-
NativeEngine::getInstance()->showSoftInput();
38+
void SupernovaAndroid::showVirtualKeyboard(std::wstring text){
39+
NativeEngine::getInstance()->showSoftInput(text);
4040
}
4141

4242
void SupernovaAndroid::hideVirtualKeyboard(){

platform/android/SupernovaAndroid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class SupernovaAndroid: public Supernova::System {
1818
virtual int getScreenWidth();
1919
virtual int getScreenHeight();
2020

21-
virtual void showVirtualKeyboard();
21+
virtual void showVirtualKeyboard(std::wstring text);
2222
virtual void hideVirtualKeyboard();
2323

2424
std::string getUserDataPath();

platform/apple/SupernovaApple.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class SupernovaApple: public Supernova::System{
1616
virtual int getScreenWidth();
1717
virtual int getScreenHeight();
1818

19-
virtual void showVirtualKeyboard();
19+
virtual void showVirtualKeyboard(std::wstring text);
2020
virtual void hideVirtualKeyboard();
2121

2222
virtual std::string getAssetPath();

platform/apple/SupernovaApple.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
return Renderer.screenSize.height;
5757
}
5858

59-
void SupernovaApple::showVirtualKeyboard(){
59+
void SupernovaApple::showVirtualKeyboard(std::wstring text){
6060
#if TARGET_OS_IPHONE
6161
[Renderer.view becomeFirstResponder];
6262
#endif

0 commit comments

Comments
 (0)