Sign in to follow this  

directx textbox issues

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 carat
int distFromStrStart = 0


for( int i = 0; i < TextBox.string.length(); i++ )
{
int w = width( TextBox.string[i], 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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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?


Share this post


Link to post
Share on other sites
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[i] = m_text[i];
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.

Share this post


Link to post
Share on other sites
Quote:
Original post by sipickles
I just step thru like this... seems quick enough :)

*** Source Snippet Removed ***

The GetTextExtent() function is as the SDK sample.


The GetTextExtentPoint32 API call seems to do what I need, thanks!

Share this post


Link to post
Share on other sites

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this