Skip to content

Commit

Permalink
Text input improvements for Android
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardodoria committed Aug 8, 2023
1 parent db1f4c9 commit 0a9ff36
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 32 deletions.
2 changes: 1 addition & 1 deletion engine/core/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ sg_context_desc System::getSokolContext(){
return {};
}

void System::showVirtualKeyboard(){
void System::showVirtualKeyboard(std::wstring text){

}

Expand Down
2 changes: 1 addition & 1 deletion engine/core/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace Supernova {
virtual int getScreenWidth() = 0;
virtual int getScreenHeight() = 0;

virtual void showVirtualKeyboard();
virtual void showVirtualKeyboard(std::wstring text = L"");
virtual void hideVirtualKeyboard();

virtual bool isFullscreen();
Expand Down
8 changes: 7 additions & 1 deletion engine/core/subsystem/UISystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,13 @@ void UISystem::eventOnPointerDown(float x, float y){
}

if (signature.test(scene->getComponentType<TextEditComponent>())){
System::instance().showVirtualKeyboard();
TextEditComponent& textedit = scene->getComponent<TextEditComponent>(entity);
TextComponent& text = scene->getComponent<TextComponent>(textedit.text);

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::wstring utf16Text = convert.from_bytes(text.text);

System::instance().showVirtualKeyboard(utf16Text);
}else{
System::instance().hideVirtualKeyboard();
}
Expand Down
54 changes: 31 additions & 23 deletions platform/android/NativeEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ static NativeEngine *_singleton = NULL;
// workaround for internal bug b/149866792
static NativeEngineSavedState appState = {false};

static std::string textInputBuffer;
static bool firstInput;
static std::wstring textInputBuffer;


NativeEngine::NativeEngine(struct android_app *app) {
Expand Down Expand Up @@ -92,8 +91,7 @@ NativeEngine::NativeEngine(struct android_app *app) {
// https://developer.android.com/reference/android/view/inputmethod/EditorInfo
constexpr int IME_ACTION_NONE = 1;
constexpr int IME_FLAG_NO_FULLSCREEN = 33554432;

//TODO: add support to input suggestions

GameActivity_setImeEditorInfo(app->activity, InputType_dot_TYPE_CLASS_TEXT, IME_ACTION_NONE, IME_FLAG_NO_FULLSCREEN);

if (app->savedState != NULL) {
Expand Down Expand Up @@ -168,14 +166,16 @@ int NativeEngine::getScreenDensity(){
return mScreenDensity;
}

void NativeEngine::showSoftInput(){
textInputBuffer = "";
firstInput = true;
void NativeEngine::showSoftInput(std::wstring text){
textInputBuffer = text;

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::string strInputBuffer = convert.to_bytes(textInputBuffer);

mGameTextInputState.text_UTF8 = textInputBuffer.data();
mGameTextInputState.text_length = textInputBuffer.length();
mGameTextInputState.selection.start = textInputBuffer.length();
mGameTextInputState.selection.end = textInputBuffer.length();
mGameTextInputState.text_UTF8 = strInputBuffer.data();
mGameTextInputState.text_length = strInputBuffer.length();
mGameTextInputState.selection.start = strInputBuffer.length();
mGameTextInputState.selection.end = strInputBuffer.length();
mGameTextInputState.composingRegion.start = -1;
mGameTextInputState.composingRegion.end = -1;

Expand Down Expand Up @@ -248,20 +248,28 @@ void NativeEngine::gameLoop() {
if (mApp->textInputState) {
GameActivity_getTextInputState(mApp->activity, [](void *context, const GameTextInputState *state) {
if (!context || !state) return;
if (textInputBuffer.length() < state->text_length) {
// text_length is different from utf16Text.length and state->(selection or composingRegion) with unicode chars
if (state->text_length > 0) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > convert;
std::wstring utf16Text = convert.from_bytes(state->text_UTF8);

// getting only the last character
Supernova::Engine::systemCharInput(utf16Text.back());
}
}else if (!firstInput){

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::wstring utf16Text = convert.from_bytes(state->text_UTF8);

while (textInputBuffer.length() > utf16Text.length()){
textInputBuffer.pop_back();
Supernova::Engine::systemCharInput('\b');
}
textInputBuffer = std::string(state->text_UTF8, state->text_length);
firstInput = false;

int pos = 0;
while (textInputBuffer[pos] == utf16Text[pos] and pos < textInputBuffer.length()){
pos++;
}

for (int i = pos; i < textInputBuffer.length(); i++){
Supernova::Engine::systemCharInput('\b');
}
for (int i = pos; i < utf16Text.length(); i++){
Supernova::Engine::systemCharInput(utf16Text[i]);
}
textInputBuffer = utf16Text;

}, this);
mApp->textInputState = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion platform/android/NativeEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class NativeEngine {
int getSurfHeight();
int getScreenDensity();

void showSoftInput();
void showSoftInput(std::wstring text);
void hideSoftInput();

std::string getInternalDataPath();
Expand Down
4 changes: 2 additions & 2 deletions platform/android/SupernovaAndroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ int SupernovaAndroid::getScreenHeight(){
return NativeEngine::getInstance()->getSurfHeight();
}

void SupernovaAndroid::showVirtualKeyboard(){
NativeEngine::getInstance()->showSoftInput();
void SupernovaAndroid::showVirtualKeyboard(std::wstring text){
NativeEngine::getInstance()->showSoftInput(text);
}

void SupernovaAndroid::hideVirtualKeyboard(){
Expand Down
2 changes: 1 addition & 1 deletion platform/android/SupernovaAndroid.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SupernovaAndroid: public Supernova::System {
virtual int getScreenWidth();
virtual int getScreenHeight();

virtual void showVirtualKeyboard();
virtual void showVirtualKeyboard(std::wstring text);
virtual void hideVirtualKeyboard();

std::string getUserDataPath();
Expand Down
2 changes: 1 addition & 1 deletion platform/apple/SupernovaApple.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class SupernovaApple: public Supernova::System{
virtual int getScreenWidth();
virtual int getScreenHeight();

virtual void showVirtualKeyboard();
virtual void showVirtualKeyboard(std::wstring text);
virtual void hideVirtualKeyboard();

virtual std::string getAssetPath();
Expand Down
2 changes: 1 addition & 1 deletion platform/apple/SupernovaApple.mm
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
return Renderer.screenSize.height;
}

void SupernovaApple::showVirtualKeyboard(){
void SupernovaApple::showVirtualKeyboard(std::wstring text){
#if TARGET_OS_IPHONE
[Renderer.view becomeFirstResponder];
#endif
Expand Down

0 comments on commit 0a9ff36

Please sign in to comment.