Esempio n. 1
0
	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 );
}