Bläddra i källkod

Implement Unicode support for ingame console

AlexVinS 11 år sedan
förälder
incheckning
9797372dbe

+ 42 - 2
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 ):

+ 5 - 0
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();

+ 3 - 26
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;

+ 29 - 0
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<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
 class LocaleWithComma: public std::numpunct<char>
 {

+ 3 - 0
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;