Accented Characters, fix for textinput proposed.

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Accented Characters, fix for textinput proposed.

Post by christianclavet »

I was playing with the klasker skin demo and discovered that the display could print accented characters. How long this is present?

The keyboard set I have does not allow this to work properly (French Canadian), So I swithched it to Canadian Multilingual, Since this doesnt need a key modifier to input an accented character I was able to input strings with accents. (like "éàç"). I also think this have to do with the font I used. Klasker font had all the character table set in the PNG file.

This seem to be related to keyboard input. Does someone know in what source file the keyboard input is treated? I would like to have a look.

I could simply check for "`" "¨" "¸" and the next character coming after then I would be able to use key modifier like in the french canadian keyboard.

Good work guys!

EDIT

Ok. This seem to be directly in the GUI with the inputbox control. I see that CONTROL key combinations are processessed there, perhaps there is a way to check for the accent, held a flag and process the next key pressed, drop the flag.

EDIT2: I made it work! My Canadian French keyboard is now working with text. I can input accents now!

I'm letting the accent modifier print in the text, then when the next key is pressed, I check if the previous key was a modifier and change the 2 keys for the proper one.

Here is the modified code in CGUIEditBox.cpp (From SVN: 2862. 13 dec 2009)

Code: Select all

void CGUIEditBox::inputChar(wchar_t c)
{
	static bool problemchar = false;
	static bool problemchar1 = false;

	if (!IsEnabled)
		return;

	if (c != 0)
	{
		if (Text.size() < Max || Max == 0)
		{
			core::stringw s;
		
			if (MarkBegin != MarkEnd)
			{
				// replace marked text
				const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
				const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;

				s = Text.subString(0, realmbgn);
				s.append(c);
				s.append( Text.subString(realmend, Text.size()-realmend) );
				Text = s;
				CursorPos = realmbgn+1;
			}
			else
			{
				// add new character
				// Christian Clavet, check here for the accent key.
				const core::stringc keytext=(core::stringc)c; //Ascii code version of C
				if (Text.subString(CursorPos-1,CursorPos)=="`") 
				{  
					CursorPos--;
					s = Text.subString(0, CursorPos);
					Text = s;
					if (c==*L"a")	c=*L"à";
					if (c==*L"A") 	c=*L"À";
					if (c==*L"e") 	c=*L"è";
					if (c==*L"E")	c=*L"È";
					if (c==*L"i") 	c=*L"ì";
					if (c==*L"I")	c=*L"Ì";
					if (c==*L"o") 	c=*L"ò";
					if (c==*L"O")	c=*L"Ò";
					if (c==*L"u") 	c=*L"ù";
					if (c==*L"U")	c=*L"Ù";
	
				} else
				if (problemchar1)//Text.subString(CursorPos-1,CursorPos)=="¨") 
				{  
					CursorPos--;
					s = Text.subString(0, CursorPos);
					Text = s;
					if (c==*L"a")	c=*L"ä";
					if (c==*L"A") 	c=*L"Ä";
					if (c==*L"e") 	c=*L"ë";
					if (c==*L"E")	c=*L"Ë";
					if (c==*L"i") 	c=*L"ï";
					if (c==*L"I")	c=*L"Ï";
					if (c==*L"o") 	c=*L"ö";
					if (c==*L"O")	c=*L"Ö";
					if (c==*L"u") 	c=*L"ü";
					if (c==*L"U")	c=*L"Ü";
					problemchar1=false;
										
				} else
				if (Text.subString(CursorPos-1,CursorPos)=="^") 
				{  
					CursorPos--;
					s = Text.subString(0, CursorPos);
					Text = s;
					if (c==*L"a")	c=*L"â";
					if (c==*L"A") 	c=*L"Â";
					if (c==*L"e") 	c=*L"ê";
					if (c==*L"E")	c=*L"Ê";
					if (c==*L"i") 	c=*L"î";
					if (c==*L"I")	c=*L"Î";
					if (c==*L"o") 	c=*L"ô";
					if (c==*L"O")	c=*L"Ô";
					if (c==*L"u") 	c=*L"û";
					if (c==*L"U")	c=*L"Û";


					
				} else
				if (problemchar) //Text.subString(CursorPos-1,CursorPos)=="¸") 
				{  
			
					CursorPos--;
					s = Text.subString(0, CursorPos);
					Text = s;
					if (c==*L"c") c=*L"ç";
					if (c==*L"C") c=*L"Ç";
					problemchar=false;
					
				} 
				if (keytext=="184") problemchar=true; // ¸ badly detected, quick fix
				if (keytext=="168") problemchar1=true; // ¨ badly detected, quick fix 
				s = Text.subString(0, CursorPos);
				s.append(c);
				s.append( Text.subString(CursorPos, Text.size()-CursorPos) );
				Text = s;
				++CursorPos;
			}

			BlinkStartTime = os::Timer::getTime();
			setTextMarkers(0, 0);
		}
	}
	breakText();
	sendGuiEvent(EGET_EDITBOX_CHANGED);
	calculateScrollPos();
}
I had trouble with two accent modifier keys: ¸ and ¨. Found a way to do a quick fix, but it's not pretty, if someone could create a better alternative of it. Still this code work.

