mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Implement Unicode support for ingame console
This commit is contained in:
		| @@ -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 ): | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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> | ||||
| { | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user