void Entry::render() { Element::render(); if (state == STATE_PRESS && SDL_GetTicks()%1000 < 500) { std::string t = getRenderText(); int fs = style.getFontSize(); vec2 s = style.getFont().textSize(t,fs); style.getFont().renderChar('|', x+w/2+s.x/2-fs/2, y+h/2-s.y/2, fs); } }
void GuiTextEditCtrl::drawText( const RectI &drawRect, bool isFocused ) { StringBuffer textBuffer; Point2I drawPoint = drawRect.point; Point2I paddingLeftTop, paddingRightBottom; // Or else just copy it over. char *renderText = Con::getReturnBuffer( GuiTextEditCtrl::MAX_STRING_LENGTH ); getRenderText( renderText ); // Apply password masking (make the masking char optional perhaps?) if(mPasswordText) { const U32 renderLen = dStrlen( renderText ); for( U32 i = 0; i < renderLen; i++ ) textBuffer.append(mPasswordMask); } else { textBuffer.set( renderText ); } // Just a little sanity. if(mCursorPos > textBuffer.length()) mCursorPos = textBuffer.length(); paddingLeftTop.set(( mProfile->mTextOffset.x != 0 ? mProfile->mTextOffset.x : 3 ), mProfile->mTextOffset.y); paddingRightBottom = paddingLeftTop; // Center vertically: drawPoint.y += ( ( drawRect.extent.y - paddingLeftTop.y - paddingRightBottom.y - S32( mProfile->mFont->getHeight() ) ) / 2 ) + paddingLeftTop.y; // Align horizontally: S32 textWidth = mProfile->mFont->getStrNWidth(textBuffer.getPtr(), textBuffer.length()); switch( mProfile->mAlignment ) { case GuiControlProfile::RightJustify: drawPoint.x += ( drawRect.extent.x - textWidth - paddingRightBottom.x ); break; case GuiControlProfile::CenterJustify: drawPoint.x += ( ( drawRect.extent.x - textWidth ) / 2 ); break; default: case GuiControlProfile::LeftJustify : drawPoint.x += paddingLeftTop.x; break; } ColorI fontColor = mActive ? mProfile->mFontColor : mProfile->mFontColorNA; // now draw the text Point2I cursorStart, cursorEnd; mTextOffset.y = drawPoint.y; mTextOffset.x = drawPoint.x; if ( drawRect.extent.x - paddingLeftTop.x > textWidth ) mTextOffset.x = drawPoint.x; else { // Alignment affects large text if ( mProfile->mAlignment == GuiControlProfile::RightJustify || mProfile->mAlignment == GuiControlProfile::CenterJustify ) { if ( mTextOffset.x + textWidth < (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x) mTextOffset.x = (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x - textWidth; } } // calculate the cursor if( isFocused && mActive ) { // Where in the string are we? S32 cursorOffset=0, charWidth=0; UTF16 tempChar = textBuffer.getChar(mCursorPos); // Alright, we want to terminate things momentarily. if(mCursorPos > 0) { cursorOffset = mProfile->mFont->getStrNWidth(textBuffer.getPtr(), mCursorPos); } else cursorOffset = 0; if( tempChar && mProfile->mFont->isValidChar( tempChar ) ) charWidth = mProfile->mFont->getCharWidth( tempChar ); else charWidth = paddingRightBottom.x; if( mTextOffset.x + cursorOffset + 1 >= (drawRect.point.x + drawRect.extent.x) ) // +1 is for the cursor width { // Cursor somewhere beyond the textcontrol, // skip forward roughly 25% of the total width (if possible) S32 skipForward = drawRect.extent.x / 4 * 3; if ( cursorOffset + skipForward > textWidth ) mTextOffset.x = (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x - textWidth; else { //mTextOffset.x -= skipForward; S32 mul = (S32)( mFloor( (cursorOffset-drawRect.extent.x) / skipForward ) ); mTextOffset.x -= skipForward * mul + drawRect.extent.x - 1; // -1 is for the cursor width } } else if( mTextOffset.x + cursorOffset < drawRect.point.x + paddingLeftTop.x ) { // Cursor somewhere before the textcontrol // skip backward roughly 25% of the total width (if possible) S32 skipBackward = drawRect.extent.x / 4 * 3; if ( cursorOffset - skipBackward < 0 ) mTextOffset.x = drawRect.point.x + paddingLeftTop.x; else { S32 mul = (S32)( mFloor( cursorOffset / skipBackward ) ); mTextOffset.x += drawRect.point.x - mTextOffset.x - skipBackward * mul; } } cursorStart.x = mTextOffset.x + cursorOffset; #ifdef TORQUE_OS_MAC cursorStart.x += charWidth/2; #endif cursorEnd.x = cursorStart.x; S32 cursorHeight = mProfile->mFont->getHeight(); if ( cursorHeight < drawRect.extent.y ) { cursorStart.y = drawPoint.y; cursorEnd.y = cursorStart.y + cursorHeight; } else { cursorStart.y = drawRect.point.y; cursorEnd.y = cursorStart.y + drawRect.extent.y; } } //draw the text if ( !isFocused ) mBlockStart = mBlockEnd = 0; //also verify the block start/end if ((mBlockStart > textBuffer.length() || (mBlockEnd > textBuffer.length()) || (mBlockStart > mBlockEnd))) mBlockStart = mBlockEnd = 0; Point2I tempOffset = mTextOffset; //draw the portion before the highlight if ( mBlockStart > 0 ) { GFX->getDrawUtil()->setBitmapModulation( fontColor ); const UTF16* preString2 = textBuffer.getPtr(); GFX->getDrawUtil()->drawText( mProfile->mFont, tempOffset, preString2, mProfile->mFontColors ); tempOffset.x += mProfile->mFont->getStrNWidth(preString2, mBlockStart); } //draw the highlighted portion if ( mBlockEnd > 0 ) { const UTF16* highlightBuff = textBuffer.getPtr() + mBlockStart; U32 highlightBuffLen = mBlockEnd-mBlockStart; S32 highlightWidth = mProfile->mFont->getStrNWidth(highlightBuff, highlightBuffLen); GFX->getDrawUtil()->drawRectFill( Point2I( tempOffset.x, drawRect.point.y ), Point2I( tempOffset.x + highlightWidth, drawRect.point.y + drawRect.extent.y - 1), mProfile->mFontColorSEL ); GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColorHL ); GFX->getDrawUtil()->drawTextN( mProfile->mFont, tempOffset, highlightBuff, highlightBuffLen, mProfile->mFontColors ); tempOffset.x += highlightWidth; } //draw the portion after the highlight if(mBlockEnd < textBuffer.length()) { const UTF16* finalBuff = textBuffer.getPtr() + mBlockEnd; U32 finalBuffLen = textBuffer.length() - mBlockEnd; GFX->getDrawUtil()->setBitmapModulation( fontColor ); GFX->getDrawUtil()->drawTextN( mProfile->mFont, tempOffset, finalBuff, finalBuffLen, mProfile->mFontColors ); } //draw the cursor if ( isFocused && mCursorOn ) GFX->getDrawUtil()->drawLine( cursorStart, cursorEnd, mProfile->mCursorColor ); }