#include "StdAfx.h" #include "EditBox.h" #include "UIManager.h" #include "UISkinLexer.h" #include "Token.h" #include "Parser.h" #include "UIImage.h" #include "PlaneObject.h" #include "UIContainer.h" #include "FontAgent.h" #include "Application.h" cEditBox::cEditBox( eUINodeType type ) : cUIIMENode( type ) , mSelectionImage( 0 ) , mEditX( 0 ) , mEditY( 0 ) , mLastTick( 0 ) , mEditTabIndex(0) , mShowLen(0) , mShowCaretFlag( false ) , mCaretTimeFlag( false ) , mCopyFlag( true ) , mEditingPos(0, 0) , mSelectionStartPos( 0, 0 ) , mTextAlign( eALIGN_LEFT ) { mOriginalTexRect.Set( 0, 0, 0, 0 ); mTextColor = mDefaultColor; mProcessEnable = true; } cEditBox::~cEditBox() { SAFE_DELETE( mSelectionImage ); } bool cEditBox::OnCreate( cUINodeProperty* ) { if( cUIIMENode::OnCreate() == 0 ) return false; /// Է Ʈ ƴϸ if( mEditKind != eEDIT_NOINPUT ) { /// θ Ʈ Ѵ mEditTabIndex = mpParent->AddEditBox( this ); } return true; } /// ǻ : bool cEditBox::SetSkin( const cUINodeSkin* pskin ) { if( pskin->IsKindof( eUINODE_EDITBOX ) == false ) { assert( 0 && "not eidtbox skin type" ); return false; } if( cUINode::SetSkin( pskin ) == false ) { return false; } cEditBoxSkin* p = (cEditBoxSkin*)pskin; ////// Ȱȭ ε!!!!!!!!! ϱ 070424 /// ̹ ϴ if( mpImage ) { mOriginalTexRect = mpImage->GetTextureRect(); } /// Ʈ ġ ޾ƿ mEditingPos = p->mEditPos; /// Ʈ Ÿ mEditKind = (eEditKind)p->mEditKind; /// Ʈ mTextAlign = p->mTextAlign; /// Ʈ Ҽ ִ ִ SetMaxEditLength( p->mMaxEditLength ); /// ٿ  ִ ( ) SetOneLineWidth( GetAbsoluteRect().GetWidth() - mEditingPos.mX * 2 ); /// ũƮ ̸ ؽƮ ִ° . if( p->mText.Cstr() ) { Sstrncpy( mText, MAX_TEXT_LENGTH, p->mText.Cstr(), p->mText.GetLength() ); /// mTextLength = p->mText.GetLength(); /// ij ڿ ű CaretMoveEnd(); } /// 巡 ̹ if( mEditKind != eEDIT_NOINPUT && p->mpSelectionTexture ) { if( p->mpSelectionTexture ) { unsigned short tx = (unsigned short)p->mSelectionSkin->mTexX; unsigned short ty = (unsigned short)p->mSelectionSkin->mTexY; unsigned short tw = (unsigned short)p->mSelectionSkin->mTexWidth; unsigned short th = (unsigned short)p->mSelectionSkin->mTexHeight; mSelectionImage = new cPlaneObject; if( mSelectionImage->Create( p->mpSelectionTexture, (short)GetAbsoluteRect().mLeft, (short)GetAbsoluteRect().mTop, tw, th, tx, ty, tx + tw, ty + th ) == false ) { assert( 0 && "failed to create select image"); return false; } } } mChangeText = true; /// ؽƮ ǥ UpdateText(); return true; } /// ǻ : bool cEditBox::HandleEvent( const cUIEvent& event ) { if( event.mCode == eKEY_DOWN || event.mCode == eKEY_UP ) { return mpParent->HandleEvent( event ); } return cUINode::HandleEvent( event ); } /// ǻ : void cEditBox::UpdateRect() { cUINode::UpdateRect(); /// ؽƮ ǥ UpdateText(); } /// ǻ : void cEditBox::OnProcess( unsigned long /*deltaTime*/, unsigned long accumTime ) { /// ũ ؽƮ Ʈ ؽƮ if( mChangeText ) { mChangeText = false; UpdateText(); UpdateShowText(); if( !mDraggingFlag && mEditKind != eEDIT_NOINPUT ) { if( mShowCaretFlag && GetFocus() == this ) { // HIMC hIMC = ::ImmGetContext( THEAPP->GetHWND() ); /// 巡 ƴϰ, Ʈ ϸ ش LPTSTR caret = _T("|"); int textwidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, (LPCTSTR)mShowText.Cstr(), mScrollCaretX ); int newcaretpos = FONTAGENT->GetTextExtent( cFontAgent::eFont_UI, caret, 1 ) / 2; /// ij ġ ϱ int caretX = mEditX + textwidth - newcaretpos+1; // COMPOSITIONFORM comf; comf.dwStyle = CFS_RECT; comf.ptCurrentPos.x = caretX; comf.ptCurrentPos.y = mEditY; comf.rcArea.left = caretX; comf.rcArea.top = mEditY; comf.rcArea.right = GetAbsoluteRect().mLeft + 512; comf.rcArea.bottom = GetAbsoluteRect().mTop + FONTAGENT->GetTextHeight(cFontAgent::eFont_System); ImmSetCompositionWindow( hIMC, &comf ); ::ImmReleaseContext( THEAPP->GetHWND(), hIMC ); } } cUIEvent event; event.mID = mID; event.mType = eUIEVENT_EDITBOX_CHAR_UPDATED; event.mpCaller = this; mpParent->HandleEvent( event ); } /// Ʈ Ʈ ڽ if( mEditKind == eEDIT_NOINPUT ) return; /// ij Ÿ UpdateCaretTime( accumTime ); /// н '*' üؼ if( mEditKind == eEDIT_ACCOUNT_PASS ) { ChangePassword(); } } /// ǻ : void cEditBox::OnRender( cUIFontItemKeeper* pKeeper ) { /// ̹ if( mpImage ) mpImage->Draw(); /// 巡 ̹ if( mEditKind != eEDIT_NOINPUT && mDraggingFlag ) { if( mSelectionImage ) mSelectionImage->Draw(); } /// ij ׸ RenderCaret( pKeeper ); /// ڿ pKeeper->AddFontItem( cFontAgent::eFont_System, (LPCTSTR)mShowText.Cstr(), mEditX, mEditY, mTextColor, mOutLine ); } /// ǻ : void cEditBox::OnKeyDown( eKeyCode code ) { /// Ʈ Ʈ ڽ if( mEditKind == eEDIT_NOINPUT ) return; switch( code ) { case eKEY_CONTROL: { if( mCopyFlag == false ) return; /// н̸ ش if( mEditKind == eEDIT_ACCOUNT_PASS ) return; mControlKey = true; } break; case eKEY_SHIFT: { mShiftKey = true; } break; case eKEY_TAB: { mpParent->ChangeFocus( mEditTabIndex ); } break; case eKEY_ESCAPE: { ReleaseFocus(); Clear(); cUIEvent event; event.mType = eUIEVENT_EDITBOX_ENTER; event.mpCaller = this; event.mID = mID; event.mCode = eKEY_ESCAPE; mpParent->HandleEvent( event ); } break; case eKEY_RETURN: { /// ̺Ʈ cUIEvent event; event.mType = eUIEVENT_EDITBOX_ENTER; event.mpCaller = this; event.mID = mID; event.mCode = eKEY_RETURN; mpParent->HandleEvent( event ); } break; } cUIIMENode::OnKeyDown( code ); } /// ǻ : void cEditBox::OnKeyUp( eKeyCode code ) { /// Ʈ Ʈ ڽ if( mEditKind == eEDIT_NOINPUT ) return; switch( code ) { case eKEY_CONTROL: { /// Ʈ Ű if( mControlKey == true ) mControlKey = false; } break; case eKEY_SHIFT: { /// Ʈ Ű if( mShiftKey == true ) mShiftKey = false; } break; } } void cEditBox::OnImeStartComposition( unsigned int wparam, unsigned int lparam ) { HIMC hIMC = ::ImmGetContext( THEAPP->GetHWND() ); int startX = mEditX; /// 巡 ƴϰ, Ʈ ϸ ش LPTSTR caret = _T("|"); int textwidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, (LPCTSTR)mShowText.Cstr(), mScrollCaretX ); int newcaretpos = FONTAGENT->GetTextExtent( cFontAgent::eFont_UI, caret, 1 ) / 2; /// ij ġ ϱ int caretX = startX + textwidth - newcaretpos+1; // COMPOSITIONFORM comf; comf.dwStyle = CFS_RECT; comf.ptCurrentPos.x = caretX; comf.ptCurrentPos.y = mEditY; comf.rcArea.left = caretX; comf.rcArea.top = mEditY; comf.rcArea.right = GetAbsoluteRect().mLeft + 512; comf.rcArea.bottom = GetAbsoluteRect().mTop + FONTAGENT->GetTextHeight(cFontAgent::eFont_System); ImmSetCompositionWindow( hIMC, &comf ); ::ImmReleaseContext( THEAPP->GetHWND(), hIMC ); } /// ǻ : void cEditBox::OnMouseMove( const cUIPos& pos ) { /// Ʈ󿡼 巡 Ǹ ̹ ش if( mEditKind != eEDIT_NOINPUT && mEditKind != eEDIT_NUMBER && mPressed && mTextLength > 0 ) { /// ̹ UpdateBackImage( pos ); } } /// ǻ : void cEditBox::OnLButtonDown( const cUIPos& pos, bool ctrl, bool alt, bool shift ) { cUINode::OnLButtonDown( pos, ctrl, alt, shift ); /// Ʈ Ʈ ڽ if( mEditKind == eEDIT_NOINPUT ) return; /// Ŀ if( GetFocus() != this ) { SetFocus(); SetCapture(); } if( mCompFlag == true ) return; /// 콺 ó ǥ mSelectionStartPos = pos; /// Ʈ 콺 ̺Ʈ Ͼ, ij ġ UpdateMouseMoveInEdit( pos, mScrollCaretX, mTextCaretX, true ); /// 巡 츦 Ѵ mStartDragCaretX = mScrollCaretX; mEndDragCaretX = mScrollCaretX; /// Ʈ mPressed = true; mDraggingFlag = false; } /// ǻ : void cEditBox::OnLButtonUp( const cUIPos& ) { ReleaseCapture(); mPressed = false; } void cEditBox::OnLButtonDoubleClick( const cUIPos& pos ) { cUINode::OnLButtonDoubleClick( pos ); SetAllSelect(); } /// ǻ : void cEditBox::OnCaptureLost( const cUIPos& ) { mDraggingFlag = false; } void cEditBox::OnMouseLeft( const cUIPos& ) { mPressed = false; } /// ǻ : void cEditBox::OnFocusLost() { mDraggingFlag = false; mCompText.Clear(); mCompFlag = false; mChangeText = true; } /// ǻ : ij ̴ ð void cEditBox::UpdateCaretTime( unsigned long accumTime ) { /// ij Ⱥ if( mCaretTimeFlag ) { mLastTick = accumTime; mCaretTimeFlag = false; } /// ij ̴ ð if( accumTime - mLastTick >= 600 ) { mShowCaretFlag = !mShowCaretFlag; mLastTick = accumTime; } } /// ǻ : ijġ ؼ void cEditBox::RenderCaret( cUIFontItemKeeper* pKeeper ) { int startX = mEditX; /// 巡 ƴϰ, Ʈ ϸ ش if( !mDraggingFlag && mEditKind != eEDIT_NOINPUT ) { if( mShowCaretFlag && GetFocus() == this ) { LPTSTR caret = _T("|"); int textwidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, (LPCTSTR)mShowText.Cstr(), mScrollCaretX ); int newcaretpos = FONTAGENT->GetTextExtent( cFontAgent::eFont_UI, caret, 1 ) / 2; /// ij ġ ϱ int caretX = startX + textwidth - newcaretpos+1; /// ѱ ̸, if( mCompFlag ) { int compLen = (int)mCompText.GetLength(); // Ѿ if( mScrollCaretX + compLen > mShowLen ) { compLen = compLen - (mScrollCaretX + compLen - mShowLen); } int nextwidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, (LPCTSTR)mShowText.Cstr(), mScrollCaretX + compLen ); /// ѱ̸ 簢 ij ׸ for( int i = 0; i < ( nextwidth - textwidth ); ++i ) { caretX = startX + textwidth - newcaretpos; pKeeper->AddFontItem( cFontAgent::eFont_UI, caret, caretX, mEditY, COLOR_DARKGRAY, mOutLine ); startX++; } } /// ƴϸ, else { pKeeper->AddFontItem( cFontAgent::eFont_UI, caret, caretX, mEditY, (unsigned long)mTextColor, mOutLine ); } } } } /// ڿ ü void cEditBox::SetAllSelect() { if( !mSelectionImage ) return; if( !(mTextAlign == eALIGN_LEFT || mTextAlign == eALIGN_RIGHT) ) return; if( mCompFlag == true ) return; /// ü mStartDragCaretX = 0; mEndDragCaretX = mTextLength; /// õ ڿ ˾Ƴ. int len = mEndDragCaretX - mStartDragCaretX; if( len <= 0 ) return; mDraggingFlag = true; /// ̹ ̴ ̸ŭ!! int endX = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), mShowLen ); /// ̹ cUIRect rc; if( mTextAlign == eALIGN_LEFT ) { rc.mLeft = GetAbsoluteRect().mLeft + mEditingPos.mX; rc.mRight = rc.mLeft + endX; } else { rc.mRight = GetAbsoluteRect().mRight; rc.mLeft = rc.mRight - endX; } /// ÿ ̹ ׸ rc.mTop = mEditY; rc.mBottom = rc.mTop + FONTAGENT->GetTextHeight(cFontAgent::eFont_Chat) + 1; mSelectionImage->SetScreenRect( rc.mLeft, rc.mTop, rc.GetWidth(), rc.GetHeight() ); } /// ǻ : 巡 ̹ void cEditBox::UpdateBackImage( const cUIPos& pos ) { if( !mSelectionImage ) return; cUIRect rc; int dummyvalue = 0; /// 巡 ʾ if( mSelectionStartPos.mX == pos.mX ) return; /// if( mSelectionStartPos.mX < pos.mX ) { /// ÿ ij ġ ( : ) UpdateMouseMoveInEdit( pos, mEndDragCaretX, dummyvalue, true ); /// õ ڿ ˾Ƴ. int len = mEndDragCaretX - mStartDragCaretX; if( len <= 0 ) { return; } mDraggingFlag = true; int startX = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), mStartDragCaretX ); int endX = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), mEndDragCaretX ); /// ̹ rc.mLeft = startX + GetAbsoluteRect().mLeft + mEditingPos.mX; rc.mRight = rc.mLeft + ( endX - startX ); /// ÿ ̹ ׸ rc.mTop = mEditY; rc.mBottom = rc.mTop + FONTAGENT->GetTextHeight(cFontAgent::eFont_Chat) + 1; mSelectionImage->SetScreenRect( rc.mLeft, rc.mTop, rc.GetWidth(), rc.GetHeight() ); } /// else if( mSelectionStartPos.mX > pos.mX ) { /// ÿ ij ġ ( : ) UpdateMouseMoveInEdit( pos, mEndDragCaretX, dummyvalue, false ); /// õ ڿ ˾Ƴ. int len = mStartDragCaretX - mEndDragCaretX; if( len <= 0 ) { return; } mDraggingFlag = true; int startX = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), mStartDragCaretX ); int endX = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), mEndDragCaretX ); /// 巡 rc.mRight = startX + GetAbsoluteRect().mLeft + mEditingPos.mX; rc.mLeft = rc.mRight - ( startX - endX ); /// ÿ ̹ ׸ rc.mTop = mEditY; rc.mBottom = rc.mTop + FONTAGENT->GetTextHeight(cFontAgent::eFont_Chat) + 2; mSelectionImage->SetScreenRect( rc.mLeft, rc.mTop, rc.GetWidth(), rc.GetHeight() ); } } /// ǻ : Ʈ 콺 ̺Ʈ Ͼ, ij ġ /// ( 콺ǥ, ֱ ij, ؽƮ ij ) void cEditBox::UpdateMouseMoveInEdit( const cUIPos& pos, int& viewcaret, int& editcaret, bool directionflag ) { /// Ʈ ǥ 콺 ǥ Ÿ ϱ int distance = pos.mX - ( GetAbsoluteRect().mLeft + mEditingPos.mX ); /// if( distance < 0 ) { distance = 0; } int showlen = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), mShowLen ); /// µ ڿ Ҽ . if( distance > showlen ) { distance = showlen; } if( distance > mOneLineWidth ) { distance = mOneLineWidth; } /// ˻ ڿ int cutWidth = 0; /// ߸ڿ int cutlen = 0; /// distance ȿ ڰ  ˻ while( (int)cutWidth < distance ) { /// ˻ʿ . if( cutlen >= mTextLength ) break; cutlen++; cutWidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), cutlen ); } /// if( cutWidth > distance ) { cutlen--; cutWidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), cutlen ); } /// ϱ int nextWidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)mShowText.Cstr(), cutlen + 1); /// յڱ ߰ ⿡ ij ġ ޶ Ѵ int width = (nextWidth - cutWidth) / 2; /// if( directionflag ) { if( distance - cutWidth > width ) { cutlen++; } } else { if( distance - cutWidth <= width ) { cutlen--; } if( cutlen < 0 ) { cutlen = 0; } } /// viewcaret = cutlen; editcaret = viewcaret + mScrollIndex; } /// ǻ :. void cEditBox::ChangePassword() { unsigned int len = mShowText.GetLength(); TCHAR temp[512] = {0,}; ::wmemset( temp, _T('*'), len ); mShowText = temp; } /// ǻ : void cEditBox::UpdateText() { /// Ʈ ڽ ǥ ޾ƿ cUIRect rc = GetAbsoluteRect(); switch( mTextAlign ) { case eALIGN_NONE: case eALIGN_LEFT: { mEditX = mEditingPos.mX + rc.mLeft; mEditY = mEditingPos.mY + rc.mTop; } break; case eALIGN_RIGHT: { unsigned int x = rc.mRight - FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, mText, mTextLength ); mEditX = x - mEditingPos.mX; mEditY = mEditingPos.mY + rc.mTop; } break; case eALIGN_CENTER: { mEditX = rc.mLeft + ( rc.GetWidth() - FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, mText, mTextLength ) ) / 2; mEditY = rc.mTop + ( rc.GetHeight() - FONTAGENT->GetTextHeight(cFontAgent::eFont_Chat) ) / 2; } break; } } /// ǻ : ؽƮ ũѰ, ѷ ؽƮ void cEditBox::UpdateShowText() { cStringT temp; /// ũ ȭ ڿ /// ƴϸ if( mCompFlag == false ) { temp.Append( mText + mScrollIndex, mMaxEditLength ); } else { /// ̸ temp.Append( mText + mScrollIndex, mTextCaretX - mScrollIndex ); temp.Append( (LPCTSTR)mCompText.Cstr(), mCompText.GetLength() ); temp.Append( mText + mTextCaretX, mTextLength - mTextCaretX ); } // ʱȭ mShowLen = 0; mShowText.Clear(); int compLen = mCompText.GetLength(); if( mTextLength + compLen > 0 ) { /// ؽƮ width ϱ /// ̸ ʺ ŭ ش int showWidth = 0; while( showWidth < mOneLineWidth ) { if( mShowLen >= mTextLength + compLen - mScrollIndex ) break; mShowLen++; showWidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_Chat, (LPCTSTR)temp.Cstr(), mShowLen ); } /// ߰ҽ, ڿ ʹ δ if( showWidth > mOneLineWidth && mTextCaretX - mScrollIndex + compLen < mShowLen ) { mShowLen--; } mShowText.Append( (LPCTSTR)temp.Cstr(), mShowLen ); } } /// ǻ : ܺο Ʈ ؽƮ Ҷ void cEditBox::SetText( LPCTSTR text, int align ) { ::ZeroMemory( mText, sizeof(mText) ); Sstrncpy( mText, MAX_TEXT_LENGTH, text, _tcslen(text) ); mTextLength = _tcslen(text); mTextAlign = align; CaretMoveEnd(); UpdateText(); UpdateShowText(); } ///////////////////////////////////////////////////////////////////////////////////// cEditBoxSkin::cEditBoxSkin( eUINodeType type ) : cUINodeSkin( type ) , mTextAlign( eALIGN_LEFT ) , mMaxEditLength( 110 ) , mEditKind(0) , mpSelectionTexture( 0 ) , mEditPos(0, 0) , mSelectionSkin(0) , mEditWidth(0) { mSelectionSkin = new sSkinInfo; } cEditBoxSkin::~cEditBoxSkin() { SAFE_DELETE( mSelectionSkin ); } /// ǻ : bool cEditBoxSkin::Load( cParser& parser ) { if( parser.ExpectTokenString( "{" ) == false ) return false; cToken token; cLexer* lexer = parser.GetLexer(); while( lexer->GetNextToken( &token ) ) { if( token == "}" ) { /// Ż ^^ break; } switch( token.mType ) { /// 巡 ̹ case eTOKEN_CHILD_IMAGEINDEX: { int i = parser.ParseInt(); mpSelectionTexture = UIMAN->GetSkin()->GetTexture( i ); } break; case eTOKEN_CHILD_SIZE: { mSelectionSkin->mWidth = mSelectionSkin->mTexWidth = (unsigned short)parser.ParseInt(); mSelectionSkin->mHeight = mSelectionSkin->mTexHeight = (unsigned short)parser.ParseInt(); } break; case eTOKEN_CHILD_TEXPOS: { mSelectionSkin->mTexX = (unsigned short)parser.ParseInt(); mSelectionSkin->mTexY = (unsigned short)parser.ParseInt(); } break; case eTOKEN_EDITKIND: { mEditKind = parser.ParseInt(); } break; case eTOKEN_TEXT_ALIGN: { /// lexer->GetNextToken( &token ); /// mTextAlign = eALIGN_LEFT; if( token.mType == eTOKEN_CENTER ) { mTextAlign = eALIGN_CENTER; } else if( token.mType == eTOKEN_RIGHT ) { mTextAlign = eALIGN_RIGHT; } } break; case eTOKEN_TEXT: { /// Ʈ ڽ ̸ ؽƮ 츦 . int i = parser.ParseInt(); if( UIMAN->GetUIText( &mText, i ) == false ) { return false; } } break; case eTOKEN_EDITPOS: { mEditPos.mX = parser.ParseInt(); mEditPos.mY = parser.ParseInt(); } break; case eTOKEN_EDITWIDTH: { mEditWidth = parser.ParseInt(); } break; case eTOKEN_EDITMAXLEN: { mMaxEditLength = parser.ParseInt(); } break; default: if( cUINodeSkin::ParseLine( parser, token ) == false ) { return false; } break; } } return true; }