⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guitexteditctrl.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
      //delete anything highlighted
      if ( mBlockEnd > 0 )
      {
         mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);
         mCursorPos  = mBlockStart;
         mBlockStart = 0;
         mBlockEnd   = 0;
      }

      if ( ( mInsertOn && ( stringLen < mMaxStrLen ) ) ||
          ( !mInsertOn && ( mCursorPos < mMaxStrLen ) ) )
      {
         if ( mCursorPos == stringLen )
         {
            mTextBuffer.append(convertedChar);
            mCursorPos++;
         }
         else
         {
            if ( mInsertOn )
            {
               mTextBuffer.insert(mCursorPos, convertedChar);
               mCursorPos++;
            }
            else
            {
               mTextBuffer.cut(mCursorPos, 1);
               mTextBuffer.insert(mCursorPos, convertedChar);
               mCursorPos++;
            }
         }
      }
      else
         playDeniedSound();

      //reset the history index
      mHistoryDirty = true;

      //execute the console command if it exists
      execConsoleCallback();

      return true;
   }

   //not handled - pass the event to it's parent

   // Or eat it if that's appropriate.
   if (mSinkAllKeyEvents)
      return true;

   return Parent::onKeyDown( event );
}

void GuiTextEditCtrl::setFirstResponder()
{
   Parent::setFirstResponder();
   
   Platform::enableKeyboardTranslation();
#ifdef TGE_RPG
#endif
}

void GuiTextEditCtrl::onLoseFirstResponder()
{
   Platform::disableKeyboardTranslation();

   //first, update the history
   updateHistory( &mTextBuffer, true );

   //execute the validate command
   if ( mValidateCommand[0] )
      Con::evaluate( mValidateCommand, false );

   // Redraw the control:
   setUpdate();
}

#ifdef TGE_RPG
void GuiTextEditCtrl::clearFirstResponder()
{
	Parent::clearFirstResponder();
   Platform::disableKeyboardTranslation();
}
#endif



void GuiTextEditCtrl::parentResized(const Point2I &oldParentExtent, const Point2I &newParentExtent)
{
   Parent::parentResized( oldParentExtent, newParentExtent );
   mTextOffsetReset = true;
}

void GuiTextEditCtrl::onRender(Point2I offset, const RectI & /*updateRect*/)
{
   RectI ctrlRect( offset, mBounds.extent );

   //if opaque, fill the update rect with the fill color
   if ( mProfile->mOpaque )
      dglDrawRectFill( ctrlRect, mProfile->mFillColor );
   
   //if there's a border, draw the border
   if ( mProfile->mBorder )
      renderBorder( ctrlRect, mProfile );

   drawText( ctrlRect, isFirstResponder() );
   
}

void GuiTextEditCtrl::onPreRender()
{
   if ( isFirstResponder() )
   {
      U32 timeElapsed = Platform::getVirtualMilliseconds() - mTimeLastCursorFlipped;
      mNumFramesElapsed++;
      if ( ( timeElapsed > 500 ) && ( mNumFramesElapsed > 3 ) )
      {
         mCursorOn = !mCursorOn;
         mTimeLastCursorFlipped = Platform::getVirtualMilliseconds();
         mNumFramesElapsed = 0;
         setUpdate();
      }

      //update the cursor if the text is scrolling
      if ( mDragHit )
      {
         if ( ( mScrollDir < 0 ) && ( mCursorPos > 0 ) )
            mCursorPos--;
         else if ( ( mScrollDir > 0 ) && ( mCursorPos < (S32) mTextBuffer.length() ) )
            mCursorPos++;
      }
   }
}

