directx textbox issues

Started by
9 comments, last by Khaos Dragon 17 years, 10 months ago
I am going to work on a GUI library for direct3D and before I started I wanted to resolve a slight issue I foresee with textboxes. I will need to be able to tell where to put the carat when a box is clicked. This would be fairly trivial for fixed width fonts, but not so much with fonts like Times New Roman. Is there a way to tell from a direct3Dfont object the distance a particular letter is from the beginning of a string? The GetMetrics method only seems to make available the min, max, and average character widths of a particular font which does not seem to be enough information to solve this.
Advertisement
Can't you just accumalate its position using the character widths you mentioned?

Dave
Quote:Original post by Dave
Can't you just accumalate its position using the character widths you mentioned?

Dave


That would only work for a fixed width font. If I have a highly variable width font, I would need to know the width each possible character in the font has.

I think you'd actually have to count it manually, increment each letter, see if it's at the mouse position, if not move on to the next.
Quote:Original post by xycsoscyx
I think you'd actually have to count it manually, increment each letter, see if it's at the mouse position, if not move on to the next.


I believe so too, the problem however is I need a way to get the width of the ith character in my textbox string.

The pseudo code would be something like this:

int relMouseX = mouseX - textBox.mouseX;//need to determine where to place caratint distFromStrStart = 0for( int i = 0; i < TextBox.string.length(); i++ ){ int w = width( TextBox.string, direct3dfont );  //relative mouse position is inside left halfbox of character if( distFromStrStart < relMouseX && relMouseX < distFromStrStart + w /2 ) {    caratPos = i;    break; } //relative mouse position is inside right halfbox of character if( distFromStrStart + w /2 < relMouseX && relMouseX < distFromStrStart + w ) {    caratPos = i + 1;    break; } distFromStrStart += w;}


So basically what's missing is my width function which takes into account the size, font, bold, italices, etc. of the font the string is rendered in.

[Edited by - Khaos Dragon on June 16, 2006 5:12:01 PM]
I believe you can use DT_CALCRECT with ID3DXFont::DrawText to calculate te size of a given string in a font. Just use that with the aforementioned incrementing method and find which character is nearest to the cursor and place the caret after that.
ouraqt is right - but there are a few gotchas - like the fact that spaces at the beginning/end of the string arent included in the width calculation.

Alex
Quote:Original post by Aface
ouraqt is right - but there are a few gotchas - like the fact that spaces at the beginning/end of the string arent included in the width calculation.

Alex


Is there any way to calculate the width of a single space character in the font then?


Can you not just write your own font engine and file format that contains the character widths, or would that just be too much work do you think?
I just step thru like this... seems quick enough :)

//--------------------------------------------------------------------------------------bool cEditBox::HandleLButtonDown(POINT mousePoint){//	char szOutput[128];//	StringCchPrintf( szOutput, 128, "WM_LBUTTONDOWN on cEditBox %s\n", m_caption );					g_log->GUI( "WM_LBUTTONDOWN on cEditBox %s\n", m_caption );	g_guiManager->SetActiveWindow( this );	SetState( WINSTATE_ACTIVE );	m_parent->SetState( WINSTATE_ACTIVE );	// Get coords and work out index clicked	char workText[GUI_MAX_TEXT];	SIZE tempSize;	int x = mousePoint.x - m_x - m_parent->GetXPosition();	for ( unsigned int i = 0; i < m_text.size(); i++ )	{		workText = m_text;		tempSize = g_guiManager->GetNormalText()->GetTextExtent( workText );			if ( x <= tempSize.cx )		{			m_caretIndex = i + 1;			m_caretPosition = tempSize.cx - 2;			break;		}	}	tempSize = g_guiManager->GetNormalText()->GetTextExtent( workText );		// check if click is at end	if ( x > tempSize.cx )	{			m_caretIndex = i;			m_caretPosition = tempSize.cx - 2;	}	return true;  // true = 'dealt with'}


The GetTextExtent() function is as the SDK sample.

This topic is closed to new replies.

Advertisement