The quick fix uses 2 static boolean variables. To mimic the look of a real accent modifier, I think I could use a static boolean variable for each accent modifier. So when we press the modifier key, nothing would be printed and a flag would be activated, once the user press another key then it would print the proper accentued character.

Right now, I'm kinda of merging the two symbols when detected to create the accentued character.

Would it be really bad, i mean declaring statics for "flags" for the modifiers? Is there any other country keyboard that use accent modifier?
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Sorry for this double posts.

Here is an update on the code. I used the method with 4 defined static bool variables (one for each accent modifier).

The input box now is working exactly the same as in any other inputbox in my windows system. MY French Canadian keyboard now work perfectly with IRRlicht when I input accentued characters.

Here is the code:

Code: Select all

void CGUIEditBox::inputChar(wchar_t c)
{
	static bool accentmod = false;
	static bool accentmod1 = false;
	static bool accentmod2 = false;
	static bool accentmod3 = false;

	if (!IsEnabled)
		return;

	if (c != 0)
	{
		if (Text.size() < Max || Max == 0)
		{
			core::stringw s;
		
			if (MarkBegin != MarkEnd)
			{
				// replace marked text
				const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
				const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;

				if (c==*L"`") accentmod=true;
				if (c==168) accentmod1=true; // ¨ badly detected, quick fix 
				if (c==*L"^") accentmod2=true;
				if (c==184) accentmod3=true; // ¸ badly detected, quick fix
				s = Text.subString(0, realmbgn);
				if (!accentmod && !accentmod1 && !accentmod2 && !accentmod3)
				{
					s.append(c);
					CursorPos = realmbgn+1;
				} else CursorPos = realmbgn;
				s.append( Text.subString(realmend, Text.size()-realmend) );
				
				Text = s;
				
			}
			else
			{
				// add new character
				// Christian Clavet, check here for the accent key.
				if (accentmod) 
				{  
					if (c==*L"a")	c=*L"à";
					if (c==*L"A") 	c=*L"À";
					if (c==*L"e") 	c=*L"è";
					if (c==*L"E")	c=*L"È";
					if (c==*L"i") 	c=*L"ì";
					if (c==*L"I")	c=*L"Ì";
					if (c==*L"o") 	c=*L"ò";
					if (c==*L"O")	c=*L"Ò";
					if (c==*L"u") 	c=*L"ù";
					if (c==*L"U")	c=*L"Ù";
					accentmod=false;
	
				} else
				if (accentmod1)
				{  
					if (c==*L"a")	c=*L"ä";
					if (c==*L"A") 	c=*L"Ä";
					if (c==*L"e") 	c=*L"ë";
					if (c==*L"E")	c=*L"Ë";
					if (c==*L"i") 	c=*L"ï";
					if (c==*L"I")	c=*L"Ï";
					if (c==*L"o") 	c=*L"ö";
					if (c==*L"O")	c=*L"Ö";
					if (c==*L"u") 	c=*L"ü";
					if (c==*L"U")	c=*L"Ü";
					accentmod1=false;
										
				} else
				if (accentmod2) 
				{  
					if (c==*L"a")	c=*L"â";
					if (c==*L"A") 	c=*L"Â";
					if (c==*L"e") 	c=*L"ê";
					if (c==*L"E")	c=*L"Ê";
					if (c==*L"i") 	c=*L"î";
					if (c==*L"I")	c=*L"Î";
					if (c==*L"o") 	c=*L"ô";
					if (c==*L"O")	c=*L"Ô";
					if (c==*L"u") 	c=*L"û";
					if (c==*L"U")	c=*L"Û";
					accentmod2=false;

				} else
				if (accentmod3)
				{  
					if (c==*L"c")	c=*L"ç";
					if (c==*L"C")	c=*L"Ç";
					accentmod3=false;
				} 
				if (c==*L"`") accentmod=true;
				if (c==168) accentmod1=true; // ¨ badly detected, quick fix 
				if (c==*L"^") accentmod2=true;
				if (c==184) accentmod3=true; // ¸ badly detected, quick fix
				if (!accentmod && !accentmod1 && !accentmod2 && !accentmod3)
				{
					s = Text.subString(0, CursorPos);
					s.append(c);
					s.append( Text.subString(CursorPos, Text.size()-CursorPos) );
					Text = s;
					++CursorPos;
				}
			}

			BlinkStartTime = os::Timer::getTime();
			setTextMarkers(0, 0);
		}
	}
	breakText();
	sendGuiEvent(EGET_EDITBOX_CHANGED);
	calculateScrollPos();
}
I've tried this code a lot and it seem to work pretty well. Do you think I could propose this for a patch?
Post Reply