void GuiTextEditCtrl::drawText( const RectI &drawRect, bool isFocused )
{
   StringBuffer textBuffer;
   Point2I drawPoint = drawRect.point;
   Point2I paddingLeftTop, paddingRightBottom;

   // Just a little sanity.
   if(mCursorPos > mTextBuffer.length()) 
      mCursorPos = mTextBuffer.length();

   // Apply password masking (make the masking char optional perhaps?)
   if(mPasswordText)
   {
      for(U32 i = 0; i<mTextBuffer.length()-1; i++)
         textBuffer.append(StringBuffer(mPasswordMask));
   }
   else
   {
      // Or else just copy it over.
      textBuffer.set(&mTextBuffer);
   }

   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 - mFont->getHeight() ) / 2 ) + paddingLeftTop.y;

   // Align horizontally:
   
   S32 textWidth;
   {
      FrameTemp<UTF8> widthTemp(textBuffer.length()*3+1);
      textBuffer.get(widthTemp, textBuffer.length()*3+1);
      textWidth = mFont->getStrWidth( widthTemp );
   }

   if ( drawRect.extent.x - paddingLeftTop.x > textWidth )
   {
      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;
      }
   }
   else
      drawPoint.x += paddingLeftTop.x;

   ColorI fontColor = mActive ? mProfile->mFontColor : mProfile->mFontColorNA;

   // now draw the text
   Point2I cursorStart, cursorEnd;
   mTextOffset.y = drawPoint.y;
   if ( mTextOffsetReset )
   {
      mTextOffset.x = drawPoint.x;
      mTextOffsetReset = false;
   }

   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 )
   {
      // Where in the string are we?
      StringBuffer preCursor = mTextBuffer.substring(0, mCursorPos);
      S32 cursorOffset=0, charWidth=0;
      UTF16 tempChar = mTextBuffer.getChar(mCursorPos);

      // Alright, we want to terminate things momentarily.
      if(mCursorPos > 0)
      {
         FrameTemp<UTF8> cursorTemp(preCursor.length()*3+1);
         preCursor.get(cursorTemp, preCursor.length()*3+1);
         cursorOffset = mFont->getStrWidth(cursorTemp);
      }
      else
         cursorOffset = 0;

      if ( tempChar )
         charWidth = mFont->getCharWidth( tempChar );
      else
         charWidth = paddingRightBottom.x;

      if( mTextOffset.x + cursorOffset + charWidth >= (drawRect.point.x + drawRect.extent.x) - paddingLeftTop.x )
      {
         // Cursor somewhere beyond the textcontrol,
         // skip forward roughly 25% of the total width (if possible)
         S32 skipForward = drawRect.extent.x / 4;

         if ( cursorOffset + skipForward > textWidth )
            mTextOffset.x = (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x - textWidth;
         else
            mTextOffset.x -= skipForward;
      }
      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;

         if ( cursorOffset - skipBackward < 0 )
            mTextOffset.x = drawRect.point.x + paddingLeftTop.x;
         else
            mTextOffset.x += skipBackward;
      }
      cursorStart.x = mTextOffset.x + cursorOffset;
      cursorEnd.x = cursorStart.x;

      S32 cursorHeight = 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;

   UTF16 temp;

   Point2I tempOffset = mTextOffset;

   //draw the portion before the highlight
   if ( mBlockStart > 0 )
   {
      StringBuffer preBuffer = textBuffer.substring(0, mBlockStart);
      FrameTemp<UTF8> preString(preBuffer.length()*3+1);
      preBuffer.get(preString, preBuffer.length()*3+1);

      dglSetBitmapModulation( fontColor );
      dglDrawText( mFont, tempOffset, preString, mProfile->mFontColors );
      tempOffset.x += mFont->getStrWidth( (const UTF8*)preString );
   }

   //draw the hilighted portion
   if ( mBlockEnd > 0 )
   {
      StringBuffer highlightBuff = mTextBuffer.substring(mBlockStart, mBlockEnd-mBlockStart);

      FrameTemp<UTF8> highlightTemp(highlightBuff.length()*3 + 1);
      highlightBuff.get(highlightTemp, highlightBuff.length()*3 + 1);

      S32 highlightWidth = mFont->getStrWidth( highlightTemp );

      dglDrawRectFill( Point2I( tempOffset.x, drawRect.point.y ),
         Point2I( tempOffset.x + highlightWidth, drawRect.point.y + drawRect.extent.y - 1),
         mProfile->mFillColorHL );

      dglSetBitmapModulation( mProfile->mFontColorHL );
      dglDrawText( mFont, tempOffset, highlightTemp, mProfile->mFontColors );
      tempOffset.x += highlightWidth;
   }

   //draw the portion after the highlite
   if(mBlockEnd < mTextBuffer.length())
   {
      StringBuffer finalBuff = mTextBuffer.substring(mBlockEnd, mTextBuffer.length() - mBlockEnd);
      FrameTemp<UTF8> finalTemp(finalBuff.length()*3 + 1);
      finalBuff.get(finalTemp, finalBuff.length()*3 + 1);

      dglSetBitmapModulation( fontColor );
      dglDrawText( mFont, tempOffset, finalTemp, mProfile->mFontColors );
   }

#if TGE_RPG
	mCursorOffset = cursorStart - mBounds.point;
#endif
   //draw the cursor
   if ( isFocused && mCursorOn )
      dglDrawLine( cursorStart, cursorEnd, mProfile->mCursorColor );
}

bool GuiTextEditCtrl::hasText()
{
   return (mTextBuffer.length());
}

void GuiTextEditCtrl::playDeniedSound()
{
   if ( mDeniedSound )
   {
      AUDIOHANDLE handle = alxCreateSource( mDeniedSound );
      alxPlay( handle );
   }
}

bool GuiTextEditCtrl::initCursors()
{
   if ( mEditCursor == NULL )
   {
      SimObject *obj;
      obj = Sim::findObject("TextEditCursor");
      mEditCursor = dynamic_cast<GuiCursor*>(obj);

      return( mEditCursor != NULL );
   }
   else
      return(true);
}


void GuiTextEditCtrl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent)
{
   showCursor = true;

   if( initCursors() )
   {
      Point2I mousePos  = lastGuiEvent.mousePoint;
      RectI winRect   = mBounds;
      winRect.point = localToGlobalCoord( winRect.point );

      if( winRect.pointInRect( mousePos ) )
         cursor = mEditCursor;
      else
         cursor = NULL;
   }
}

const char *GuiTextEditCtrl::getScriptValue()
{
   FrameTemp<UTF8> temp(mTextBuffer.length() * 3 + 1);
   mTextBuffer.get(temp, mTextBuffer.length() * 3 + 1);
   return StringTable->insert((const char*)(UTF8*)temp);
}

void GuiTextEditCtrl::setScriptValue(const char *value)
{
   mTextBuffer.set(value);
   mCursorPos = mTextBuffer.length() - 1;
}

ConsoleMethod( GuiTextEditCtrl, getText, const char*, 2, 2, "textEditCtrl.getText()" )
{
   argc; argv;
   if( !object->hasText() )
      return StringTable->insert("");

   char *retBuffer = Con::getReturnBuffer( GuiTextEditCtrl::MAX_STRING_LENGTH );
   object->getText( retBuffer );

   return retBuffer;
}


ConsoleMethod( GuiTextEditCtrl, getCursorPos, S32, 2, 2, "textEditCtrl.getCursorPos()" )
{
   argc; argv;
   return( object->getCursorPos() );
}

ConsoleMethod( GuiTextEditCtrl, setCursorPos, void, 3, 3, "textEditCtrl.setCursorPos( newPos )" )
{
   argc;
   object->reallySetCursorPos( dAtoi( argv[2] ) );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -