1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Implement Unicode support for ingame console

This commit is contained in:
AlexVinS 2014-07-02 19:16:05 +04:00
parent 195eae48ca
commit 9797372dbe
5 changed files with 82 additions and 28 deletions

View File

@ -3946,7 +3946,7 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
{ {
if(enteredText.size() > 1) if(enteredText.size() > 1)
{ {
enteredText.resize(enteredText.size()-1); Unicode::trimRight(enteredText,1);
enteredText[enteredText.size()-1] = '_'; enteredText[enteredText.size()-1] = '_';
refreshEnteredText(); refreshEnteredText();
} }
@ -3999,14 +3999,43 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
refreshEnteredText(); refreshEnteredText();
} }
} }
#endif // 0 #endif // VCMI_SDL1
break; 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() void CInGameConsole::startEnteringText()
{ {
#ifndef VCMI_SDL1
if (SDL_IsTextInputActive() == SDL_FALSE)
{
SDL_StartTextInput();
}
SDL_SetTextInputRect(&pos);
#endif
enteredText = "_"; enteredText = "_";
if(GH.topInt() == adventureInt) if(GH.topInt() == adventureInt)
{ {
@ -4024,6 +4053,13 @@ void CInGameConsole::startEnteringText()
void CInGameConsole::endEnteringText(bool printEnteredText) void CInGameConsole::endEnteringText(bool printEnteredText)
{ {
#ifndef VCMI_SDL1
if (SDL_IsTextInputActive() == SDL_TRUE)
{
SDL_StopTextInput();
}
#endif
prevEntDisp = -1; prevEntDisp = -1;
if(printEnteredText) if(printEnteredText)
{ {
@ -4062,7 +4098,11 @@ void CInGameConsole::refreshEnteredText()
CInGameConsole::CInGameConsole() : prevEntDisp(-1), defaultTimeout(10000), maxDisplayedTexts(10) CInGameConsole::CInGameConsole() : prevEntDisp(-1), defaultTimeout(10000), maxDisplayedTexts(10)
{ {
#ifdef VCMI_SDL1
addUsedEvents(KEYBOARD); addUsedEvents(KEYBOARD);
#else
addUsedEvents(KEYBOARD | TEXTINPUT);
#endif
} }
CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits ): CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits ):

View File

@ -834,6 +834,11 @@ public:
void print(const std::string &txt); void print(const std::string &txt);
void keyPressed (const SDL_KeyboardEvent & key); //call-in 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 startEnteringText();
void endEnteringText(bool printEnteredText); void endEnteringText(bool printEnteredText);
void refreshEnteredText(); void refreshEnteredText();

View File

@ -1616,30 +1616,7 @@ void CTextInput::clickLeft( tribool down, bool previousState )
void CTextInput::keyPressed( const SDL_KeyboardEvent & key ) 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) if(!focus || key.state != SDL_PRESSED)
return; return;
@ -1661,12 +1638,12 @@ void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
case SDLK_BACKSPACE: case SDLK_BACKSPACE:
if(!newText.empty()) if(!newText.empty())
{ {
trim(newText); Unicode::trimRight(newText);
redrawNeeded = true; redrawNeeded = true;
} }
else if(!text.empty()) else if(!text.empty())
{ {
trim(text); Unicode::trimRight(text);
redrawNeeded = true; redrawNeeded = true;
} }
break; break;

View File

@ -126,6 +126,35 @@ std::string Unicode::fromUnicode(const std::string &text, const std::string &enc
return boost::locale::conv::from_utf<char>(text, encoding); return boost::locale::conv::from_utf<char>(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 //Helper for string -> float conversion
class LocaleWithComma: public std::numpunct<char> class LocaleWithComma: public std::numpunct<char>
{ {

View File

@ -38,6 +38,9 @@ namespace Unicode
/// NOTE: usage of these functions should be avoided if possible /// 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);
std::string DLL_LINKAGE fromUnicode(const std::string & text, const std::string & encoding); 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; class CInputStream;