diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 8d43ddfdb..07fca201a 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -3946,7 +3946,7 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key) { if(enteredText.size() > 1) { - enteredText.resize(enteredText.size()-1); + Unicode::trimRight(enteredText,1); enteredText[enteredText.size()-1] = '_'; refreshEnteredText(); } @@ -3999,14 +3999,43 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key) refreshEnteredText(); } } - #endif // 0 + #endif // VCMI_SDL1 break; } } } +#ifndef VCMI_SDL1 + +void CInGameConsole::textInputed(const SDL_TextInputEvent & event) +{ + if(!captureAllKeys || enteredText.size() == 0) + return; + enteredText.resize(enteredText.size()-1); + + enteredText += event.text; + enteredText += "_"; + + refreshEnteredText(); +} + +void CInGameConsole::textEdited(const SDL_TextEditingEvent & event) +{ + //do nothing here +} + +#endif // VCMI_SDL1 + void CInGameConsole::startEnteringText() { + #ifndef VCMI_SDL1 + if (SDL_IsTextInputActive() == SDL_FALSE) + { + SDL_StartTextInput(); + } + SDL_SetTextInputRect(&pos); + #endif + enteredText = "_"; if(GH.topInt() == adventureInt) { @@ -4024,6 +4053,13 @@ void CInGameConsole::startEnteringText() void CInGameConsole::endEnteringText(bool printEnteredText) { + #ifndef VCMI_SDL1 + if (SDL_IsTextInputActive() == SDL_TRUE) + { + SDL_StopTextInput(); + } + #endif + prevEntDisp = -1; if(printEnteredText) { @@ -4062,7 +4098,11 @@ void CInGameConsole::refreshEnteredText() CInGameConsole::CInGameConsole() : prevEntDisp(-1), defaultTimeout(10000), maxDisplayedTexts(10) { + #ifdef VCMI_SDL1 addUsedEvents(KEYBOARD); + #else + addUsedEvents(KEYBOARD | TEXTINPUT); + #endif } CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits ): diff --git a/client/GUIClasses.h b/client/GUIClasses.h index 4da40b028..2126a315d 100644 --- a/client/GUIClasses.h +++ b/client/GUIClasses.h @@ -834,6 +834,11 @@ public: void print(const std::string &txt); void keyPressed (const SDL_KeyboardEvent & key); //call-in +#ifndef VCMI_SDL1 + void textInputed(const SDL_TextInputEvent & event) override; + void textEdited(const SDL_TextEditingEvent & event) override; +#endif // VCMI_SDL1 + void startEnteringText(); void endEnteringText(bool printEnteredText); void refreshEnteredText(); diff --git a/client/gui/CIntObjectClasses.cpp b/client/gui/CIntObjectClasses.cpp index cf9d1f618..4484bc16c 100644 --- a/client/gui/CIntObjectClasses.cpp +++ b/client/gui/CIntObjectClasses.cpp @@ -1616,30 +1616,7 @@ void CTextInput::clickLeft( tribool down, bool previousState ) void CTextInput::keyPressed( const SDL_KeyboardEvent & key ) { - auto trim = [](std::string & s){ - if(s.empty()) - return; - auto b = s.begin(); - auto e = s.end(); - size_t lastLen = 0; - size_t len = 0; - while (b != e) { - lastLen = len; - size_t n = Unicode::getCharacterSize(*b); - - if(!Unicode::isValidCharacter(&(*b),e-b)) - { - logGlobal->errorStream() << "Invalid UTF8 sequence"; - break;//invalid sequence will be trimmed - } - - len += n; - b += n; - } - - s.resize(lastLen); - }; - + if(!focus || key.state != SDL_PRESSED) return; @@ -1661,12 +1638,12 @@ void CTextInput::keyPressed( const SDL_KeyboardEvent & key ) case SDLK_BACKSPACE: if(!newText.empty()) { - trim(newText); + Unicode::trimRight(newText); redrawNeeded = true; } else if(!text.empty()) { - trim(text); + Unicode::trimRight(text); redrawNeeded = true; } break; diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index b6d2f9885..c31261a27 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -126,6 +126,35 @@ std::string Unicode::fromUnicode(const std::string &text, const std::string &enc return boost::locale::conv::from_utf(text, encoding); } +void Unicode::trimRight(std::string & text, const size_t amount/* =1 */) +{ + if(text.empty()) + return; + //todo: more efficient algorithm + for(int i = 0; i< amount; i++){ + auto b = text.begin(); + auto e = text.end(); + size_t lastLen = 0; + size_t len = 0; + while (b != e) { + lastLen = len; + size_t n = getCharacterSize(*b); + + if(!isValidCharacter(&(*b),e-b)) + { + logGlobal->errorStream() << "Invalid UTF8 sequence"; + break;//invalid sequence will be trimmed + } + + len += n; + b += n; + } + + text.resize(lastLen); + } +} + + //Helper for string -> float conversion class LocaleWithComma: public std::numpunct { diff --git a/lib/CGeneralTextHandler.h b/lib/CGeneralTextHandler.h index c4ae01596..a80531cfd 100644 --- a/lib/CGeneralTextHandler.h +++ b/lib/CGeneralTextHandler.h @@ -38,6 +38,9 @@ namespace Unicode /// NOTE: usage of these functions should be avoided if possible std::string DLL_LINKAGE fromUnicode(const std::string & text); std::string DLL_LINKAGE fromUnicode(const std::string & text, const std::string & encoding); + + ///delete (amount) UTF characters from right + DLL_LINKAGE void trimRight(std::string & text, const size_t amount = 1); }; class CInputStream;