From 684c35e25a0dc81566e28ed05dd58a933cdef1ba Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Fri, 21 Sep 2012 03:41:10 +0000 Subject: [PATCH] - fix text entry so unicode characters work properly --- source/glest_game/menu/main_menu.cpp | 90 +++++++++++++++++-- source/glest_game/menu/main_menu.h | 2 + .../shared_lib/include/platform/sdl/window.h | 3 + .../sources/platform/sdl/window.cpp | 28 ++++++ 4 files changed, 116 insertions(+), 7 deletions(-) diff --git a/source/glest_game/menu/main_menu.cpp b/source/glest_game/menu/main_menu.cpp index 4913c791..4960e700 100644 --- a/source/glest_game/menu/main_menu.cpp +++ b/source/glest_game/menu/main_menu.cpp @@ -347,6 +347,7 @@ void MenuState::setActiveInputLabel(GraphicLabel *newLabel, GraphicLabel **activ text += "_"; } newLabel->setText(text); + textCharLength = extractKeyPressedUnicodeLength(text); } if(activeInputLabelEdit != NULL && activeInputLabelEdit->getText().empty() == false) { string text= activeInputLabelEdit->getText(); @@ -356,6 +357,7 @@ void MenuState::setActiveInputLabel(GraphicLabel *newLabel, GraphicLabel **activ text = text.substr(0,found); } activeInputLabelEdit->setText(text); + textCharLength = extractKeyPressedUnicodeLength(text); activeInputLabelEdit->setEditModeEnabled(false); } if(newLabel != NULL) { @@ -377,6 +379,7 @@ bool MenuState::keyPressEditLabel(SDL_KeyboardEvent c, GraphicLabel **activeInpu if(isKeyPressed(SDLK_ESCAPE,c,false) == true || isKeyPressed(SDLK_RETURN,c,false) == true ) { setActiveInputLabel(NULL,activeInputLabelPtr); + textCharLength.clear(); eventHandled = true; return eventHandled; } @@ -386,22 +389,51 @@ bool MenuState::keyPressEditLabel(SDL_KeyboardEvent c, GraphicLabel **activeInpu if(activeInputLabel->getText().size() < maxTextSize) { string text= activeInputLabel->getText(); //text.insert(text.end()-1, key); - char szCharText[20]=""; - sprintf(szCharText,"%c",key); - char *utfStr = String::ConvertToUTF8(&szCharText[0]); + + //char szCharText[20]=""; + //sprintf(szCharText,"%c",key); + //char *utfStr = String::ConvertToUTF8(&szCharText[0]); + + wchar_t keyW = extractKeyPressedUnicode(c); + wchar_t textAppend[] = { keyW, 0 }; + wchar_t newKey = textAppend[0]; + + char buf[4] = {0}; + if (newKey < 0x80) { + buf[0] = newKey; + textCharLength.push_back(1); + //printf("1 char, textCharLength = %d\n",textCharLength.size()); + } + else if (newKey < 0x800) { + buf[0] = (0xC0 | newKey >> 6); + buf[1] = (0x80 | newKey & 0x3F); + textCharLength.push_back(2); + //printf("2 char, textCharLength = %d\n",textCharLength.size()); + } + else { + buf[0] = (0xE0 | newKey >> 12); + buf[1] = (0x80 | newKey >> 6 & 0x3F); + buf[2] = (0x80 | newKey & 0x3F); + textCharLength.push_back(3); + //printf("3 char, textCharLength = %d\n",textCharLength.size()); + } + if(text.size() > 0) { size_t found = text.find_last_of("_"); if (found == string::npos || found != text.length()-1) { - text.insert(text.end(), utfStr[0]); + //text.insert(text.end(), utfStr[0]); + //text.insert(text.end(), buf); + text += buf; } else { - text.insert(text.end() -1, utfStr[0]); + //text.insert(text.end() -1, utfStr[0]); + text.insert(text.end() -1, buf[0]); } } else { - text = utfStr[0]; + text = buf; } - delete [] utfStr; + //delete [] utfStr; activeInputLabel->setText(text); @@ -418,6 +450,9 @@ bool MenuState::keyDownEditLabel(SDL_KeyboardEvent c, GraphicLabel **activeInput if(activeInputLabel != NULL) { string text = activeInputLabel->getText(); if(isKeyPressed(SDLK_BACKSPACE,c) == true && text.length() > 0) { + //printf("BSPACE text [%s]\n",text.c_str()); + +/* size_t found = text.find_last_of("_"); if (found == string::npos || found != text.length()-1) { text.erase(text.end() - 1); @@ -427,7 +462,48 @@ bool MenuState::keyDownEditLabel(SDL_KeyboardEvent c, GraphicLabel **activeInput text.erase(text.end() - 2); } } +*/ + bool hasUnderscore = false; + bool delChar = false; + size_t found = text.find_last_of("_"); + if (found == string::npos || found != text.length()-1) { + //printf("A text.length() = %d textCharLength.size() = %d\n",text.length(),textCharLength.size()); + + if(textCharLength[textCharLength.size()-1] >= 1) { + //textCharLength[textCharLength.size()-1] = text.length(); + delChar = true; + } + } + else { + //printf("B text.length() = %d textCharLength.size() = %d\n",text.length(),textCharLength.size()); + + hasUnderscore = true; + if(textCharLength.size() >= 2 && textCharLength[textCharLength.size()-2] >= 1) { + //textCharLength[textCharLength.size()-2] = text.length(); + delChar = true; + } + } + if(delChar == true) { + if(hasUnderscore) { + if(textCharLength.size() > 1) { + for(unsigned int i = 0; i < textCharLength[textCharLength.size()-2]; ++i) { + text.erase(text.end() -2); + } + //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); + textCharLength.pop_back(); + textCharLength.pop_back(); + textCharLength.push_back(1); + } + } + else { + for(unsigned int i = 0; i < textCharLength[textCharLength.size()-1]; ++i) { + text.erase(text.end() -1); + } + //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); + textCharLength.pop_back(); + } + } activeInputLabel->setText(text); eventHandled = true; } diff --git a/source/glest_game/menu/main_menu.h b/source/glest_game/menu/main_menu.h index 8d298c65..ab460361 100644 --- a/source/glest_game/menu/main_menu.h +++ b/source/glest_game/menu/main_menu.h @@ -103,6 +103,8 @@ protected: const char *containerName; Console console; + vector textCharLength; + protected: void setActiveInputLabel(GraphicLabel *newLabel, GraphicLabel **activeInputLabelPtr); diff --git a/source/shared_lib/include/platform/sdl/window.h b/source/shared_lib/include/platform/sdl/window.h index 597066db..3688dfae 100644 --- a/source/shared_lib/include/platform/sdl/window.h +++ b/source/shared_lib/include/platform/sdl/window.h @@ -19,9 +19,11 @@ #include #include "data_types.h" #include "vec.h" +#include #include "leak_dumper.h" using std::map; +using std::vector; using std::string; using Shared::Graphics::Vec2i; @@ -213,6 +215,7 @@ SDLKey extractKeyPressed(SDL_KeyboardEvent input); bool isAllowedInputTextKey(SDLKey key); wchar_t extractKeyPressedUnicode(SDL_KeyboardEvent input); +vector extractKeyPressedUnicodeLength(string text); bool isAllowedInputTextKey(wchar_t &key); }}//end namespace diff --git a/source/shared_lib/sources/platform/sdl/window.cpp b/source/shared_lib/sources/platform/sdl/window.cpp index 2285bdba..259f19b8 100644 --- a/source/shared_lib/sources/platform/sdl/window.cpp +++ b/source/shared_lib/sources/platform/sdl/window.cpp @@ -936,6 +936,34 @@ wchar_t extractKeyPressedUnicode(SDL_KeyboardEvent input) { return c; } +vector extractKeyPressedUnicodeLength(string text) { + vector result; + unsigned int i = 0; + for(i = 0; i < text.length();) { + char c = text[i]; + wchar_t keyW = c; + wchar_t textAppend[] = { keyW, 0 }; + + if(textAppend) { + wchar_t newKey = textAppend[0]; + if (newKey < 0x80) { + result.push_back(1); + //printf("1 char, textCharLength = %d\n",textCharLength.size()); + } + else if (newKey < 0x800) { + result.push_back(2); + //printf("2 char, textCharLength = %d\n",textCharLength.size()); + } + else { + result.push_back(3); + //printf("3 char, textCharLength = %d\n",textCharLength.size()); + } + i += result[result.size()-1]; + } + } + return result; +} + SDLKey extractKeyPressed(SDL_KeyboardEvent input) { SDLKey c = SDLK_UNKNOWN; //if(input.keysym.unicode > 0 && input.keysym.unicode < 0x80) {