#include "stdafx.h" #ifndef _COUNTRY_ME_ #include "KViewport.h" #include "../KTextPhrase.h" #include "KPrimitiveSprite.h" //#include "KUIControl.h" #include "KUITipControl.h" #include "KUIWndManager.h" #include "KUIDragAndDrop.h" #include "KResourceManager.h" #include //#include "Util.h" #include #include "KTextPhrase.h" #include using namespace KUI_MESSAGE; using namespace rp; namespace { const char* c_szDefaultTooltipAniName = "static_fulldown_outframe"; struct StringOmitter { struct Element { Element( bool isTag, const std::string& token ) : mIsTag( isTag ), mToken( token ) { } bool mIsTag; std::string mToken; }; bool operator( )( std::string& out, const char* target, DWORD limitByte, const char* omissionMark ) { if( target == 0 ) return false; out.assign( target ); std::vector< Element > List; size_t curBegin = 0; DWORD byteCount = 0; while( true ) { size_t tag_begin = out.find( '<', curBegin ); if( tag_begin == out.npos ) { if( out.begin() + curBegin != out.end() ) { List.push_back( Element( false, std::string( out.begin() + curBegin, out.begin() + out.size() ) ) ); byteCount += out.size() - curBegin; } break; } size_t tag_end = out.find( '>', curBegin ); if( tag_end == out.npos ) { if( out.begin() + curBegin != out.end() ) { List.push_back( Element( false, std::string( out.begin() + curBegin, out.begin() + out.size() ) ) ); byteCount += out.size() - curBegin; } break; } if( tag_end > tag_begin ) { if( tag_begin > curBegin ) { List.push_back( Element( false, std::string( out.begin() + curBegin, out.begin() + tag_begin ) ) ); byteCount += tag_begin - curBegin; } List.push_back( Element( true, std::string( out.begin() + tag_begin, out.begin() + tag_end + 1 ) ) ); curBegin = tag_end + 1; } else break; } if( byteCount <= limitByte ) return false; out.clear(); bool found = false, needOmission = false; byteCount = 0; if( limitByte >= ::strlen( omissionMark ) ) { limitByte -= ::strlen( omissionMark ); needOmission = true; } std::vector< Element >::iterator begin = List.begin(), end = List.end(); for( ; begin != end; ++begin ) { Element& elem = *begin; if( !elem.mIsTag ) { if( !found ) { byteCount += elem.mToken.size(); if( byteCount >= limitByte ) { found = true; DWORD overByte = byteCount - limitByte; if( overByte > 0 ) { LPCSTR lpszEnd = elem.mToken.c_str() + elem.mToken.size(); LPCSTR lpszNew = lpszEnd; while( (lpszEnd - lpszNew) < overByte ) { lpszNew = CharPrev( elem.mToken.c_str(), lpszNew ); } elem.mToken.assign( elem.mToken.c_str(), lpszNew ); if( needOmission ) elem.mToken.append( omissionMark ); } } out.append( elem.mToken ); } } else { out.append( elem.mToken ); } } return true; } std::vector< Element > result; }; }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KUIControl Implement //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool KUIControl::s_bIsDrawRectGrid = false; short KUIControl::s_nBlankWidth = 0; KUIControl* KUIControl::s_pToolTipOnControl = NULL; void KUIControl::OnToolTipOnControl( KUIControl* pControl ) { OffToolTipOnControl( pControl ); s_pToolTipOnControl = pControl; } void KUIControl::OffToolTipOnControl( KUIControl* pNewControl ) { if( s_pToolTipOnControl && s_pToolTipOnControl != pNewControl ) { s_pToolTipOnControl->SetTooltipOff(); s_pToolTipOnControl = NULL; } } void KUIControl::SetNULLToolTipOnControl() { s_pToolTipOnControl = NULL; } KUIControl::KUIControl(void) { m_bIsDisable = false; m_bUsePos = false; m_bUsePosEnable = true; m_bUseCustomSize = false; // #2.1.2.11.1 m_bUseHorizonPiece = true; m_bUseEmoticonFilter = true; m_bCaptionRandomColor = false; m_bToolTipLeftRender = false; m_nPieceCount = 0; m_pSpriteList = NULL; m_pTipControl = NULL; m_pDragObject = NULL; m_dwToolTipStartTime = 0; m_dwToolTipPreStartTime = 0; m_strEnableColor = "<#242424>"; m_strDisableColor = "<#505050>"; m_pRectGrid = new KWireUtilPrimitive; m_bCutCaption = false; // 제목의 잘림처리 여부. } KUIControl::~KUIControl(void) { // 2010.05.06 - prodongi clearEmoticonSizeList(); SAFE_DELETE( m_pRectGrid ); _destroyControl(); } void KUIControl::Create(KUIWND_CREATE_ARG& CREATE_ARG) { KUIWnd::Create(CREATE_ARG); _initControl(); SAFE_DELETE(m_pDragObject ); m_strTooltipSprName = CREATE_ARG.lpszSprName; m_strTooltipAniName = c_szDefaultTooltipAniName; if( m_dwFlag & KFLAG_CAN_DRAG) { if (m_pDragObject == NULL) m_pDragObject = new KUIDragAndDropObject; } // 2010.07.05. bintitle. FontSize 얻기. m_FontSize = 0; std::string::size_type nPos = m_sCaption.find( "" ); strTemp = strTemp.substr( 0, nPos_End ); m_FontSize = ::atoi( m_sCaption.substr( nPos, strTemp.size() ).c_str() ); } } void KUIControl::Render( KViewportObject *pViewport, bool isFront ) { if ( m_bShowFlag ) { _renderBack(pViewport, isFront); _renderChild(pViewport, isFront); _renderCaption(pViewport, isFront); #ifdef _KUI_INVALIDATION // _renderToolTip(pViewport, isFront); #else _renderToolTip(pViewport, isFront); #endif if( s_bIsDrawRectGrid ) { m_pRectGrid->Clear(); KRect rc = GetRect(); K3DVector pos[4]; K3DVector opos[4]; for( int i(0); 4>i; i++ ) { pos[0] = K3DVector(0,0,0); opos[0] = K3DVector(0,0,0); } pos[0] = K3DVector( rc.left , rc.top , 0 ); pos[1] = K3DVector( rc.right, rc.top , 0 ); pos[2] = K3DVector( rc.left , rc.bottom, 0 ); pos[3] = K3DVector( rc.right, rc.bottom, 0 ); pViewport->Get2DVto3DV( pos[0], opos[0] ); pViewport->Get2DVto3DV( pos[1], opos[1] ); pViewport->Get2DVto3DV( pos[2], opos[2] ); pViewport->Get2DVto3DV( pos[3], opos[3] ); m_pRectGrid->AddLine( opos[0], opos[1], KColor(255,0,0,255) ); m_pRectGrid->AddLine( opos[1], opos[3], KColor(255,0,0,255) ); m_pRectGrid->AddLine( opos[2], opos[3], KColor(255,0,0,255) ); m_pRectGrid->AddLine( opos[2], opos[0], KColor(255,0,0,255) ); pViewport->RegisterWire( m_pRectGrid ); } } } void KUIControl::Process(DWORD dwTime) { KUIWnd::Process(dwTime); _processAlphaShow(dwTime); _processToolTip(); } void KUIControl::_processAlphaShow( DWORD dwTime ) { if( m_bShowAlpha && m_dwStyle & KSTYLE_ALPHA_SHOW ) { DWORD dwTimeDiff = dwTime - m_dwAlphaTime; float fAlphaValue = (float)dwTimeDiff / (float)500.f; ChangeAlpha( fAlphaValue); if(dwTimeDiff >= 500.f ) m_bShowAlpha = false; } } void KUIControl::SetTooltip( LPCSTR lpszTip /*= NULL*/ ) { //툴팁 if( lpszTip == NULL ) { m_sTip.clear(); m_LazyTip = NULL; SAFE_DELETE(m_pTipControl); } else { std::string sTip = lpszTip; if( m_sTip != sTip ) { /// 2010.11.03 툴팁 배경이 검은 색이기 때문에 툴팁이 검정색일 경우에는 흰색으로 바꿔준다 - prodongi XStringUtil::Replace(sTip, "<#000000>", "<#ffffff>"); m_sTip = sTip; m_LazyTip = NULL; SAFE_DELETE(m_pTipControl); } } // 메인 툴팁이 호출되면 서브는 초기화 한다. ClearSubTooptip(); } // sonador 1.2.5 Lazy Tooltip 구현 void KUIControl::SetLazyTooltip( KLazyTip* lazyTip ) // sonador #2.1.2.4.3 팻 조작 UI 연동 { if( lazyTip == NULL ) { m_sTip.clear(); m_LazyTip = NULL; SAFE_DELETE(m_pTipControl); } else { if( m_LazyTip != lazyTip ) { m_LazyTip = lazyTip; m_sTip.clear(); SAFE_DELETE( m_pTipControl ); } } // 메인 툴팁이 호출되면 서브는 초기화 한다. ClearSubTooptip(); } void KUIControl::AddSubTooltip( LPCSTR lpszText ) { if( lpszText == NULL ) { SAFE_DELETE(m_pTipControl); ClearSubTooptip(); } else { std::string sSubTip = (NULL != lpszText) ? lpszText : ""; auto pos = std::find( m_SubTip.begin(), m_SubTip.end(), sSubTip ); if( pos == m_SubTip.end() ) { SAFE_DELETE(m_pTipControl); /// 2010.11.03 툴팁 배경이 검은 색이기 때문에 툴팁이 검정색일 경우에는 흰색으로 바꿔준다 - prodongi XStringUtil::Replace(sSubTip, "<#000000>", "<#ffffff>"); m_SubTip.push_back( sSubTip ); SAFE_DELETE_VECTOR( m_SubTipContorl ); } } } void KUIControl::AddLazySubTooltip( KLazyTip* pLazyTip ) { if( pLazyTip == NULL ) { SAFE_DELETE(m_pTipControl); ClearSubTooptip(); } else { auto pos = std::find( m_SubLazyTip.begin(), m_SubLazyTip.end(), pLazyTip ); if( pos == m_SubLazyTip.end() ) { SAFE_DELETE(m_pTipControl); m_SubLazyTip.push_back( pLazyTip ); SAFE_DELETE_VECTOR( m_SubTipContorl ); } } } void KUIControl::ClearSubTooptip() { m_SubTip.clear(); m_SubLazyTip.clear(); SAFE_DELETE_VECTOR( m_SubTipContorl ); } DWORD KUIControl::OnMouseMessage(DWORD dwMessage, int x, int y) { DWORD dwRet = KUIWnd::OnMouseMessage(dwMessage,x,y); // sonador 1.2.5 Lazy Tooltip 구현 if(false == IsInRect(x, y )|| ( m_sTip.empty() && !m_LazyTip ) || dwMessage != KMOUSE_MOVE) { // Tooltip Cancel if( m_dwToolTipStartTime != 0 ) _setToolTipOff(); return dwRet; } // Clip 안에 들어오지 않는다면 아예 받지를 말자. if( false == m_rcClipArea.IsInRect( x, y )) return dwRet; // 예전과 다른 위치 (Tooltip Set) if(x != m_nOldPosX || y != m_nOldPosY ) { //_oprint( "# 툴팁 갱신 : %s\n", m_sID.c_str() ); DWORD dwTime = GetSafeTickCount(); m_dwToolTipPreStartTime = dwTime; m_nOldPosX = x; m_nOldPosY = y; // 만약 Tool Tip을 찍는 도중이라면 time을 update if(m_dwToolTipStartTime != 0) { // if( 0 == dwTime ) DebugBreak(); m_dwToolTipStartTime = dwTime; } else { // Position Offset int TIP_OFFSET_X = 10; int TIP_OFFSET_Y = 20; // ToolTip 이 찍힐 자리 보정 (스크린을 넘어서면 이동) m_nToolTipPosX = x; m_nToolTipPosY = y; if( !m_bToolTipLeftRender ) { m_nToolTipPosX += TIP_OFFSET_X; m_nToolTipPosY += TIP_OFFSET_Y; } if( NULL == m_pTipControl) UpdateTip(); /// 2010.11.01 화면 경계 체크를 함수로 뺌 - prodongi /* if( m_pTipControl ) { if( m_bToolTipLeftRender ) { m_nToolTipPosX -= m_pTipControl->GetRect().GetWidth(); if( m_nToolTipPosX<0 ) m_nToolTipPosX=0; } int xDiff = KUIWndManager::GetResolution().width - (m_nToolTipPosX + m_pTipControl->GetRect().GetWidth() ); int yDiff = KUIWndManager::GetResolution().height - (m_nToolTipPosY + m_pTipControl->GetRect().GetHeight() ); if(xDiff < 0) m_nToolTipPosX += xDiff; if(yDiff < 0) m_nToolTipPosY += yDiff; } */ checkToolTipScreenBound(); } } return dwRet; } void* KUIControl::Perform( KID id, KArg& msg ) { return NULL; } // Parent로 Message 를 Pumping 해준다. void KUIControl::PumpUpMessage(LPCSTR lpszControlID, DWORD dwMessage, DWORD dwLParam, DWORD dwWParam) { if ( GetParent() ) GetParent()->PumpUpMessage( lpszControlID, dwMessage, dwLParam, dwWParam ); } void KUIControl::OnChangeCaptionNotify() { // disable 이면 텍스트 회색으로.. if( IsDisable() ) { size_t cpos = 0; while( ( cpos = m_sCaption.find( "<#" ) ) != m_sCaption.npos ) { m_sCaption.erase( cpos, 9 ); } std::string strNewCaption = m_strDisableColor.c_str(); strNewCaption += m_sCaption; m_sCaption = strNewCaption; m_sOrgCaption = m_sCaption; /// 2011.02.16 m_sOrgCaption에 저장하지 않으면 Disable했다가 SetCaption했을 때, Caption이 적용되지 않는다 - prodongi } UpdateCaption(); KUIWnd::OnChangeCaptionNotify(); } void KUIControl::OnChangeAniNameNotify() { UpdateAniName(); KUIWnd::OnChangeAniNameNotify(); } void KUIControl::OnChagneBackNotify() { UpdateBack(); KUIWnd::OnChagneBackNotify(); } void KUIControl::OnSizeChangeNofity(const KRect& rcNewRect) { KUIWnd::OnSizeChangeNofity( rcNewRect); _initControl(); } void KUIControl::OnParentSizeChangeNotify(const KRect& rcNewRect, int nXMove, int nYMove, int nResizeStyle) { std::list< KUIWnd* >::iterator it = m_listChild.begin(); for ( ; it != m_listChild.end() ; ++it ) { KUIWnd * wnd = *it; (*it)->OnParentSizeChangeNotify(rcNewRect, nXMove ,nYMove, nResizeStyle); } int nXMoveOffset = 0; int nYMoveOffset = 0; if( nResizeStyle & KSTYLE_RESIZE_LEFT) // 왼쪽으로 이동 nXMoveOffset = (m_dwAnchor & KANCHOR_LEFT ) ? nXMove : 0; else nXMoveOffset = (m_dwAnchor & KANCHOR_RIGHT ) ? nXMove : 0; if( nResizeStyle & KSTYLE_RESIZE_TOP) nYMoveOffset = (m_dwAnchor & KANCHOR_TOP ) ? nYMove : 0; else nYMoveOffset = (m_dwAnchor & KANCHOR_BOTTOM ) ? nYMove : 0; MovePosOffset( nXMoveOffset, nYMoveOffset); } void KUIControl::OnParentPosChangeNotify(int x, int y) { MovePos(m_rcRegion.left + x, m_rcRegion.top + y); } void KUIControl::OnPosChangeNofity(int x, int y) { KUIWnd::OnPosChangeNofity(x,y); //if( ::_stricmp( GetID(), "worldmap_small" ) == 0 ) // int a = 0; int i; for(i = 0; i < m_nPieceCount; ++i) m_pSpriteList[i].SetAddPosition(x,y); if(m_pCaptionPhrase) m_pCaptionPhrase->SetAddPosition(x,y); for( i = 0; i < m_vtSprite.size(); ++i) m_vtSprite.at(i)->SetAddPosition(x,y); for( i = 0; i < m_vtTextPhrase.size(); ++i) m_vtTextPhrase.at(i)->SetAddPosition(x,y); } void KUIControl::OnClipChangeNotify(const KRect& rcClipRect) { KUIWnd::OnClipChangeNotify( rcClipRect ); int i; for(i = 0; i < m_nPieceCount; ++i) m_pSpriteList[i].SetClipRect( &m_rcClipArea ) ; if(m_pCaptionPhrase) m_pCaptionPhrase->SetClipRect( m_rcClipArea ); for( i = 0; i < m_vtSprite.size(); ++i) m_vtSprite.at(i)->SetClipRect( &m_rcClipArea); for( i = 0; i < m_vtTextPhrase.size(); ++i) m_vtTextPhrase.at(i)->SetClipRect( m_rcClipArea ); } void KUIControl::OnParentClipChangeNotify(const KRect& rcClipRect) { OnClipChangeNotify( rcClipRect ); } void KUIControl::OnAlphaChangeNotify(float fAlpha) { KUIWnd::OnAlphaChangeNotify( fAlpha); int i; for(i = 0; i < m_nPieceCount; ++i) m_pSpriteList[i].SetVisibility( m_fAlpha); if(m_pCaptionPhrase) m_pCaptionPhrase->SetVisibility( m_fAlpha); for( i = 0; i < m_vtSprite.size(); ++i) m_vtSprite.at(i)->SetVisibility( m_fAlpha); for( i = 0; i < m_vtTextPhrase.size(); ++i) m_vtTextPhrase.at(i)->SetVisibility(m_fAlpha); } void KUIControl::OnParentAlphaChangeNotify(float fAlphaDiff) { ChangeAlpha( m_fAlpha + fAlphaDiff); } void KUIControl::OnAlphaChangeNotNotify(float alpha) { int i; for(i = 0; i < m_nPieceCount; ++i) m_pSpriteList[i].SetVisibility( alpha); if(m_pCaptionPhrase) m_pCaptionPhrase->SetVisibility( alpha); for( i = 0; i < m_vtSprite.size(); ++i) m_vtSprite.at(i)->SetVisibility( alpha); for( i = 0; i < m_vtTextPhrase.size(); ++i) m_vtTextPhrase.at(i)->SetVisibility(alpha); } KUIDragAndDropObject* KUIControl::GetDragObject() { if( NULL != m_pDragObject) m_pDragObject->Set( m_pParent, this); return m_pDragObject; } void KUIControl::UpdateBack() { if( m_bUsePos && m_bUsePosEnable && !m_bUseCustomSize) // #2.1.2.11.1 m_rcRegion.right = -1; _reArrangeRect( m_bUseHorizonPiece ); m_rcCaptionArea = m_rcRegion; } void KUIControl::UpdateAniName() { // { 임시로 이렇게 구현 by Testors UpdateBack(); // } } // 2010.09.03 - prodongi // SINGLE_LINE 처리 수정:2010.09.27 - bintitle. void KUIControl::UpdateCaption(DWORD maxWidth) { // Caption 설정 if((!m_sCaption.empty() || GetClassName() == "edit") && m_rcCaptionArea.GetWidth() > 1 && m_rcCaptionArea.GetHeight() > 1) { /// 2011.02.23 m_pCaptionPhrase에서 스프라이트 스크롤 정보를 갖고와서 저장해 놓는다, 캡션이 바껴도 이 설정은 유지 되야 되기 때문에 - prodongi KTextPhrase::sSpriteScrollInfo spriteScrollInfo; if (m_pCaptionPhrase) m_pCaptionPhrase->getSpriteScrollInfo(spriteScrollInfo); SAFE_DELETE(m_pCaptionPhrase); m_pCaptionPhrase = new KTextPhrase(m_rcCaptionArea.right - m_rcCaptionArea.left, m_rcCaptionArea.bottom - m_rcCaptionArea.top); m_pCaptionPhrase->SetAlign( m_dwCaptionAlign ); m_pCaptionPhrase->SetPosition(m_rcCaptionArea.left, m_rcCaptionArea.top, m_fZPos); m_pCaptionPhrase->SetVisibility( m_fAlpha ); /// 2011.02.23 복구 - prodongi m_pCaptionPhrase->setSpriteScrollInfo(spriteScrollInfo); m_pCaptionPhrase->SetCaptionRandomColor( m_bCaptionRandomColor ); if( m_dwFlag & KFLAG_SINGLE_LINE) { /// 2010.11.04 - prodongi DWORD realCaptionWidth = KTextPhrase::GetOneLineStringSize(m_sCaption.c_str(), NULL, NULL); if (realCaptionWidth > m_rcCaptionArea.GetWidth()) { DWORD dwWidht = 0; std::string sFontName; std::string strSingleLine; //
태그가 존재할 경우 첫
태그 이전( 첫번째줄 ) 텍스트. std::string strPureCaption; // <> 태그를 제거한 순수한 텍스트. //
태그가 존재하면 2줄 이상인 것이다. 첫번째
이전의 텍스트에 대한 SINGLE_LINE 처리를 한다. bool bBr = true; std::string::size_type nfos = m_sCaption.find( "
" ); if( nfos == std::string::npos ) { nfos = m_sCaption.find( "
" ); if( nfos == std::string::npos ) bBr = false; } bool bFontBold; CStringUtil::GetTextFontName(m_sCaption, sFontName); CStringUtil::GetTextFontBold(m_sCaption, bFontBold); std::wstring wStrPure; if( bBr ) { strSingleLine = m_sCaption.substr( 0, nfos ); wStrPure = nsl::uni::conv( strSingleLine.c_str() ); } else { strSingleLine = m_sCaption; wStrPure = nsl::uni::conv( m_sCaption.c_str() ); } // 태그를 제거할때 <$> 태그를 보존하기 위함. std::wstring wTemp( wStrPure ); std::wstring wTagKey( L"***!!!@_%_&_#_^_@" ); std::wstring wTagString; std::wstring::size_type sTagStart = wStrPure.find( L"<$" ); if( sTagStart != std::wstring::npos ) { wTemp = wStrPure.substr( sTagStart, wStrPure.size() ); std::wstring::size_type sTagEnd = wTemp.find_first_of( L">" ); if( sTagEnd != std::wstring::npos ) { wTagString = wStrPure.substr( sTagStart, sTagEnd + 1 ); wStrPure.replace( sTagStart, sTagEnd + 1, wTagKey ); } } // 텍스트 꾸미기태그분리( 텍스트 내부의 태그는 제외 ). std::string strDeco( "" ); std::wstring::size_type sEnd( 0 ); // ★ 태그를 제외한 텍스트만을 걸러낸다. if( !wStrPure.empty() ) { while( 1 ) { std::wstring::size_type sStart = wStrPure.find_first_of( L"<" ); if( sStart != std::wstring::npos ) { // "<" 는 존재하는데 ">" 는 없다는 것도 태그가 없는 것. sEnd = wStrPure.find_first_of( L">" ); if( sEnd == std::wstring::npos || sStart > sEnd ) break; else { strDeco += nsl::uni::conv( wStrPure.substr( sStart, sEnd - sStart + 1 ) ); wStrPure = wStrPure.replace( sStart, sEnd - sStart + 1, L"" ); } } // 텍스트에 "<" 이 문자가 없다는 것은 태그가 없다는 것. 모두 걸러내었다! 종료. else break; } } // 태그를 걸러낸 텍스트에 보존해논 <$> 적용. if( !wTagString.empty() ) { sTagStart = wStrPure.find( wTagKey ); if( sTagStart != std::wstring::npos ) { wStrPure.replace( sTagStart, wTagKey.size(), wTagString ); } } strPureCaption = nsl::uni::conv( wStrPure.c_str() ); // 태그를 모두 걸러낸 텍스트. DWORD dwHeight = 0; KTextRender::GetStringSize(sFontName.c_str(), this->GetFontSize(), bFontBold, strPureCaption.c_str(), strPureCaption.size(), &dwWidht, &dwHeight); if( bBr || dwWidht > m_rcCaptionArea.GetWidth() ) { //this->SetTooltip( m_sCaption.c_str() ); DWORD dwByte = GetOneLineStringByte( strSingleLine.c_str(), m_rcCaptionArea.GetWidth()-4 ); /// 2010.10.27 GetOneLineStringByte 할 때 넓이를 -4 했기 때문에 여기서는 안해도 됩니다. - prodongi //if( dwByte > 8 ) // dwByte -= 8; std::string newCaption; static StringOmitter omitter; /*if( omitter( newCaption, strPureCaption.c_str(), dwByte, "..." ) == false && bBr ) { newCaption += "..."; this->SetTooltip( m_sCaption.c_str() ); }*/ if( omitter( newCaption, strPureCaption.c_str(), dwByte, "..." ) ) this->SetTooltip( m_sCaption.c_str() ); else if( bBr ) { this->SetTooltip( m_sCaption.c_str() ); newCaption += "..."; } m_pCaptionPhrase->AddString( ( strDeco + newCaption ).c_str(), m_fZPos, true, false, m_bUseEmoticonFilter ); } else { this->SetTooltip( NULL ); m_pCaptionPhrase->AddString(m_sCaption.c_str(), m_fZPos, true, false, m_bUseEmoticonFilter); } //UpdateTip(); } else { m_pCaptionPhrase->AddString(m_sCaption.c_str(), m_fZPos, true, false, m_bUseEmoticonFilter, false, maxWidth); SetTooltip(NULL); } } else { // 2010.09.03 - prodongi m_pCaptionPhrase->AddString(m_sCaption.c_str(), m_fZPos, true, false, m_bUseEmoticonFilter, false, maxWidth); } /// 2011.02.23 - prodongi m_pCaptionPhrase->updateSpriteScrollInfo(); m_pCaptionPhrase->SetClipRect(m_rcClipArea); // MIMI 2005/08/17 이모티콘이 추가된 텍스트는 텍스쳐 크기가 틀려지므로 ?팁에 적용하기 위해 기억한다. if( GetClassName() == "tooltip" ) { m_nToolTipTextWidth = m_pCaptionPhrase->GetTextureSize().cx; m_nToolTipTextWidth += s_nBlankWidth; m_nToolTipTextHeight = m_pCaptionPhrase->GetTextureSize().cy; } } else { //_oprint( "DELETE CAPTION PHARSE : %s(%s)\n", m_sID.c_str(), m_sCaption.c_str() ); SAFE_DELETE(m_pCaptionPhrase); } } void KUIControl::UpdateTip() { if( false == m_sTip.empty() ) { SAFE_DELETE(m_pTipControl); KUIWND_CREATE_ARG arg; arg.lpszClassName = "tooltip"; arg.lpszID = "tool_tip"; arg.lpszCaption = m_sTip.c_str(); arg.lpszAniName = m_strTooltipAniName; arg.lpszSprName = "ui_frame.spr"; arg.rcRect = KRect( 0, 0, KUITipControl::m_dwTipWindowWidth, KUITipControl::m_dwTipWindowHeight ); arg.pParent = NULL; m_pTipControl = reinterpret_cast( m_pManager->CreateControl( arg) ); if( m_pTipControl ) m_pTipControl->UpdateTooltipRegion( m_pTipControl->m_nToolTipTextWidth, m_pTipControl->m_nToolTipTextHeight ); } // sonador 1.2.5 Lazy Tooltip 구현 else if( m_LazyTip ) { SAFE_DELETE(m_pTipControl); KUIWND_CREATE_ARG arg; arg.lpszClassName = "tooltip"; arg.lpszID = "tool_tip"; arg.lpszCaption = m_LazyTip->getTip(); arg.lpszAniName = m_strTooltipAniName; arg.lpszSprName = "ui_frame.spr"; arg.rcRect = KRect( 0, 0, KUITipControl::m_dwTipWindowWidth, KUITipControl::m_dwTipWindowHeight ); arg.pParent = NULL; m_pTipControl = reinterpret_cast( m_pManager->CreateControl( arg) ); if( m_pTipControl ) m_pTipControl->UpdateTooltipRegion( m_pTipControl->m_nToolTipTextWidth, m_pTipControl->m_nToolTipTextHeight ); } else { SAFE_DELETE(m_pTipControl); SAFE_DELETE_VECTOR( m_SubTipContorl ); } // 메인 툴팁이 있다면 서브 튤팁도 만든다. if( m_pTipControl != NULL ) { SAFE_DELETE_VECTOR( m_SubTipContorl ); if( m_SubTip.empty() == false ) { auto pos = m_SubTip.begin(); auto end = m_SubTip.end(); for( ; pos != end; ++pos ) { KUIWND_CREATE_ARG arg; arg.lpszClassName = "tooltip"; arg.lpszID = "tool_tip"; arg.lpszCaption = (*pos).c_str(); arg.lpszAniName = m_strTooltipAniName; arg.lpszSprName = "ui_frame.spr"; arg.rcRect = KRect( 0, 0, KUITipControl::m_dwTipWindowWidth, KUITipControl::m_dwTipWindowHeight ); arg.pParent = NULL; KUITipControl* pSubTipContorl = reinterpret_cast( m_pManager->CreateControl( arg) ); if( pSubTipContorl ) { pSubTipContorl->UpdateTooltipRegion( pSubTipContorl->m_nToolTipTextWidth, pSubTipContorl->m_nToolTipTextHeight ); m_SubTipContorl.push_back( pSubTipContorl ); } } } if( m_SubLazyTip.empty() == false ) { auto pos = m_SubLazyTip.begin(); auto end = m_SubLazyTip.end(); for( ; pos != end; ++pos ) { KUIWND_CREATE_ARG arg; arg.lpszClassName = "tooltip"; arg.lpszID = "tool_tip"; arg.lpszCaption = (*pos)->getTip(); arg.lpszAniName = m_strTooltipAniName; arg.lpszSprName = "ui_frame.spr"; arg.rcRect = KRect( 0, 0, KUITipControl::m_dwTipWindowWidth, KUITipControl::m_dwTipWindowHeight ); arg.pParent = NULL; KUITipControl* pSubTipContorl = reinterpret_cast( m_pManager->CreateControl( arg) ); if( pSubTipContorl ) { pSubTipContorl->UpdateTooltipRegion( pSubTipContorl->m_nToolTipTextWidth, pSubTipContorl->m_nToolTipTextHeight ); m_SubTipContorl.push_back( pSubTipContorl ); } } } } // 2010.05.06 - prodongi updateToolTipEmoticonSize(); } void KUIControl::SetRotate(float fRadian) { K3DMatrix matRot; K3DMatrixRotationZ( matRot, fRadian); for(int i = 0; i GetPosition()); m_vtSprite.at(i)->SetTransform(matRot); } } int KUIControl::GetOneLineStringByte(LPCSTR lpszText,DWORD dwWidth) { return KTextPhrase::GetOneLineStringByte( lpszText, dwWidth ); } void KUIControl::_destroyControl() { if( s_pToolTipOnControl == this ) SetNULLToolTipOnControl(); // [sonador] fix acess violation SAFE_DELETE( m_pCaptionPhrase ); SAFE_DELETE_ARRAY( m_pSpriteList ); SAFE_DELETE(m_pTipControl); SAFE_DELETE_VECTOR( m_SubTipContorl ); SAFE_DELETE(m_pDragObject ); } void KUIControl::_initControl() { // Back Ground Set UpdateBack(); // Caption Set UpdateCaption(); } void KUIControl::RenderToolTip(KViewportObject * pViewport, bool isFront) { _renderToolTip( pViewport, isFront ); } void KUIControl::_renderChild(KViewportObject* pViewport, bool isFront) { std::list< KUIWnd* >::iterator it = m_listChild.begin(); for ( ; it != m_listChild.end() ; ++it ) { (*it)->Render(pViewport, isFront); } } void KUIControl::_renderBack(KViewportObject * pViewport, bool isFront) { for(int i = 0; i < m_nPieceCount; ++i) { pViewport->Register(&m_pSpriteList[i], isFront); } std::vector::iterator it = m_vtSprite.begin(); std::vector::iterator end = m_vtSprite.end(); for(; it != end; ++it) { pViewport->Register( *it , isFront); } } void KUIControl::_renderCaption(KViewportObject * pViewport, bool isFront) { if(m_pCaptionPhrase) { m_pCaptionPhrase->Render(pViewport,isFront ); } std::vector::iterator it = m_vtTextPhrase.begin(); std::vector::iterator end = m_vtTextPhrase.end(); for(; it != end; ++it) { (*it)->Render(pViewport,isFront ); } } void KUIControl::_renderToolTip(KViewportObject * pViewport, bool isFront) { // sonador 1.2.5 Lazy Tooltip 구현 if( m_sTip.empty() && !m_LazyTip ) return; if(m_dwToolTipStartTime != 0) { // Tip Control을 Render if(NULL == m_pTipControl) { // sonador 1.2.5 Lazy Tooltip 구현 if( m_sTip.empty() == false || m_LazyTip ) { UpdateTip(); checkToolTipScreenBound(); /// 2010.11.01 기존에는 마우스를 움직여야만 체크가 되어 있어서, 체크가 안되는 경우가 발생 했음- prodongi } else return; } m_pTipControl->MovePos(m_nToolTipPosX,m_nToolTipPosY); m_pTipControl->Render(pViewport, isFront); if( m_SubTipContorl.empty() == false ) { int nSubToolTipPosX = m_nToolTipPosX; const int nLeftSpace = 34; // 왼쪽을 출력할때 마우스 커서로 인해 34 아이콘 하나 크기만큼 간격을 띄운다. int nRightWidth = KUIWndManager::GetResolution().width - nSubToolTipPosX - m_pTipControl->GetRect().GetWidth(); // 기본 툴팁 좌표가 화면의 오른쪽에 있다면 왼쪽에 표시한다. if( (nSubToolTipPosX - nLeftSpace) > nRightWidth ) { int nSubToolTipWidth = nLeftSpace; auto pos = m_SubTipContorl.begin(); auto end = m_SubTipContorl.end(); for( ; pos != end; ++pos ) { KUITipControl* pSubTip = (*pos); nSubToolTipWidth += pSubTip->GetRect().GetWidth(); } nSubToolTipPosX = m_nToolTipPosX - nSubToolTipWidth; } else { nSubToolTipPosX += m_pTipControl->GetRect().GetWidth(); } auto pos = m_SubTipContorl.begin(); auto end = m_SubTipContorl.end(); for( ; pos != end; ++pos ) { KUITipControl* pSubTip = (*pos); int nSubToolTipPosY = m_nToolTipPosY; int yDiff = KUIWndManager::GetResolution().height - (nSubToolTipPosY + pSubTip->GetRect().GetHeight() ); if(yDiff < 0) nSubToolTipPosY += yDiff; // Tip Control을 Render pSubTip->MovePos(nSubToolTipPosX, nSubToolTipPosY); pSubTip->Render(pViewport, isFront); nSubToolTipPosX += pSubTip->GetRect().GetWidth(); } } } } void KUIControl::_processToolTip() { // { [sonador] performance tunning if( m_dwToolTipPreStartTime == 0 && m_dwToolTipStartTime == 0 ) return; // } DWORD dwTime = GetSafeTickCount(); if(m_dwToolTipPreStartTime != 0 ) { // Tool Tip이 찍히는 도중이 아니면 if(m_dwToolTipStartTime == 0) { if( KUITipControl::GetToolTipOnOff() == false) { // if( 0 == dwTime ) DebugBreak(); m_dwToolTipStartTime = dwTime; KUITipControl::SetToolTipOnOff( true ); OnToolTipOnControl( this ); //부모에게 툴팁 설정 됨을 알림. if( m_pParent ) m_pParent->OnToolTipWnd( this ); } } } if(m_dwToolTipStartTime != 0) { // Drag 하는 경우에는 Tooltip 취소 if(dwTime - m_dwToolTipStartTime >= KUITipControl::GetContinueTime() || m_pManager->GetDragObject() != NULL ) _setToolTipOff(); // 2010.07.16 메세지박스가 출력되고 있을때 툴팁이 안나오도록 한다- prodongi else if (m_pManager->IsOpenModalWnd()) _setToolTipOff(); } } void KUIControl::_reArrangeRect(bool bHorizonPiece) { // AniName 이 없으면 만든 Sprite 삭제 if(m_sAniName.empty() ) { SAFE_DELETE_ARRAY(m_pSpriteList); m_nPieceCount = 0; return; } // Pos로 되어 있어서 Sprite로부터 Rect Size를 얻어오는 경우 if(m_bUsePosEnable && ( m_rcRegion.right == -1 || m_bUseCustomSize ) ) // #2.1.2.11.1 { KResSprite * pFrame = NULL; if( _getSpriteSet() ) pFrame = _getSpriteSet()->GetSpriteRes(m_sAniName.c_str(), m_nFrameIndex); if(pFrame) { m_nPieceCount = 1; if( !m_bUseCustomSize ) { m_rcRegion.right = int(m_rcRegion.left + pFrame->GetSizeX()); m_rcRegion.bottom = int(m_rcRegion.top + pFrame->GetSizeY()); } } m_rcPieceArea[0] = m_rcRegion; _makeSpriteForArrangedRect(); return; } if( _getSpriteSet() ) { m_nPieceCount = _getSpriteSet()->GetSpriteResAniCount( m_sAniName.c_str() ); if(m_nPieceCount < 1) return; int nLeft = m_rcRegion.left; int nTop = m_rcRegion.top; switch(m_nPieceCount) { case 1: { m_rcPieceArea[0] = m_rcRegion; } break; case 3: { // 가로로 세조각 KResSprite* pSpriteFrame_0( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 0 ) ); KResSprite* pSpriteFrame_2( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 2 ) ); if(bHorizonPiece) { int nCalcMidSizeX = m_rcRegion.GetWidth() - pSpriteFrame_0->GetSizeX() - pSpriteFrame_2->GetSizeX(); int nCalcMidSizeY = pSpriteFrame_0->GetSizeY(); for(int i(0); i < 3; ++i) { int nFrameSizeX( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i )->GetSizeX() ); int nFrameSizeY( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i )->GetSizeY() ); m_rcPieceArea[i].left = nLeft; m_rcPieceArea[i].top = nTop; m_rcPieceArea[i].right = nLeft + nFrameSizeX; m_rcPieceArea[i].bottom = nTop + nFrameSizeY; if(i == 1) { m_rcPieceArea[i].right = nLeft + nCalcMidSizeX; nLeft += nCalcMidSizeX; } else nLeft += nFrameSizeX; } } // 세로로 세조각 else { int nCalcMidSizeX = pSpriteFrame_0->GetSizeX(); int nCalcMidSizeY = m_rcRegion.GetWidth() - pSpriteFrame_0->GetSizeY() - pSpriteFrame_2->GetSizeY(); for(int i(0); i < 3; ++i) { int nFrameSizeX( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i )->GetSizeX() ); int nFrameSizeY( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i )->GetSizeY() ); m_rcPieceArea[i].left = nLeft; m_rcPieceArea[i].top = nTop; m_rcPieceArea[i].right = nLeft + nFrameSizeX; m_rcPieceArea[i].bottom = nTop + nFrameSizeY; if(i == 1) { m_rcPieceArea[i].bottom = nTop + nCalcMidSizeY; nTop += nCalcMidSizeY; } else nTop += nFrameSizeY; } } } break; case 9: // 9조각으로 찢어질 경우 { KResSprite* pSpriteFrame_0( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 0 ) ); KResSprite* pSpriteFrame_2( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 2 ) ); KResSprite* pSpriteFrame_6( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 6 ) ); int nCount = 0; int nCalcMidSizeX = m_rcRegion.GetWidth() - pSpriteFrame_0->GetSizeX() - pSpriteFrame_2->GetSizeX(); int nCalcMidSizeY = m_rcRegion.GetHeight() - pSpriteFrame_0->GetSizeY() - pSpriteFrame_6->GetSizeY(); // 찍는 부분 설정 for(int i = 0; i < 3; ++ i) { nLeft = m_rcRegion.left; for(int j = 0; j < 3; ++j) { int nFrameSizeX( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), nCount )->GetSizeX() ); int nFrameSizeY( _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), nCount )->GetSizeY() ); m_rcPieceArea[nCount].left = nLeft; m_rcPieceArea[nCount].top = nTop; m_rcPieceArea[nCount].right = m_rcPieceArea[nCount].left + nFrameSizeX; m_rcPieceArea[nCount].bottom = m_rcPieceArea[nCount].top + nFrameSizeY; // 중간 열 if( j == 1 ) { m_rcPieceArea[nCount].right = nLeft + nCalcMidSizeX; nLeft += nCalcMidSizeX; } else { nLeft += nFrameSizeX; } // 중간 행 if(i == 1) { m_rcPieceArea[nCount].bottom = nTop + nCalcMidSizeY ; } nCount++; } // Mid if( i == 0 ) nTop += pSpriteFrame_0->GetSizeY(); if( i == 1 ) nTop += nCalcMidSizeY; if( i == 2 ) nTop += pSpriteFrame_6->GetSizeY(); } } break; case 10: break; default: { _oprint( "Error!!! : Frame의 조각이 맞지 않습니다 - %s : %d\n", m_sAniName.c_str(), m_nPieceCount ); break; } } } _makeSpriteForArrangedRect(); } void KUIControl::_makeSpriteForArrangedRect() { SAFE_DELETE_ARRAY(m_pSpriteList); if(0 == m_nPieceCount) return; m_pSpriteList = new KSpritePrimitive[m_nPieceCount]; // Position을 사용할 경우 FrameIndex 에 지정된 Frame을 가져와서 만든다. if(true == m_bUsePos) { KResSprite * pFrame = NULL; if(_getSpriteSet()) pFrame = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), m_nFrameIndex ); if(NULL == pFrame) return; m_pSpriteList[0].SetRes(pFrame); m_pSpriteList[0].SetTargetSize( (float)m_rcPieceArea[0].GetWidth(), (float)m_rcPieceArea[0].GetHeight() ); m_pSpriteList[0].SetPosition( K3DVector((K3DVALUE)m_rcPieceArea[0].left , (K3DVALUE)m_rcPieceArea[0].top, m_fZPos ) ); return; } // 그게 아닐경우 조합 for(int i = 0; i GetSpriteRes( m_sAniName.c_str(), i ); if(NULL == pFrame) continue; m_pSpriteList[i].SetRes(pFrame); m_pSpriteList[i].SetTargetSize( (float)m_rcPieceArea[i].GetWidth(), (float)m_rcPieceArea[i].GetHeight() ); m_pSpriteList[i].SetPosition( K3DVector((K3DVALUE)m_rcPieceArea[i].left ,(K3DVALUE)m_rcPieceArea[i].top, m_fZPos ) ); } } void KUIControl::_setToolTipOff() { KUITipControl::SetToolTipOnOff( false ); m_dwToolTipStartTime = 0; m_dwToolTipPreStartTime = 0; #ifdef _KUI_INVALIDATION m_pParent->OnToolTipWnd( NULL ); #endif } void KUIControl::UpdateUV( KRect rt ) { SAFE_DELETE_ARRAY(m_pSpriteList); if( m_nPieceCount == 0 ) return; m_pSpriteList = new KSpritePrimitive[m_nPieceCount]; for( int i = 0; i < m_nPieceCount; i++ ) { KResSprite* pFrame = NULL; if( _getSpriteSet() ) pFrame = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i ); if( pFrame == NULL ) continue; if( pFrame->GetTexture() == NULL ) continue; m_pSpriteList[i].SetRes( pFrame ); // uv 좌표 구한다 float fX = static_cast(rt.left+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); float fY = static_cast(rt.top+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); float fR = static_cast(rt.right+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); float fB = static_cast(rt.bottom+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); m_pSpriteList[i].SetSourceUVRect( fX, fY, fR, fB ); m_pSpriteList[i].SetTargetSize( static_cast(m_rcPieceArea[i].GetWidth()), static_cast(m_rcPieceArea[i].GetHeight()) ); m_pSpriteList[i].SetPosition( K3DVector( (K3DVALUE)GetRect().left ,(K3DVALUE)GetRect().top, m_fZPos ) ); m_pSpriteList[i].SetVisibility( m_fAlpha ); } } //void KUIControl::UpdateUV( KRect rt, int nTextureCount, int nMapPosX, int nMapPosY ) //{ // SAFE_DELETE_ARRAY(m_pSpriteList); // if( m_nPieceCount == 0 ) return; // // int nPieceCount = nTextureCount; nPieceCount++; // // if( nPieceCount%2 != 0 ) nPieceCount = 1; // // m_nPieceCount = nPieceCount; // // m_pSpriteList = new KSpritePrimitive[nPieceCount]; // KResSprite* pFrame = NULL; // switch(nPieceCount) // { // case 1: // { // if( _getSpriteSet() ) pFrame = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 0 ); // if( pFrame == NULL ) return; // // m_pSpriteList[0].SetRes( pFrame ); // // // uv 좌표 구한다 // float fX = static_cast(rt.left+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); // float fY = static_cast(rt.top+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); // float fR = static_cast(rt.right+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); // float fB = static_cast(rt.bottom+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); // // m_pSpriteList[0].SetSourceUVRect( fX, fY, fR, fB ); // m_pSpriteList[0].SetTargetSize( static_cast(m_rcPieceArea[0].GetWidth()), static_cast(m_rcPieceArea[0].GetHeight()) ); // m_pSpriteList[0].SetPosition( K3DVector( (K3DVALUE)GetRect().left ,(K3DVALUE)GetRect().top, m_fZPos ) ); // } // break; // case 2: // { // std::string strAniName[2]; // strAniName[0] = m_sAniName; // KRect rtTexture[2]; rtTexture[0] = rt; rtTexture[1] = rt; // int nOffsetX[2], nOffsetY[2]; // for( int i = 0; i < nPieceCount; i++ ) // { // nOffsetX[i] = GetRect().left; // nOffsetY[i] = GetRect().top; // } // // int nMapIndex = 0; // if( ::_stricmp( GetID(), "worldmap_small" ) == 0 ) nMapIndex = WORLDMAP_INDEX; // else nMapIndex = MINIMAP_INDEX; // // // ↑ or ↓ // if( rt.top < 0 || rt.bottom > GetTextureSizeY() ) // { // if( rt.top < 0 ) // { // rtTexture[0].top = 0; // // rtTexture[1].top = GetTextureSizeY() + rt.top; // rtTexture[1].bottom = GetTextureSizeY(); // // strAniName[1] = c_szMapAniName[c_nMapIndex[nMapPosY+1][nMapPosX]][nMapIndex]; // nOffsetY[0] = GetRect().top + rtTexture[1].GetHeight(); // } // else if( rt.bottom > GetTextureSizeY() ) // { // rtTexture[0].bottom = GetTextureSizeY(); // // rtTexture[1].top = 0; // rtTexture[1].bottom = rt.bottom - GetTextureSizeY(); // // strAniName[1] = c_szMapAniName[c_nMapIndex[nMapPosY-1][nMapPosX]][nMapIndex]; // nOffsetY[1] = GetRect().top + rtTexture[0].GetHeight(); // } // } // // ← or → // else if( rt.left < 0 || rt.right > GetTextureSizeX() ) // { // if( rt.left < 0 ) // { // rtTexture[0].left = 0; // // rtTexture[1].left = GetTextureSizeX() + rt.left; // rtTexture[1].right = GetTextureSizeX(); // // strAniName[1] = c_szMapAniName[c_nMapIndex[nMapPosY][nMapPosX-1]][nMapIndex]; // nOffsetX[0] = GetRect().left + rtTexture[1].GetWidth(); // } // else if( rt.right > GetTextureSizeX() ) // { // rtTexture[0].right = GetTextureSizeX(); // // rtTexture[1].left = 0; // rtTexture[1].right = rt.right - GetTextureSizeX(); // // strAniName[1] = c_szMapAniName[c_nMapIndex[nMapPosY][nMapPosX+1]][nMapIndex]; // nOffsetX[1] = GetRect().left + rtTexture[0].GetWidth(); // } // } // // for( int i = 0; i < nPieceCount; i++ ) // { // if( _getSpriteSet() ) pFrame = _getSpriteSet()->GetSpriteRes( strAniName[i].c_str(), 0 ); // if( pFrame == NULL ) continue; // // m_pSpriteList[i].SetRes( pFrame ); // // // uv 좌표 구한다 // float fX = static_cast(rtTexture[i].left+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); // float fY = static_cast(rtTexture[i].top+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); // float fR = static_cast(rtTexture[i].right+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); // float fB = static_cast(rtTexture[i].bottom+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); // // m_pSpriteList[i].SetSourceUVRect( fX, fY, fR, fB ); // m_pSpriteList[i].SetTargetSize( static_cast(rtTexture[i].GetWidth()), static_cast(rtTexture[i].GetHeight()) ); // m_pSpriteList[i].SetPosition( K3DVector( (K3DVALUE)nOffsetX[i] ,(K3DVALUE)nOffsetY[i], m_fZPos ) ); // } // } // break; // case 4: // { // if( _getSpriteSet() ) pFrame = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 0 ); // if( pFrame == NULL ) return; // // m_pSpriteList[0].SetRes( pFrame ); // // // uv 좌표 구한다 // float fX = static_cast(rt.left+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); // float fY = static_cast(rt.top+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); // float fR = static_cast(rt.right+pFrame->GetRectSrc().left) / static_cast(pFrame->GetTexture()->GetSize().width); // float fB = static_cast(rt.bottom+pFrame->GetRectSrc().top) / static_cast(pFrame->GetTexture()->GetSize().height); // // m_pSpriteList[0].SetSourceUVRect( fX, fY, fR, fB ); // m_pSpriteList[0].SetTargetSize( static_cast(m_rcPieceArea[0].GetWidth()), static_cast(m_rcPieceArea[0].GetHeight()) ); // m_pSpriteList[0].SetPosition( K3DVector( (K3DVALUE)GetRect().left ,(K3DVALUE)GetRect().top, m_fZPos ) ); // } // break; // } //} int KUIControl::GetTextureSizeX() { if( m_nPieceCount == 0 ) return -1; KResSprite* pFrame = NULL; if( _getSpriteSet() ) pFrame = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 0 ); if( pFrame == NULL ) return -1; return pFrame->GetSizeX(); } int KUIControl::GetTextureSizeY() { if( m_nPieceCount == 0) return -1; KResSprite* pFrame = NULL; if( _getSpriteSet() ) pFrame = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 0 ); if( pFrame == NULL ) return -1; return pFrame->GetSizeY(); } void KUIControl::SetTooltipOff() { _setToolTipOff(); } static void GetTextWidth( SIZE& size, const char* szText, int nLen, const char* szFontName, int nFontSize, bool bBold ) { //GetTextExtentPoint32( KTextRender::GetStaticDC(), szText, nLen, &size ); DWORD nW, nH; KTextRender::GetStringSize( szFontName, nFontSize, bBold, szText, nLen, &nW, &nH ); size.cx = nW; size.cy = nH; } void KUIControl::SplitLine( std::vector< std::string > & vecLineList, const std::string& strOriginal, const char* szFontName, int nFontSize, bool bBold, bool bUseFontSize /*= false*/ ) { #ifdef _DEBUG int nDWidth = GetRect().GetWidth(); int nDHeight = GetRect().GetHeight(); #endif std::vector< std::string > vTextList; { std::string strTmp = strOriginal; size_t pos, pos0, pos1; while( true ) { pos0 = strTmp.find( "
" ); pos1 = strTmp.find( "
" ); if( pos0 != strTmp.npos && pos1 != strTmp.npos ) pos = std::min( pos0, pos1 ); else if( pos0 != strTmp.npos ) pos = pos0; else if( pos1 != strTmp.npos ) pos = pos1; else { if( !strTmp.empty() ) vTextList.push_back( strTmp ); break; } std::string strLine( strTmp.begin(), strTmp.begin() + pos ); vTextList.push_back( strLine ); strTmp = strTmp.substr( pos + 4, strTmp.size() ); } } while( !vTextList.empty() ) { std::string strTmp = vTextList.front(); if( strTmp.size() == 0 ) { vecLineList.push_back( strTmp ); vTextList.erase( vTextList.begin() ); continue; } { std::vector< std::string > vTempList; //KTextPhrase::GetSplitString( CStringUtil::StringFormat( "%s", szFontName, nFontSize, strTmp.c_str() ).c_str(), GetRect().GetWidth(), vTempList, bUseFontSize ); // 텍스트 분할을 하기위해 태그 가 필요하다. bintite. 2010.09.29. std::string::size_type fpos = strTmp.find( "%s", szFontName, nFontSize, strTmp.c_str() ).c_str(), GetRect().GetWidth(), vTempList, bUseFontSize ); else KTextPhrase::GetSplitString( strTmp.c_str(), GetRect().GetWidth(), vTempList, bUseFontSize ); for( unsigned int i(0); vTempList.size()>i; i++ ) vecLineList.push_back( vTempList[i].c_str() ); } vTextList.erase( vTextList.begin() ); } // { 처음 공백은 무시해 달라는 구랴... for( std::vector< std::string >::iterator it = vecLineList.begin(); it != vecLineList.end(); ++it ) { while( !(*it).empty() ) { if( (*it)[0] != ' ' ) break; (*it) = (*it).substr( 1, (*it).size()-1 ); } } } #include "KUITextureManager.h" // 2010.03.15 - bintitle // 자신과 동일한 control을 생성하여 반환. KUIControl * KUIControl::Clone() { KUIControl * pControl = static_cast< KUIControl * >( m_pManager->CreateControl( KUIWND_CREATE_ARG( m_sClassName.c_str(), this->GetID(),//GetClassNameA().c_str(), GetCaption(), GetRect(), GetStyle(), GetFlag(), GetParent(), GetAniName(), GetSprName(), m_pManager, GetFrameIndex(), "", GetAnchor() ) ) ); pControl->SetEnableColor( m_strEnableColor.c_str() ); pControl->SetDisableColor( m_strDisableColor.c_str() ); return pControl; } // 2010.03.15 - bintitle // 자신과 동일한 control을 생성하여 반환. KUIControl * KUIControl::Clone( const char * newName ) { return static_cast< KUIControl * >( m_pManager->CreateControl( KUIWND_CREATE_ARG( m_sClassName.c_str(), newName, GetCaption(), GetRect(), GetStyle(), GetFlag(), GetParent(), GetAniName(), GetSprName(), m_pManager, GetFrameIndex(), "", GetAnchor() ) ) ); } // bintitle. void KUIControl::SetColor( KColor & color ){ if( m_pSpriteList ) m_pSpriteList->SetColor( color ); } // Modified. bintitle. 2010.09.29 // Trim the caption to fit the window size (add "..." at the end), // and show the original caption as a tooltip. void KUIControl::CutCaptionNTooltip() { // 추가. bintitle. 2010.10.01. if( m_sCaption.empty() ) return; //
태그가 속한 텍스트는 무시. std::string::size_type nPos = m_sCaption.find( "
" ); if( nPos != -1 ) return; // Font명 얻기. std::string fontName = "Default"; nPos = m_sCaption.find( "" ); fontName = strTemp.substr( 0, nPos_End ); } // FontSize. int nFontSize = this->GetFontSize(); m_sOrgCaption = m_sCaption; // 원본 복사. // 잘림처리( .. ) std::vector< std::string > arrString; // 텍스트 분할. this->SplitLine( arrString, m_sCaption, fontName.c_str(), nFontSize, fontName == "font_02" ? true : false, true ); if( arrString.size() > 1 ) { m_bCutCaption = true; // 제목의 잘림처리 여부. // Tooltip. this->SetTooltip( m_sOrgCaption.c_str() ); UpdateTip(); // 분할한 텍스트의 첫행. std::wstring wstr( nsl::uni::conv(arrString[0]) ); // 2010.10.01. bintitle. // 2010.10.01 맨 뒤에 짜투리 스트링이 있을 경우- prodongi std::wstring extraStr; std::wstring::size_type extraPos = wstr.rfind(L">"); if (extraPos != (wstr.size()-1)) { extraStr = wstr.substr(extraPos+1, wstr.size()-1); } if (extraStr.empty()) { cutCaptionNToolTipWithTag(wstr, 3); } else { if (3 <= extraStr.size()) { wstr.erase(wstr.end()-1); wstr.erase(wstr.end()-1); wstr.erase(wstr.end()-1); wstr += L"..."; /// 2010.10.25 ".."-> "..." - prodongi } else { wstr = wstr.substr(0, extraPos+1); cutCaptionNToolTipWithTag(wstr, 3 - extraStr.size()); } } std::string textDecorate( m_sOrgCaption ); // 앞부분 꾸미기태그 얻기 : 번역 전 텍스트( 스트링 ID ) 인 경우. std::string::size_type nPos = textDecorate.find( "<$" ); if( nPos != std::string::npos ) { textDecorate = textDecorate.substr( 0, nPos ); nPos = textDecorate.rfind( ">" ) + 1; textDecorate = textDecorate.substr( 0, nPos ) ; } // 앞부분 꾸미기태그 얻기 : 번역 후 텍스트( 스트링 ID가 실제 텍스트로 변환 ) 인 경우. else { nPos = textDecorate.rfind( ">" ) + 1; textDecorate = textDecorate.substr( 0, nPos ) ; //textDecorate.erase(); //// 텍스트 꾸미기태그분리( 텍스트 내부의 태그는 제외 ). ////std::wstring wStrPure( wstr ); //std::wstring wStrPure( nsl::uni::conv(m_sCaption.c_str())); //std::wstring::size_type sEnd; //std::wstring::size_type oldEnd = 0; //// ★ 태그를 제외한 텍스트만을 걸러낸다. //if( !wStrPure.empty() ) //{ // while( 1 ) // { // std::wstring::size_type sStart = wStrPure.find_first_of( L"<" ); // if( sStart != std::wstring::npos ) // { // // 텍스트 꾸미기태그분리( 텍스트 내부의 태그는 제외 ). // if( textDecorate.empty() && sStart > 0 ) // textDecorate = m_sCaption.substr( 0, oldEnd ).c_str(); // // "<" 는 존재하는데 ">" 는 없다는 것도 태그가 없는 것. // sEnd = wStrPure.find_first_of( L">" ); // // if( sEnd == std::wstring::npos || sStart > sEnd ) // break; // else // oldEnd += sEnd + 1; // wStrPure = wStrPure.replace( sStart, sEnd - sStart + 1, L"" ); // } // // 텍스트에 "<" 이 문자가 없다는 것은 태그가 없다는 것. 모두 걸러내었다! 종료. // else // { // // 텍스트 꾸미기태그분리( 텍스트에 태그가 없는 경우 ). // if( textDecorate.empty() && oldEnd > 0 ) // textDecorate = m_sCaption.substr( 0, oldEnd ).c_str(); // break; // } // } //} } // Caption 설정. textDecorate += nsl::uni::conv(wstr.c_str()); this->SetCaption( textDecorate.c_str() ); } else { m_bCutCaption = false; // 제목의 잘림처리 여부. // Tooltip. this->SetTooltip(); } } // 2010.05.06 - prodongi void KUIControl::addEmoticonSize(std::string const& aniName, int width, int height) { m_emoticonSizeList.push_back(sEmoticonSize(aniName, width, height)); } // 2010.05.06 - prodongi void KUIControl::updateToolTipEmoticonSize() { if (!m_pTipControl) return ; if (m_emoticonSizeList.empty()) return ; std::vector::iterator it = m_emoticonSizeList.begin(); for (; it != m_emoticonSizeList.end(); ++it) { m_pTipControl->applyEmoticonSize(it->m_aniName, it->m_width, it->m_height); } m_emoticonSizeList.clear(); } // 2010.10.01 - prodongi void KUIControl::cutCaptionNToolTipWithTag(std::wstring& wstr, size_t strEraseCount) { // 2010.10.01. bintitle. // 분할한 텍스트에서 순수한텍스트 의 뒤에 <태그> 가 있는 경우에 제거한다. // ex >> "<#b35134>ABC<#ffffff>" 이런 텍스트의 경우 "<#b35134>ABC" 와 "<#ffffff>" 를 분리 하는 것이다. std::vector< std::wstring > arrStrEndTag; while( 1 ) { std::wstring::size_type eTagpos = wstr.rfind( L">" ); if( eTagpos != std::wstring::npos && eTagpos == ( wstr.size()-1 ) ) { std::wstring::size_type sTagpos = wstr.rfind( L"<" ); if( sTagpos != std::wstring::npos ) { arrStrEndTag.push_back( wstr.substr( sTagpos, eTagpos ) ); wstr = wstr.substr( 0, sTagpos ); } else break; } else break; } // 2010.06.08 조건 추가 - prodongi for (size_t i = 0; i < strEraseCount; ++i) { if (wstr.size() > 0) wstr.erase(wstr.end()-1); } wstr += L"..."; /// 2010.10.25 ".."-> "..." - prodongi // 2010.10.01. bintitle. // 뒷부분의 태그를 제거한 경우 ".." 처리 후 추가한다. 제거시에 거꾸로 추가되었기때문에 뒤에서부터 추가. if( !arrStrEndTag.empty() ) { int size = arrStrEndTag.size(); for( int i=size-1; i>=0; --i ) wstr += arrStrEndTag[ i ]; // 2010.10.01 - prodongi arrStrEndTag.clear(); } } /// 2010.11.01 - prodongi void KUIControl::checkToolTipScreenBound() { if (!m_pTipControl) return ; if( m_bToolTipLeftRender ) { m_nToolTipPosX -= m_pTipControl->GetRect().GetWidth(); if( m_nToolTipPosX<0 ) m_nToolTipPosX=0; } int xDiff = KUIWndManager::GetResolution().width - (m_nToolTipPosX + m_pTipControl->GetRect().GetWidth() ); int yDiff = KUIWndManager::GetResolution().height - (m_nToolTipPosY + m_pTipControl->GetRect().GetHeight() ); if(xDiff < 0) m_nToolTipPosX += xDiff; if(yDiff < 0) m_nToolTipPosY += yDiff; } // 2011.03.23 - servantes bool KUIControl::GetUVScrollEndFlag() { KTextPhrase* pPhrase = GetCaptionPhrase(); if(NULL == pPhrase) return false; std::vector* pList = pPhrase->GetLineList(); if(NULL == pList) return false; KTextPhrase::KTEXT_LINE_OBJECT* pLineObj = pList->at(0); if(NULL == pLineObj) return false; KTextPhrase::KTEXT_OBJECT Obj = pLineObj->vtLineObject.at(0); KSpritePrimitive* pSP = Obj.pRender->GetSpritePrimitive(); if(NULL == pSP) return false; sSpritePrimitiveScrollType* pScrollType = pSP->GetScroll(); if(NULL == pScrollType) return false; return pScrollType->m_bEnd; } // 2011.03.23 - servantes void KUIControl::ResetUVScrollEndFlag() { KTextPhrase* pPhrase = GetCaptionPhrase(); if(NULL == pPhrase) return ; std::vector* pList = pPhrase->GetLineList(); if(NULL == pList) return ; KTextPhrase::KTEXT_LINE_OBJECT* pLineObj = pList->at(0); if(NULL == pLineObj) return ; KTextPhrase::KTEXT_OBJECT Obj = pLineObj->vtLineObject.at(0); KSpritePrimitive* pSP = Obj.pRender->GetSpritePrimitive(); if(NULL == pSP) return ; sSpritePrimitiveScrollType* pScrollType = pSP->GetScroll(); if(NULL == pScrollType) return ; pScrollType->m_bEnd = false; } #endif