DragonNest/Common/EtInterface/EtUIEditBox.cpp

1832 lines
48 KiB
C++
Raw Normal View History

2024-12-19 09:48:26 +08:00
#include "StdAfx.h"
#include "EtUIEditBox.h"
#include "EtUIDialog.h"
#include "EtUIIME.h"
#include "StringUtil.h"
#include "strsafe.h"
#include "EtUINameLinkMgr.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
SUICoord CEtUIEditBox::s_CurrentCaretPos;
std::vector<WCHAR> CEtUIEditBox::s_vecInvalidCharater;
bool CEtUIEditBox::s_bCheckThaiLanguageVowelRule = false;
CEtUIEditBox::CEtUIEditBox( CEtUIDialog *pParent )
: CEtUIControl( pParent )
{
m_Property.UIType = UI_CONTROL_EDITBOX;
m_bCaretOn = true;
m_fCaretBlinkTime = GetCaretBlinkTime() * 0.001f;
QueryPerformanceCounter( &m_liLastBlinkTime );
m_nFirstVisible = 0;
m_nLastVisible = 0;
m_nCaret = 0;
m_FullTextCaret = 0;
m_nSelStart = 0;
m_bInsertMode = true;
m_bMouseDrag = false;
m_fCompositionWidth = 0.0f;
m_nFilterOption = 0;
m_RenderTextColor = 0;
}
CEtUIEditBox::~CEtUIEditBox(void)
{
}
void CEtUIEditBox::Initialize( SUIControlProperty *pProperty )
{
CEtUIControl::Initialize( pProperty );
UpdateRects();
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
}
void CEtUIEditBox::SetTemplate( int nTemplateIndex )
{
CEtUIControl::SetTemplate( nTemplateIndex );
SUIElement *pElement(NULL);
pElement = GetElement(0);
//if( pElement )
//{
// ID3DXFont *pFont = m_pParent->GetFont( pElement->nFontIndex, pElement->nFontHeight );
// SetFont( pFont );
//}
if( m_Property.EditBoxProperty.dwMaxChars == 0 )
m_Property.EditBoxProperty.dwMaxChars = 256;
SetMaxEditLength( m_Property.EditBoxProperty.dwMaxChars );
}
void CEtUIEditBox::Focus( bool bFocus )
{
CEtUIControl::Focus( bFocus );
CEtUIControl::SetFocusEditBox( IsFocus() );
ResetCaretBlink();
if( IsFocus() )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_FOCUS, true, this );
}
else
{
m_pParent->ProcessCommand( EVENT_EDITBOX_RELEASEFOCUS, true, this );
SetSelection(GetCaretPos(), GetCaretPos());
}
}
void CEtUIEditBox::SetText( LPCWSTR wszText, bool bSelected )
{
ASSERT( wszText != NULL );
const CEtUINameLinkMgr& nameLinkMgr = EtInterface::GetNameLinkMgr();
std::wstring translated = wszText;
if (translated.empty() == false)
nameLinkMgr.TranslateText(translated, wszText);
if( m_Buffer.SetText( translated.c_str() ) )
m_FullTextBuffer.SetText( wszText );
m_nFirstVisible = 0;
PlaceCaret( m_Buffer.GetTextSize() );
if( bSelected )
{
m_nSelStart = 0;
}
else
{
m_nSelStart = m_nCaret;
}
}
void CEtUIEditBox::AddText( LPCWSTR wszText, bool bFocus )
{
ASSERT( wszText != NULL );
std::wstring translated;
int pureTextLength = EtInterface::GetNameLinkMgr().TranslateText( translated, wszText );
if( m_Buffer.IsEnableInsertString( m_nCaret, translated.c_str() ) &&
m_FullTextBuffer.IsEnableInsertString( m_FullTextCaret, wszText ) )
{
m_Buffer.InsertString( m_nCaret, translated.c_str(), -1, true );
m_FullTextBuffer.InsertString( m_FullTextCaret, wszText, -1, true );
PlaceCaret( m_nCaret + pureTextLength );
m_nSelStart = m_nCaret;
if( bFocus && m_bFocus == false )
m_pParent->RequestFocus( this );
}
}
HRESULT CEtUIEditBox::GetTextCopy( LPWSTR strDest, UINT bufferCount )
{
ASSERT( strDest );
if( bufferCount != 0 ) {
//wcscpy_s( strDest, bufferCount, m_Buffer.GetBuffer() );
StringCchCopyW(strDest, bufferCount, m_Buffer.GetBuffer());
}
return S_OK;
}
void CEtUIEditBox::ClearText()
{
m_FullTextBuffer.Clear();
m_Buffer.Clear();
m_RenderBuffer.Clear();
m_nFirstVisible = 0;
PlaceCaret( 0 );
m_nSelStart = 0;
}
void CEtUIEditBox::ClearTextMemory()
{
m_FullTextBuffer.ClearMemory();
m_Buffer.ClearMemory();
m_RenderBuffer.ClearMemory();
m_nFirstVisible = 0;
PlaceCaret( 0 );
m_nSelStart = 0;
}
int CEtUIEditBox::GetTextToInt()
{
const WCHAR *pBuffer = m_Buffer.GetBuffer();
if( pBuffer )
{
if( wcslen( pBuffer ) == 0 )
return -1;
return _wtoi( pBuffer );
}
return 0;
}
void CEtUIEditBox::SetIntToText( int nValue )
{
WCHAR wszBuffer[256]={0};
_itow( nValue, wszBuffer, 10 );
SetText( wszBuffer, false );
}
INT64 CEtUIEditBox::GetTextToInt64()
{
const WCHAR *pBuffer = m_Buffer.GetBuffer();
if( pBuffer )
{
return _wtoi64( pBuffer );
}
return 0;
}
void CEtUIEditBox::SetInt64ToText( INT64 nValue )
{
WCHAR wszBuffer[256]={0};
_i64tow( nValue, wszBuffer, 10 );
SetText( wszBuffer, false );
}
#define IN_FLOAT_CHARSET( c ) \
( (c) == L'-' || (c) == L'.' || ( (c) >= L'0' && (c) <= L'9' ) )
void CEtUIEditBox::ParseFloatArray( float *pNumbers, int nCount )
{
int nWritten;
const WCHAR *pToken, *pEnd;
WCHAR wszToken[ 60 ];
nWritten = 0;
pToken = m_Buffer.GetBuffer();
while( ( nWritten < nCount ) && ( *pToken != L'\0' ) )
{
while( *pToken == L' ' )
{
pToken++;
}
if( *pToken == L'\0' )
{
break;
}
// Locate the end of number
pEnd = pToken;
while( IN_FLOAT_CHARSET( *pEnd ) )
{
pEnd++;
}
int nTokenLen;
nTokenLen = min( sizeof( wszToken ) / sizeof( wszToken[ 0 ] ) - 1, int( pEnd - pToken ) );
wcscpy_s( wszToken, nTokenLen, pToken );
*pNumbers = ( float )wcstod( wszToken, NULL );
nWritten++;
pNumbers++;
pToken = pEnd;
}
}
void CEtUIEditBox::SetTextFloatArray( const float *pNumbers, int nCount )
{
WCHAR wszBuffer[ 512 ] = { 0 };
WCHAR wszTmp[ 64 ];
if( pNumbers == NULL )
{
return;
}
int i;
for( i = 0; i < nCount; i++ )
{
swprintf_s( wszTmp, 64, L"%.4f ", pNumbers[i] );
wcscat_s( wszBuffer, 512, wszTmp );
}
if( ( nCount > 0 ) && ( wcslen( wszBuffer ) > 0 ) )
{
wszBuffer[ wcslen( wszBuffer ) - 1 ] = 0;
}
SetText( wszBuffer );
}
bool CEtUIEditBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( !IsEnable() || !IsShow() || !IsKeyLock())
{
return false;
}
bool bHandled(false);
if( uMsg == WM_KEYDOWN )
{
switch( wParam )
{
case VK_HOME:
PlaceCaret( 0 );
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_END:
PlaceCaret( m_Buffer.GetTextSize() );
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_INSERT:
if( GetKeyState( VK_CONTROL ) < 0 )
{
CopyToClipboard();
}
else if( GetKeyState( VK_SHIFT ) < 0 )
{
PasteFromClipboard();
}
else
{
m_bInsertMode = !m_bInsertMode;
}
break;
case VK_DELETE:
if( m_nCaret != m_nSelStart )
{
DeleteSelectionText();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
else
{
if (RemoveChar(m_nCaret, 1))
{
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
}
ResetCaretBlink();
bHandled = true;
break;
case VK_LEFT:
if( GetKeyState( VK_CONTROL ) < 0 )
{
// Note : <20>ѱۿ<D1B1><DBBF><EFBFBD><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵȴ<C8B5>. <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20><> <20><>...
m_Buffer.GetPriorItemPos( m_nCaret, &m_nCaret );
PlaceCaret( m_nCaret );
}
else if( m_nCaret > 0 )
{
PlaceCaret( GetPrevCaret() );
}
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_RIGHT:
if( GetKeyState( VK_CONTROL ) < 0 )
{
m_Buffer.GetNextItemPos( m_nCaret, &m_nCaret );
PlaceCaret( m_nCaret );
}
else if( m_nCaret < m_Buffer.GetTextSize() )
{
PlaceCaret( GetNextCaret() );
}
if( GetKeyState( VK_SHIFT ) >= 0 )
{
m_nSelStart = m_nCaret;
}
ResetCaretBlink();
bHandled = true;
break;
case VK_UP:
if( GetKeyState( VK_SHIFT ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_SHIFT_KEYUP, true, this );
}
else if ( GetKeyState( VK_LCONTROL ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_LCTRL_KEYUP, true, this );
}
else
{
m_pParent->ProcessCommand( EVENT_EDITBOX_KEYUP, true, this );
}
bHandled = true;
break;
case VK_DOWN:
if( GetKeyState( VK_SHIFT ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_SHIFT_KEYDOWN, true, this );
}
else if ( GetKeyState( VK_LCONTROL ) < 0 )
{
m_pParent->ProcessCommand( EVENT_EDITBOX_LCTRL_KEYDOWN, true, this );
}
else
{
m_pParent->ProcessCommand( EVENT_EDITBOX_KEYDOWN, true, this );
}
bHandled = true;
break;
case VK_ESCAPE:
m_pParent->ProcessCommand( EVENT_EDITBOX_ESCAPE, true, this );
bHandled = true;
break;
case VK_TAB:
break;
default:
bHandled = wParam != VK_ESCAPE;
}
}
return bHandled;
}
bool CEtUIEditBox::HandleMouse( UINT uMsg, float fX, float fY, WPARAM wParam, LPARAM lParam )
{
if( !IsEnable() || !IsShow() || !IsKeyLock())
{
return false;
}
switch( uMsg )
{
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
{
if( !m_bFocus )
{
m_pParent->RequestFocus( this );
}
if( !IsInside( fX, fY ) )
{
return false;
}
m_bMouseDrag = true;
SetCapture( m_pParent->GetHWnd() );
int nCP, nTrail, nX1st;
CEtFontMng& FontMng = CEtFontMng::GetInstance();
SUIElement* pElement = GetElement( 0 );
nX1st = FontMng.GetCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible );
//m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st );
nCP = FontMng.GetCaretFromCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight,
( int )( m_pParent->GetScreenWidth() * ( fX - m_TextCoord.fX ) + nX1st ), nTrail );
// nTrail <20>̶<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD> <20>;<EFBFBD><CDBE>ϴ<EFBFBD><CFB4><EFBFBD> <20><><EFBFBD>θ<EFBFBD> <20>˷<EFBFBD><CBB7>ִ<EFBFBD> <20><><EFBFBD>̴<EFBFBD>
if( 0 <= nCP )
//if( SUCCEEDED( m_Buffer.XtoCP( ( int )( m_pParent->GetScreenWidth() * ( fX - m_TextCoord.fX ) + nX1st ), &nCP, &nTrail ) ) )
{
if( ( nTrail ) && ( nCP < m_Buffer.GetTextSize() ) )
{
PlaceCaret( nCP + 1 );
}
else
{
PlaceCaret( nCP );
}
m_nSelStart = m_nCaret;
ResetCaretBlink();
}
return true;
}
case WM_LBUTTONUP:
ReleaseCapture();
m_bMouseDrag = false;
break;
case WM_MOUSEMOVE:
if( m_bMouseDrag )
{
int nCP, nTrail, nX1st;
CEtFontMng& FontMng = CEtFontMng::GetInstance();
SUIElement* pElement = GetElement( 0 );
nX1st = FontMng.GetCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible );
//m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st );
nCP = FontMng.GetCaretFromCaretPos( m_Buffer.GetBuffer(), pElement->nFontIndex, pElement->nFontHeight,
( int )( m_pParent->GetScreenWidth() * (fX-GetUICoord().fX) + nX1st ), nTrail );
if( 0 <= nCP )
//if( SUCCEEDED( m_Buffer.XtoCP( ( int )( m_pParent->GetScreenWidth() * fX + nX1st ), &nCP, &nTrail ) ) )
{
if( ( nTrail ) && ( nCP < m_Buffer.GetTextSize() ) )
{
PlaceCaret( nCP + 1 );
}
else
{
PlaceCaret( nCP );
}
}
}
break;
}
return false;
}
bool CEtUIEditBox::InsertChar(WCHAR wChar)
{
if( m_Buffer.IsEnableInsertChar( m_nCaret, wChar ) &&
m_FullTextBuffer.IsEnableInsertChar( m_FullTextCaret, wChar ) )
{
m_Buffer.InsertChar( m_nCaret, wChar, true );
m_FullTextBuffer.InsertChar( m_FullTextCaret, wChar, true );
return true;
}
return false;
}
bool CEtUIEditBox::OverTypeChar(WCHAR wChar)
{
if (RemoveChar(m_nCaret, 1))
return InsertChar(wChar);
return false;
}
void CEtUIEditBox::GetFullTextTagFieldPos(int& tagFieldStart, int& tagFieldEnd, int curCursorPos) const
{
std::wstring fullText = m_FullTextBuffer.GetBuffer();
std::wstring targetTag;
std::wstring::size_type tagStart, tagEnd;
tagStart = tagEnd = std::wstring::npos;
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_START);
tagStart = fullText.rfind(targetTag, curCursorPos);
if (tagStart != std::wstring::npos)
{
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_END);
tagEnd = fullText.find(targetTag, tagStart);
if (int(tagStart) <= curCursorPos && curCursorPos < int(tagEnd))
{
tagFieldStart = int(tagStart);
tagFieldEnd = int(tagEnd);
}
}
}
bool CEtUIEditBox::RemoveChar(int startCaretPos, int length)
{
int tempS, tempE;
tempS = tempE = -1;
int fullTextStartCaretPos = GetFullTextCaretPos(startCaretPos, false);
GetFullTextTagFieldPos(tempS, tempE, fullTextStartCaretPos);
fullTextStartCaretPos = (tempS == -1) ? fullTextStartCaretPos : tempS;
tempS = tempE = -1;
int endCaretPos = startCaretPos + length;
int fullTextEndCaretPos = GetFullTextCaretPos(endCaretPos, false);
GetFullTextTagFieldPos(tempS, tempE, fullTextEndCaretPos);
fullTextEndCaretPos = (tempE == -1) ? fullTextEndCaretPos : tempE;
int processingCaretPos = fullTextStartCaretPos;
int i = 0;
for (; i < fullTextEndCaretPos - fullTextStartCaretPos;)
{
std::wstring fullText = m_FullTextBuffer.GetBuffer();
if (fullText.size() <= 0)
break;
std::wstring targetTag;
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_START);
if (processingCaretPos >= 0)
{
std::wstring::size_type tagStart = std::wstring::npos;
if (EtInterface::GetNameLinkMgr().IsTagType(fullText, processingCaretPos, CEtUINameLinkMgr::eNLTAG_START))
tagStart = (std::wstring::size_type)processingCaretPos;
if (tagStart == std::wstring::npos && processingCaretPos > 0)
tagStart = fullText.rfind(targetTag, processingCaretPos - 1);
if (tagStart != std::wstring::npos)
{
EtInterface::GetNameLinkMgr().MakeTag(targetTag, CEtUINameLinkMgr::eNLTAG_END);
std::wstring::size_type tagEnd = fullText.find(targetTag, tagStart);
int calculatedTagEnd = int(tagEnd) + 2;
if (int(tagStart) <= processingCaretPos && processingCaretPos <= int(tagEnd))
{
fullText.erase(tagStart, calculatedTagEnd - tagStart);
SetText(fullText.c_str(), false);
processingCaretPos = (int)tagStart;
i += calculatedTagEnd - int(tagStart);
continue;
}
}
}
int textCaretPos = GetTextCaretPos(processingCaretPos);
if( m_Buffer.RemoveChar(textCaretPos) == false ||
m_FullTextBuffer.RemoveChar(processingCaretPos) == false )
{
_ASSERT(0);
return false;
}
++i;
}
PlaceCaret(GetTextCaretPos(processingCaretPos));
m_nSelStart = m_nCaret;
return true;
}
bool CEtUIEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( !IsEnable() || !IsShow() || !IsKeyLock() )
{
return false;
}
switch( uMsg )
{
case WM_KEYUP:
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_RETURN:
m_pParent->ProcessCommand( EVENT_EDITBOX_STRING, true, this, (UINT)wParam );
return true;
}
break;
case WM_CHAR:
switch( ( WCHAR )wParam )
{
// Ctrl+<2B><EFBFBD><E9BDBA><EFBFBD>̽<EFBFBD><CCBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> <20>˾ƺ<CBBE><C6BA><EFBFBD> 0x7f<37>ε<EFBFBD> <20>ѱ۹<D1B1><DBB9><EFBFBD><EFBFBD><EFBFBD> <20>ƴϰ<C6B4> <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD>ڴ<EFBFBD>.
// DxCustomUI<55><49> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>Ŷ<EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD>Ƶα<C6B5><CEB1><EFBFBD> <20>Ѵ<EFBFBD>.
case 0x7f:
break;
// Ctrl+h<><68> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WM_CHAR<41><52> 0x08<30><38> <20><><EFBFBD>ԵǼ<D4B5> <20><><EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
// <20>ذ<EFBFBD><D8B0>ϱ<EFBFBD> <20><><EFBFBD>ؼ<EFBFBD>,
// VK_BACK<43><4B> WM_KEYDOWN<57><4E><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD>(<28>̶<EFBFBD> WM_CHAR-VK_BACK<43><4B><EFBFBD><EFBFBD> <20>ƹ<EFBFBD><C6B9>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> break)
// H<><48> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD> <20>˻<EFBFBD>.
// <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD>.
case VK_BACK:
if( GetKeyState('H')&0x80 )
break;
if( m_nCaret != m_nSelStart )
{
DeleteSelectionText();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
else if( m_nCaret > 0 )
{
PlaceCaret( m_nCaret - 1 );
m_nSelStart = m_nCaret;
RemoveChar(m_nCaret, 1);
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
ResetCaretBlink();
break;
case 24: // Ctrl-X Cut
case VK_CANCEL: // Ctrl-C Copy
CopyToClipboard();
if( ( WCHAR )wParam == 24 )
{
DeleteSelectionText();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
break;
case 22: // Ctrl-V Paste
PasteFromClipboard();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
break;
case 1: // Ctrl-A Select All
if( m_nSelStart == m_nCaret )
{
m_nSelStart = 0;
PlaceCaret( m_Buffer.GetTextSize() );
}
break;
case VK_RETURN:
// m_pParent->ProcessCommand( EVENT_EDITBOX_STRING, true, this, (UINT)wParam );
// break;
// Junk characters we don't want in the string
case 26: // Ctrl Z
case 2: // Ctrl B
case 14: // Ctrl N
case 19: // Ctrl S
case 4: // Ctrl D
case 6: // Ctrl F
case 7: // Ctrl G
case 10: // Ctrl J
case 11: // Ctrl K
case 12: // Ctrl L
case 17: // Ctrl Q
case 23: // Ctrl W
case 5: // Ctrl E
case 18: // Ctrl R
case 20: // Ctrl T
case 25: // Ctrl Y
case 21: // Ctrl U
case 9: // Ctrl I
case 15: // Ctrl O
case 16: // Ctrl P
case 27: // Ctrl [
case 29: // Ctrl ]
case 28: // Ctrl \
break;
default:
// <20>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD> <20><>ȯó<C8AF><C3B3>
ProcessHalfWidth( wParam );
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>
if( !CheckValidCharacter( (WCHAR)wParam ) )
break;
if( s_bCheckThaiLanguageVowelRule )
{
if( !CheckThaiLanguageVowelRule( (WCHAR)wParam ) )
break;
}
if( m_Property.UIType == UI_CONTROL_EDITBOX )
{
if( m_Property.EditBoxProperty.bOnlyDigit && !iswdigit( (WCHAR)wParam ) )
{
break;
}
}
bool bFiltering = false;
if (m_nFilterOption != 0)
{
if (m_nFilterOption & eDIGIT)
{
if (iswdigit((WCHAR)wParam))
bFiltering = true;
}
if (m_nFilterOption & eALPHABET)
{
if (iswalpha((WCHAR)wParam))
bFiltering = true;
}
if (bFiltering == false)
break;
}
if( m_nCaret != m_nSelStart )
{
DeleteSelectionText();
}
if( ( !m_bInsertMode ) && ( m_nCaret < m_Buffer.GetTextSize() ) )
{
if (OverTypeChar((WCHAR)wParam))
{
PlaceCaret(m_nCaret + 1);
m_nSelStart = m_nCaret;
}
}
else
{
if (InsertChar((WCHAR)wParam))
{
PlaceCaret( m_nCaret + 1 );
//UpdateLastVisible();
m_nSelStart = m_nCaret;
}
}
ResetCaretBlink();
m_pParent->ProcessCommand( EVENT_EDITBOX_CHANGE, true, this, (UINT)wParam );
}
return true;
}
return false;
}
void CEtUIEditBox::ProcessHalfWidth(WPARAM &wParam)
{
const int nOffset = 0xFEE0;
if( (WCHAR)wParam >= 0x0041+nOffset && (WCHAR)wParam <= 0x005A+nOffset ) // L'A' ~ L'Z'
wParam -= nOffset;
else if( (WCHAR)wParam >= 0x0061+nOffset && (WCHAR)wParam <= 0x007A+nOffset ) // L'a' ~ L'z'
wParam -= nOffset;
else if( (WCHAR)wParam >= 0x0030+nOffset && (WCHAR)wParam <= 0x0039+nOffset ) // L'0' ~ L'9'
wParam -= nOffset;
}
bool CEtUIEditBox::CheckValidCharacter( WCHAR wChar )
{
for( DWORD dwIndex = 0; dwIndex < (DWORD)s_vecInvalidCharater.size(); ++dwIndex )
{
if( s_vecInvalidCharater[dwIndex] == wChar )
return false;
}
return true;
}
void CEtUIEditBox::AddInvalidCharacter( wchar_t wCharStart, wchar_t wCharEnd )
{
if( static_cast<DWORD>(wCharStart) > static_cast<DWORD>(wCharEnd) )
return;
for( DWORD dwIndex = static_cast<DWORD>(wCharStart); dwIndex <= static_cast<DWORD>(wCharEnd); ++dwIndex )
s_vecInvalidCharater.push_back( (WCHAR)dwIndex );
}
void CEtUIEditBox::UpdateRects()
{
m_TextCoord = m_Property.UICoord;
m_TextCoord.fX += m_Property.EditBoxProperty.fBorder;
m_TextCoord.fWidth -= m_Property.EditBoxProperty.fBorder * 2;
m_TextCoord.fY += m_Property.EditBoxProperty.fBorder;
m_TextCoord.fHeight -= m_Property.EditBoxProperty.fBorder * 2;
m_RenderCoord[ 0 ] = m_TextCoord;
m_RenderCoord[ 1 ].SetCoord( m_Property.UICoord.fX, m_Property.UICoord.fY, m_TextCoord.fX - m_Property.UICoord.fX, m_Property.UICoord.fHeight );
m_RenderCoord[ 2 ].SetCoord( m_TextCoord.Right(), m_Property.UICoord.fY, m_Property.UICoord.Right() - m_TextCoord.Right(), m_Property.UICoord.fHeight );
m_RenderCoord[ 3 ].SetCoord( m_TextCoord.fX, m_Property.UICoord.fY, m_TextCoord.fWidth, m_TextCoord.fY - m_Property.UICoord.fY );
m_RenderCoord[ 4 ].SetCoord( m_TextCoord.fX, m_TextCoord.Bottom(), m_TextCoord.fWidth, m_Property.UICoord.Bottom() - m_TextCoord.Bottom() );
m_TextCoord.fX += m_Property.EditBoxProperty.fSpace;
m_TextCoord.fWidth -= m_Property.EditBoxProperty.fSpace * 2;
m_TextCoord.fY += m_Property.EditBoxProperty.fSpace;
m_TextCoord.fHeight -= m_Property.EditBoxProperty.fSpace * 2;
}
void CEtUIEditBox::RenderText(float fElapsedTime, SUIElement* pElement, const SUICoord& TempCoord, bool bNeedDivide)
{
// EditBox <20>۾<EFBFBD><DBBE><EFBFBD><EFBFBD><EFBFBD> wordbreak<61><6B> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
bool bFontMngWordBreak = CEtFontMng::s_bUseWordBreak;
CEtFontMng::s_bUseWordBreak = false;
//pElement = GetElement(0);
if (pElement)
{
pElement->TextureColor.Blend( m_CurrentState, fElapsedTime, m_fBlendRate );
pElement->FontColor.Blend( m_CurrentState, fElapsedTime, m_fBlendRate );
pElement->ShadowFontColor.Blend( m_CurrentState, fElapsedTime, m_fBlendRate );
if (false == bNeedDivide)
{
SUICoord drawCoord = TempCoord;
DrawTextWithTraslation(m_FullTextBuffer.GetBuffer(), pElement, drawCoord);
}
else
{
wstring strBuf = m_RenderBuffer.GetBuffer() + m_nFirstVisible;
wstring strFormer = strBuf.substr( 0, (m_nCaret-m_nFirstVisible) );
wstring strLatter = strBuf.substr( max(0, min((int)strBuf.length(), m_nCaret-m_nFirstVisible)), strBuf.length()-(m_nCaret-m_nFirstVisible) );
SUICoord FormerCoord = TempCoord;
SUICoord LatterCoord = TempCoord;
SUICoord WidthCoord; // <20>ʺ<EFBFBD><CABA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӽ÷<D3BD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>
m_pParent->DrawDlgText( strFormer.c_str(), pElement,
m_Property.EditBoxProperty.dwTextColor, FormerCoord, -1, pElement->dwFontFormat, true );
m_pParent->CalcTextRect( strFormer.c_str(), pElement, WidthCoord );
LatterCoord.fX += (WidthCoord.fWidth + m_fCompositionWidth);
m_pParent->DrawDlgText( strLatter.c_str(), pElement,
m_Property.EditBoxProperty.dwTextColor, LatterCoord, -1, pElement->dwFontFormat, true );
}
}
CEtFontMng::s_bUseWordBreak = bFontMngWordBreak;
}
void CEtUIEditBox::Render( float fElapsedTime )
{
if( !IsShow() )
return;
//HRESULT hr;
int nSelStartX(0), nCaretX(0);
SUIElement *pElement = NULL;
// Note : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ䰡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <09><><EFBFBD>߿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǹ<EFBFBD> <20>ּ<EFBFBD><D6BC><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
//pElement = &m_Template.m_vecElement[ 0 ];
//if( pElement )
//{
// m_Buffer.SetFont( m_pParent->GetFont( pElement->nFontIndex ) );
// PlaceCaret( m_nCaret );
//}
UpdateBlendRate();
int nVecSize = (int)m_Template.m_vecElement.size();
for( int i = 0; i < nVecSize; i++ )
{
pElement = GetElement(i);
if( !m_bFocus )
{
if (IsEnable() == false)
pElement->TextureColor.Blend( UI_STATE_DISABLED, fElapsedTime, 0.5f );
else
pElement->TextureColor.Blend( UI_STATE_NORMAL, fElapsedTime, m_fBlendRate );
}
else
{
pElement->TextureColor.Blend( UI_STATE_FOCUS, fElapsedTime, m_fBlendRate );
}
if( m_bExistTemplateTexture )
m_pParent->DrawSprite( m_Template.m_hTemplateTexture, pElement->TemplateUVCoord, pElement->TextureColor.dwCurrentColor, m_RenderCoord[ i ] );
else
m_pParent->DrawSprite( pElement->UVCoord, pElement->TextureColor.dwCurrentColor, m_RenderCoord[ i ] );
}
UpdateLastVisible();
wstring strBuf = m_Buffer.GetBuffer();
if( m_Property.EditBoxProperty.bPassword )
strBuf.replace(0, int(strBuf.size()), int(strBuf.size()), '*');
m_RenderBuffer.SetText( strBuf.substr( 0, m_nLastVisible ).c_str() );
const WCHAR* pTextToRender = m_RenderBuffer.GetBuffer();
int nXFirst = 0;
CEtFontMng& FontMng = CEtFontMng::GetInstance();
pElement = GetElement(0);
if( pElement )
{
nXFirst = FontMng.GetCaretPos( pTextToRender, pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible);
//m_RenderBuffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst );
#ifdef _TEST_CODE_KAL
nCaretX = FontMng.GetCaretPos( strBuf.c_str(), pElement->nFontIndex, pElement->nFontHeight, m_nCaret );
#else
nCaretX = FontMng.GetCaretPos( pTextToRender, pElement->nFontIndex, pElement->nFontHeight, m_nCaret );
#endif
//hr = m_RenderBuffer.CPtoX( m_nCaret, FALSE, &nCaretX );
if( m_nCaret != m_nSelStart )
{
//hr = m_RenderBuffer.CPtoX( m_nSelStart, FALSE, &nSelStartX );
// Note: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20>ٷ<EFBFBD><D9B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>
//m_nSelStart = m_nSelStart - m_nFirstVisible;
//if( m_nSelStart < 0 )
// m_nSelStart = 0;
#ifdef _TEST_CODE_KAL
nSelStartX = FontMng.GetCaretPos(strBuf.c_str(), pElement->nFontIndex, pElement->nFontHeight, m_nSelStart);
#else
nSelStartX = FontMng.GetCaretPos(m_RenderBuffer.GetBuffer()/*+m_nFirstVisible*/, pElement->nFontIndex, pElement->nFontHeight, m_nSelStart);
#endif
}
else
{
nSelStartX = nCaretX;
}
}
SUICoord SelectionCoord;
if( m_nCaret != m_nSelStart )
{
int nSelLeftX, nSelRightX;
nSelLeftX = nCaretX;
nSelRightX = nSelStartX;
if( nSelLeftX > nSelRightX )
{
std::swap( nSelLeftX, nSelRightX );
}
float fMinRight, fMinBottom;
int nTextWidth = ( int )( m_TextCoord.fWidth * m_pParent->GetScreenWidth() );
int nSelRightXTemp = nSelRightX, nSelLeftXTemp = nSelLeftX;
if( nSelRightX >= nXFirst )
nSelRightXTemp = nSelRightX - nXFirst;
if( nSelLeftX >= nXFirst )
nSelLeftXTemp = nSelLeftX - nXFirst;
int nSelWidth = nSelRightXTemp - nSelLeftXTemp;
//if( nSelWidth > nTextWidth )
// nSelWidth -= nXFirst;
//nSelWidth = nSelWidth % nTextWidth;
SelectionCoord.SetCoord( ( ( float )nSelLeftX ) / m_pParent->GetScreenWidth(), m_TextCoord.fY,
( ( float )( nSelWidth ) ) / m_pParent->GetScreenWidth(), m_TextCoord.fHeight );
SelectionCoord.fX += m_TextCoord.fX - ( ( float )nXFirst ) / m_pParent->GetScreenWidth();
fMinRight = min( m_TextCoord.Right(), SelectionCoord.Right() );
fMinBottom = min( m_TextCoord.Bottom(), SelectionCoord.Bottom() );
SelectionCoord.fWidth = fMinRight - SelectionCoord.fX;
SelectionCoord.fHeight = fMinBottom - SelectionCoord.fY;
SelectionCoord.fX = max( m_TextCoord.fX, SelectionCoord.fX );
SelectionCoord.fY = max( m_TextCoord.fY, SelectionCoord.fY );
SelectionCoord.fWidth = min( m_TextCoord.fWidth, SelectionCoord.fWidth );
bool bEnableZ = GetEtDevice()->EnableZ( false );
m_pParent->DrawRect( SelectionCoord, m_Property.EditBoxProperty.dwSelBackColor );
GetEtDevice()->EnableZ( bEnableZ );
}
// <20><><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD> <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20>ִٸ<D6B4> <20>ʺ<EFBFBD> <20><>ŭ <20>ڷ<EFBFBD> <20>о<EFBFBD><D0BE>ش<EFBFBD>.
// <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
SUICoord TempCoord = m_TextCoord;
bool bNeedDivide = false;
if( 0.0f != m_fCompositionWidth )
{
if( m_nCaret < m_nLastVisible )
{
if( 0 == m_nCaret )
TempCoord.fX += m_fCompositionWidth;
else
bNeedDivide = true;
}
}
RenderText(fElapsedTime, pElement, TempCoord, bNeedDivide);
//if( wcslen(m_RenderBuffer.GetBuffer() + m_nFirstVisible) > 0 )
//{
// OutputDebugStringW( L"[Edit Box]" );
// OutputDebugStringW( m_RenderBuffer.GetBuffer() + m_nFirstVisible );
// OutputDebugStringW( L"\n" );
//}
//if( m_nCaret != m_nSelStart )
//{
// int nFirstToRender, nNumChatToRender;
// nFirstToRender = max( m_nFirstVisible, min( m_nSelStart, m_nCaret ) );
// nNumChatToRender = max( m_nSelStart, m_nCaret ) - nFirstToRender;
// m_pParent->DrawDlgText( m_RenderBuffer.GetBuffer() + nFirstToRender, pElement,
// m_Property.EditBoxProperty.dwSelTextColor, SelectionCoord, -1, pElement->dwFontFormat, true );
//}
//CEtFontMng::GetInstance().EnableFreeType( true );
LARGE_INTEGER liCurTime, liFrequency;
float fElapsedBlinkTime;
QueryPerformanceCounter( &liCurTime );
QueryPerformanceFrequency( &liFrequency );
fElapsedBlinkTime = ( ( float )( liCurTime.QuadPart - m_liLastBlinkTime.QuadPart ) ) / liFrequency.QuadPart;
if( fElapsedBlinkTime >= m_fCaretBlinkTime )
{
m_bCaretOn = !m_bCaretOn;
m_liLastBlinkTime = liCurTime;
}
SUICoord CaretCoord;
CaretCoord = TempCoord;
CaretCoord.fX += ( ( float )( -nXFirst + nCaretX - 1 ) ) / m_pParent->GetScreenWidth();
CaretCoord.fWidth = 2.0f / m_pParent->GetScreenWidth();
if (IsFocus())
{
s_CurrentCaretPos = CaretCoord;
// <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD>̾<EFBFBD><CCBE>α<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٰ<EFBFBD> ó<><C3B3><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>, <20>θ<EFBFBD><CEB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20≯<EFBFBD> <20><><EFBFBD>صд<D8B5>.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD> <20>Ʒ<EFBFBD> ( !CEtUIIME::s_bHideCaret ) <20><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD> false<73><65> <20>Ǽ<EFBFBD> s_CurrentCaretPos <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>,
// <20>̷<EFBFBD><CCB7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>׻<EFBFBD> ó<><C3B3><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD> <20>ߴ<EFBFBD>.
if( m_pParent )
{
s_CurrentCaretPos.fX += m_pParent->GetXCoord();
s_CurrentCaretPos.fY += m_pParent->GetYCoord();
}
}
if( ( m_bFocus ) && ( m_bCaretOn ) && ( !CEtUIIME::s_bHideCaret ) )
{
if( !m_bInsertMode )
{
int nRightEdgeX = 0;
//m_RenderBuffer.CPtoX( m_nCaret, TRUE, &nRightEdgeX );
nRightEdgeX = FontMng.GetCaretPos( pTextToRender, pElement->nFontIndex, pElement->nFontHeight, m_nCaret );
CaretCoord.fWidth = m_TextCoord.fX + ( ( float )( nRightEdgeX - nXFirst ) ) / m_pParent->GetScreenWidth() - CaretCoord.fX;
}
bool bEnableZ = GetEtDevice()->EnableZ( false );
m_pParent->DrawRect( CaretCoord, m_Property.EditBoxProperty.dwCaretColor );
GetEtDevice()->EnableZ( bEnableZ );
}
}
void CEtUIEditBox::PlaceCaret( int nCP )
{
ASSERT( ( nCP >= 0 ) && ( nCP <= m_Buffer.GetTextSize() ) );
int nX1st, nX, nX2;
m_nCaret = nCP;
m_FullTextCaret = GetFullTextCaretPos(m_nCaret, true);
CEtFontMng& FontMng = CEtFontMng::GetInstance();
const WCHAR* pText = m_Buffer.GetBuffer();
SUIElement* pElement = GetElement( 0 );
if( !pElement ) {
return;
}
nX1st = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, m_nFirstVisible );
//m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st );
nX = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nCP );
//m_Buffer.CPtoX( nCP, FALSE, &nX ); // LEAD
if( nCP == m_Buffer.GetTextSize() )
{
nX2 = nX;
}
else
{
//m_Buffer.CPtoX( nCP, TRUE, &nX2 );
nX2 = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nCP );
}
if( nX < nX1st )
{
// Note : <20><><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>տ<EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾұ<CABE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// m_nFirstVisible<6C><65> <20><><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD>.
if( nCP >= 2 )
nCP -= GetTextMoveCount( 2, false );
m_nFirstVisible = nCP;
//UpdateLastVisible();
}
else
{
int nTextWidth;
nTextWidth = ( int )( m_TextCoord.fWidth * m_pParent->GetScreenWidth() );
if( nX2 > nX1st + nTextWidth )
{
int nXNewLeft = 0, nCPNew1st = 0, nNewTrail = 0, nXNew1st = 0;
nXNewLeft = nX2 - nTextWidth;
//m_Buffer.XtoCP( nXNewLeft, &nCPNew1st, &nNewTrail );
nCPNew1st = FontMng.GetCaretFromCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nXNewLeft, nNewTrail );
nXNew1st = FontMng.GetCaretPos( pText, pElement->nFontIndex, pElement->nFontHeight, nCPNew1st );
//m_Buffer.CPtoX( nCPNew1st, FALSE, &nXNew1st );
if( nXNew1st < nXNewLeft )
{
// Note : <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>Է<EFBFBD> <20><><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// <09>Ʒ<EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD> <20>ִ<EFBFBD> <20>Է<EFBFBD> <20><><EFBFBD>̰<EFBFBD> 3<>̻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <09><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><33><C4AD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
if( s_bCheckThaiLanguageVowelRule )
{
int nTemp = m_Buffer.GetMaxEditBoxLength() - GetThaiLength( m_Buffer.GetBuffer() );
if( nTemp < 3 )
nCPNew1st += GetTextMoveCount( 1, true );
else
nCPNew1st += GetTextMoveCount( 3, true );
}
else
{
int nTemp = m_Buffer.GetMaxEditBoxLength() - m_Buffer.GetTextSize();
if( nTemp < 3 )
++nCPNew1st;
else
nCPNew1st += 3;
}
}
m_nFirstVisible = nCPNew1st;
}
}
}
void CEtUIEditBox::DeleteSelectionText()
{
int nFirst, nLast;
nFirst = min( m_nCaret, m_nSelStart );
nLast = max( m_nCaret, m_nSelStart );
RemoveChar( nFirst, nLast - nFirst );
}
void CEtUIEditBox::ResetCaretBlink()
{
m_bCaretOn = true;
QueryPerformanceCounter( &m_liLastBlinkTime );
}
void CEtUIEditBox::CopyToClipboard()
{
if( ( m_nCaret != m_nSelStart ) && ( OpenClipboard( NULL ) ) )
{
HGLOBAL hBlock;
EmptyClipboard();
hBlock = GlobalAlloc( GMEM_MOVEABLE, sizeof( WCHAR ) * ( m_Buffer.GetTextSize() + 1 ) );
if( hBlock )
{
WCHAR *pwszText;
int nFirst, nLast;
pwszText = ( WCHAR * )GlobalLock( hBlock );
if( pwszText )
{
nFirst = min( m_nCaret, m_nSelStart );
nLast = max( m_nCaret, m_nSelStart );
if( nLast - nFirst > 0 )
{
memcpy( pwszText, m_Buffer.GetBuffer() + nFirst, ( nLast - nFirst ) * sizeof( WCHAR ) );
}
pwszText[ nLast - nFirst ] = L'\0';
GlobalUnlock( hBlock );
}
SetClipboardData( CF_UNICODETEXT, hBlock );
}
CloseClipboard();
if( hBlock )
{
GlobalFree( hBlock );
}
}
}
void CEtUIEditBox::PasteFromClipboard()
{
DeleteSelectionText();
if( OpenClipboard( NULL ) )
{
HANDLE handle;
handle = GetClipboardData( CF_UNICODETEXT );
if( handle )
{
WCHAR *pwszText;
pwszText = ( WCHAR * )GlobalLock( handle );
if( pwszText )
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><>ü.
int nLen = (int)wcslen( pwszText );
for( int i = 0; i < nLen; ++i )
{
if( pwszText[i] == '\n' )
pwszText[i] = ' ';
// <20>ٿ<EFBFBD><D9BF>ֱ⿡<D6B1><E2BFA1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EBB0A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>
if( !CheckValidCharacter( pwszText[i] ) )
pwszText[i] = ' ';
}
// <20><><EFBFBD>ڸ<EFBFBD> <20>޾ƾ<DEBE><C6BE>ϴ<EFBFBD> <20><>Ȳ<EFBFBD>ε<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴѰ<C6B4> <20>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF>ֱ⸦ <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
if( m_Property.EditBoxProperty.bOnlyDigit == TRUE )
{
int nLenInner = (int)wcslen( pwszText );
for( int i = 0; i < nLenInner; ++i )
{
if( !iswdigit( pwszText[i] ) )
{
CloseClipboard();
return;
}
}
}
AddText(pwszText, true);
GlobalUnlock( handle );
}
}
CloseClipboard();
}
}
void CEtUIEditBox::SetMaxEditLength( DWORD dwMaxLength )
{
ASSERT( dwMaxLength > 0 );
m_RenderBuffer.SetMaxEditBoxLength( dwMaxLength );
m_Buffer.SetMaxEditBoxLength( dwMaxLength-1 );
}
void CEtUIEditBox::UpdateLastVisible( void )
{
CEtFontMng& FontMng = CEtFontMng::GetInstance();
const WCHAR* pText = m_Buffer.GetBuffer();
SUIElement* pElement = GetElement( 0 );
int nTrail = 0;
int nTextWidth = ( int )( m_TextCoord.fWidth * m_pParent->GetScreenWidth() );
if( CEtFontMng::s_bUseUniscribe )
{
// EditBox <20>۾<EFBFBD><DBBE><EFBFBD><EFBFBD><EFBFBD> wordbreak<61><6B> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
bool bFontMngWordBreak = CEtFontMng::s_bUseWordBreak;
CEtFontMng::s_bUseWordBreak = false;
std::vector<std::wstring> vecTextLine;
std::wstring strText( pText + m_nFirstVisible );
int nMaxWidth;
bool bRtnWordBreakText = CEtFontMng::GetInstance().GetWordBreakText( strText, pElement->nFontIndex, pElement->nFontHeight, static_cast<float>( nTextWidth ), vecTextLine, nMaxWidth );
CEtFontMng::s_bUseWordBreak = bFontMngWordBreak;
if( !bRtnWordBreakText )
return;
if( static_cast<int>( vecTextLine.size() ) > 0 )
{
m_nLastVisible = static_cast<int>( vecTextLine[0].length() ) + m_nFirstVisible;
}
}
else
{
m_nLastVisible = FontMng.GetCaretFromCaretPos( pText+m_nFirstVisible, pElement->nFontIndex, pElement->nFontHeight, nTextWidth, nTrail )+m_nFirstVisible+1; // ī<><C4AB>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>־<EFBFBD><D6BE><EFBFBD> <20>ϹǷ<CFB9> +1
}
}
void CEtUIEditBox::SetSelection(int startPos, int caretPos)
{
if (caretPos < 0 || caretPos > GetTextLength() ||
startPos < 0 || startPos > GetTextLength())
return;
m_nSelStart = startPos;
m_nCaret = caretPos;
}
int CEtUIEditBox::GetMaxChar() const
{
return m_Property.EditBoxProperty.dwMaxChars;
}
void CEtUIEditBox::SetMaxChar( DWORD dwChar )
{
m_Property.EditBoxProperty.dwMaxChars = dwChar;
SetMaxEditLength( dwChar );
}
void CEtUIEditBox::SetTextWithEllipsis(const wchar_t* text, const wchar_t* wszSymbol, bool bSelected)
{
std::wstring result;
std::wstring tempStr = text;
std::wstring ellipsis = wszSymbol;
DWORD maxChar = GetMaxChar();
if (wcslen(text) >= maxChar)
{
result = tempStr.substr(0, maxChar - ellipsis.size() - 2);
result += ellipsis;
}
else
{
result = tempStr;
}
m_pParent->MakeStringWithEllipsis(GetElement(0), m_TextCoord.fWidth, result, wszSymbol);
SetText(result.c_str(), bSelected);
}
bool CEtUIEditBox::DrawTextPiece(const std::wstring& piece, int pieceStart, int pieceEnd, SUIElement* pElement, SUICoord& drawCoord)
{
if (piece.empty())
return true;
if (m_nFirstVisible > pieceEnd || m_nLastVisible < pieceStart)
return true;
// viewporting(?)
bool res = true;
SUICoord widthCoord;
std::wstring drawText(piece);
int pieceSize = (int)piece.size() - abs(m_nFirstVisible - pieceStart);
if (pieceStart >= m_nFirstVisible)
{
if (pieceEnd > m_nLastVisible)
{
drawText = piece.substr(0, m_nLastVisible - pieceStart);
res = false;
}
}
else
{
if (pieceEnd > m_nLastVisible)
{
drawText = piece.substr(m_nFirstVisible - pieceStart, m_nLastVisible - m_nFirstVisible);
res = false;
}
else
{
drawText = piece.substr(m_nFirstVisible - pieceStart, std::wstring::npos);
}
}
if( m_Property.EditBoxProperty.bPassword )
drawText.replace(0, int(drawText.size()), int(drawText.size()), '*');
m_pParent->DrawDlgText(drawText.c_str(), pElement, m_RenderTextColor, drawCoord, -1, pElement->dwFontFormat, true, 0.f);
m_pParent->CalcTextRect(drawText.c_str(), pElement, widthCoord);
drawCoord.fX += widthCoord.fWidth;
return res;
}
int CEtUIEditBox::GetFullTextCaretPos(int caretPos, bool bRetWithCalcTagLast) const
{
if (caretPos == 0)
return 0;
std::wstring text = m_FullTextBuffer.GetBuffer();
std::wstring::size_type linkStartPos = 0;
int caretPosFound = 0;
int fullTextCaretPos = 0;
int processTextCaretPos = 0;
bool bInsideTag = false;
WORD sep = EtInterface::GetNameLinkMgr().GetNameLinkSeperator();
while(fullTextCaretPos < int(text.size()))
{
if (caretPos == caretPosFound)
{
if (bRetWithCalcTagLast)
{
if (bInsideTag)
{
std::wstring parsee = text.substr(fullTextCaretPos, std::wstring::npos);
std::wstring targetTag;
targetTag = FormatW(L"%ce", sep);
std::wstring::size_type loc = parsee.find(targetTag.c_str());
fullTextCaretPos += (loc != std::wstring::npos) ? int(loc + 2) : int(parsee.length());
}
}
else
{
CEtUINameLinkMgr::eNameLinkTagType type = EtInterface::GetNameLinkMgr().IsTagType(text, fullTextCaretPos);
if (type != CEtUINameLinkMgr::eNLTAG_NONE)
{
std::wstring parsee = text.substr(fullTextCaretPos, std::wstring::npos);
std::wstring targetTag;
targetTag = FormatW(L"%ce", sep);
std::wstring::size_type loc = parsee.find(targetTag.c_str());
fullTextCaretPos += (loc != std::wstring::npos) ? int(loc + 2) : int(parsee.length());
}
}
break;
}
CEtUINameLinkMgr::eNameLinkTagType type = EtInterface::GetNameLinkMgr().IsTagType(text, fullTextCaretPos);
if (type != CEtUINameLinkMgr::eNLTAG_NONE)
{
if (type == CEtUINameLinkMgr::eNLTAG_START)
bInsideTag = true;
else if (type == CEtUINameLinkMgr::eNLTAG_END)
bInsideTag = false;
// todo by kalliste : parsee <20><> <20>±<EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><><EFBFBD>̰<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3>. <20><> <20>ʿ䰡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>±<EFBFBD> Ÿ<>Կ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ѱ<EFBFBD><D1B1><EFBFBD> <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD>.
int offset = 0;
std::wstring parsee = text.substr(++fullTextCaretPos, std::wstring::npos);
EtInterface::GetNameLinkMgr().GetTagOffsetByParseText(parsee, offset);
fullTextCaretPos += offset;
}
else
{
++caretPosFound;
++fullTextCaretPos;
}
}
return fullTextCaretPos;
}
int CEtUIEditBox::GetTextCaretPos(int fullTextCaretPos)
{
if (fullTextCaretPos <= 0)
return 0;
std::wstring text = m_FullTextBuffer.GetBuffer();
std::wstring::size_type linkStartPos = 0;
int caretPosFound = 0;
int curFullCaretPos = 0;
bool bInsideTag = false;
while(curFullCaretPos < int(text.size()) && (curFullCaretPos < fullTextCaretPos))
{
CEtUINameLinkMgr::eNameLinkTagType type = EtInterface::GetNameLinkMgr().IsTagType(text, curFullCaretPos);
if (type != CEtUINameLinkMgr::eNLTAG_NONE)
{
int offset = 0;
std::wstring parsee = text.substr(curFullCaretPos + 1, std::wstring::npos);
EtInterface::GetNameLinkMgr().GetTagOffsetByParseText(parsee, offset);
curFullCaretPos += (offset + 1);
}
else
{
++caretPosFound;
++curFullCaretPos;
}
}
return caretPosFound;
}
// todo : refactoring using command pattern. by kalliste
int CEtUIEditBox::DrawTextWithTraslation(const WCHAR* originalStr, SUIElement* pElement, SUICoord& drawCoord)
{
if (pElement == NULL || (drawCoord.fHeight == 0.f && drawCoord.fWidth == 0.f))
return 0;
std::wstring rest;
const std::wstring& trs_org = originalStr;
std::wstring::size_type linkStartPos = 0;
int posWithoutTag, lengthWithoutTag, fullTextCaretIdx, i;
posWithoutTag =
lengthWithoutTag =
i =
fullTextCaretIdx = 0;
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
WCHAR sep = EtInterface::GetNameLinkMgr().GetNameLinkSeperator();
rest = originalStr;
while(rest.size() > 0 || linkStartPos != std::wstring::npos)
{
linkStartPos = rest.find_first_of(sep, linkStartPos);
if (linkStartPos == std::wstring::npos)
{
lengthWithoutTag = posWithoutTag + int(rest.length());
DrawTextPiece(rest, posWithoutTag, lengthWithoutTag, pElement, drawCoord);
break;
}
else
{
std::wstring drawText = rest.substr(0, linkStartPos);
if (DrawTextPiece(drawText, posWithoutTag, posWithoutTag + (int)linkStartPos, pElement, drawCoord) == false)
break;
rest = rest.substr(linkStartPos + 1, std::wstring::npos);
posWithoutTag += int(drawText.length());
lengthWithoutTag += int(drawText.length());
int tagOffset = 1;
if (EtInterface::GetNameLinkMgr().ParseText(rest, tagOffset, this) == false)
{
lengthWithoutTag = posWithoutTag + int(rest.length());
DrawTextPiece(rest, posWithoutTag, posWithoutTag + int(rest.length()), pElement, drawCoord);
break;
}
linkStartPos = 0;
}
}
return lengthWithoutTag;
}
bool CEtUIEditBox::OnParseTextColor(DWORD color)
{
m_RenderTextColor = (color != 0) ? color : m_Property.EditBoxProperty.dwTextColor;
return true;
}
bool CEtUIEditBox::OnParseTextFailColor()
{
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
return true;
}
bool CEtUIEditBox::OnParseTextRestoreColor()
{
m_RenderTextColor = m_Property.EditBoxProperty.dwTextColor;
return true;
}
void CEtUIEditBox::SetFilterOption(int option)
{
m_nFilterOption |= option;
}
static const WCHAR s_wThaiVowels[26] =
{
// Allow to use double vowels
0xE40, 0xE41, 0xE42, 0xE43, 0xE44, 0xE45, 0xE46,
// Behind vowels
0xE30, 0xE32,
// Below vowels
0xE38, 0xE39, 0xE3A,
// Above vowels in 1st class
0xE31, 0xE33, 0xE34, 0xE35, 0xE36, 0xE37,
// Above vowels in 2nd class
0xE47, 0xE48, 0xE49, 0xE4A, 0xE4B, 0xE4C, 0xE4D, 0xE4E
};
#define ISTHAIBASECONSONANT( ch ) ( (unsigned int)(ch) - 0xE01 ) <= ( 0xE2E - 0xE01 ) // <20>±<EFBFBD><C2B1><EFBFBD> <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
static const WCHAR s_wThaiStart = 0xE01;
static const int s_nThaiAllowDoubleVowelLastIndex = 6;
static const int s_nBehindVowelStartIndex = 7;
static const int s_nBelowVowelStartIndex = 9;
static const int s_nAboveVowelStartIndex = 12;
static const int s_nAboveVowelsIn1stClassStartIndex = 12;
static const int s_nAboveVowelsIn2ndClassStartIndex = 18;
int CEtUIEditBox::CheckThaiLanguageVowel( WCHAR wChar )
{
int nVowelIndex = -1;
for( int i=0; i<26; i++ )
{
if( s_wThaiVowels[i] == wChar )
{
nVowelIndex = i;
break;
}
}
return nVowelIndex;
}
int CEtUIEditBox::GetThaiLength( const WCHAR* pWChar )
{
if( pWChar == NULL ) return 0;
int nBufferThaiLength = 0;
int nBufferSize = lstrlenW( pWChar );
for( int i=0; i<nBufferSize; i++ )
{
int nTextIndex = CheckThaiLanguageVowel( pWChar[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
nBufferThaiLength++;
}
return nBufferThaiLength;
}
WCHAR CEtUIEditBox::GetThaiStartChar()
{
return s_wThaiStart;
}
int CEtUIEditBox::GetThaiBelowVowelStartIndex()
{
return s_nBelowVowelStartIndex;
}
bool CEtUIEditBox::CheckThaiLanguageVowelRule( WCHAR wChar )
{
int nVowelIndex = CheckThaiLanguageVowel( wChar );
bool bCheckAvailableChar = true;
if( nVowelIndex >= 0 ) // <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>츸 Ȯ<><C8AE>
{
int nTextSize = m_Buffer.GetTextSize();
WCHAR wLastChar = m_Buffer[m_nCaret-1];
if( m_nCaret > 0 && m_nCaret <= nTextSize && wLastChar >= s_wThaiStart ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
int nLastTextIndex = CheckThaiLanguageVowel( wLastChar );
if( nVowelIndex > s_nThaiAllowDoubleVowelLastIndex && nLastTextIndex == nVowelIndex ) // <20><><EFBFBD>߸<EFBFBD><DFB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ȵǴ<C8B5> <20>͵<EFBFBD> Ȯ<><C8AE>
{
bCheckAvailableChar = false;
}
else if( nLastTextIndex == -1 && !( ISTHAIBASECONSONANT( wLastChar ) ) ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴ<EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20>н<EFBFBD>
{
bCheckAvailableChar = false;
}
else if( nLastTextIndex >= 0 && nVowelIndex >= s_nBehindVowelStartIndex ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̰<EFBFBD> <20>Է<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><>,<2C>Ʒ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
if( nLastTextIndex < s_nBelowVowelStartIndex ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20>ܵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
bCheckAvailableChar = false;
}
else if( ( nLastTextIndex >= s_nAboveVowelStartIndex ) && ( nVowelIndex >= s_nBelowVowelStartIndex && nVowelIndex < s_nAboveVowelStartIndex ) ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD> <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
bCheckAvailableChar = false;
}
else if( ( nLastTextIndex >= s_nBelowVowelStartIndex && nLastTextIndex < s_nAboveVowelStartIndex ) && ( nVowelIndex >= s_nBelowVowelStartIndex && nVowelIndex < s_nAboveVowelStartIndex ) )
{
bCheckAvailableChar = false; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20>Ʒ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD> <20>Է<EFBFBD><D4B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
}
else
{
std::vector<WCHAR> vecVowelChar;
for( int i=m_nCaret-1; i>=0; i-- )
{
int nTextIndex = CheckThaiLanguageVowel( m_FullTextBuffer[i] );
if( nTextIndex >= 0 )
vecVowelChar.push_back( nTextIndex );
else
break;
}
int nAboveVowelsCount = 0;
int nAboveVowelsIn1stClassCount = 0;
int nAboveVowelsIn2ndClassCount = 0;
for( int i=0; i<static_cast<int>( vecVowelChar.size() ); i++ )
{
if( vecVowelChar[i] == nVowelIndex )
{
bCheckAvailableChar = false;
break;
}
if( vecVowelChar[i] >= s_nAboveVowelStartIndex )
nAboveVowelsCount++;
if( vecVowelChar[i] >= s_nAboveVowelsIn1stClassStartIndex && vecVowelChar[i] < s_nAboveVowelsIn2ndClassStartIndex )
nAboveVowelsIn1stClassCount++;
if( vecVowelChar[i] >= s_nAboveVowelsIn2ndClassStartIndex )
nAboveVowelsIn2ndClassCount++;
if( vecVowelChar[i] == 13 ) // behind vowel<65><6C> 0xE33<33><33> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
bCheckAvailableChar = false;
}
if( nAboveVowelsCount >= 2 ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
bCheckAvailableChar = false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> 2<><32><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>. 0xE33<33><33> 2<><32> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־ <20><><EFBFBD><20><> <20>ִ<EFBFBD>.
if( ( nVowelIndex >= s_nAboveVowelsIn1stClassStartIndex && nVowelIndex < s_nAboveVowelsIn2ndClassStartIndex ) &&
( nAboveVowelsIn1stClassCount > 0 || ( nVowelIndex != 13 && nAboveVowelsIn2ndClassCount > 0 ) ) )
bCheckAvailableChar = false;
if( nVowelIndex >= s_nAboveVowelsIn2ndClassStartIndex && nAboveVowelsIn2ndClassCount > 0 )
bCheckAvailableChar = false;
}
}
}
else // ù <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
if( nVowelIndex >= s_nBehindVowelStartIndex ) // <20><>, <20><>,<2C>Ʒ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
bCheckAvailableChar = false;
}
}
return bCheckAvailableChar;
}
int CEtUIEditBox::GetPrevCaret()
{
int nPrevCaret = 0;
if( s_bCheckThaiLanguageVowelRule )
{
const WCHAR* pBuffer = m_Buffer.GetBuffer();
if( pBuffer == NULL ) return false;
for( int i=m_nCaret-1; i>=0; i-- )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
nPrevCaret = i;
break;
}
}
}
else
{
nPrevCaret = m_nCaret - 1;
}
return nPrevCaret;
}
int CEtUIEditBox::GetNextCaret()
{
int nNextCaret = 0;
if( s_bCheckThaiLanguageVowelRule )
{
int nBufferSize = m_Buffer.GetTextSize();
const WCHAR* pBuffer = m_Buffer.GetBuffer();
if( pBuffer == NULL ) return false;
for( int i=m_nCaret; i<nBufferSize; i++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
int nVowels = 0;
for( int j=i+1; j<nBufferSize; j++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[j] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 )
break;
else
nVowels++;
}
nNextCaret = i + 1 + nVowels;
break;
}
}
}
else
{
nNextCaret = m_nCaret + 1;
}
return nNextCaret;
}
int CEtUIEditBox::GetTextMoveCount( int nMoveCount, bool bForward )
{
int nResultMoveCount = 0;
if( s_bCheckThaiLanguageVowelRule )
{
const WCHAR* pBuffer = m_Buffer.GetBuffer();
int nBufferSize = m_Buffer.GetBufferSize();
if( pBuffer == NULL ) return 0;
int nCount = 0;
if( bForward )
{
for( int i=m_nFirstVisible; i<nBufferSize; i++, nResultMoveCount++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
nCount++;
if( nCount > nMoveCount )
break;
}
}
}
else
{
for( int i=m_nCaret; i>=0; i--, nResultMoveCount++ )
{
int nTextIndex = CheckThaiLanguageVowel( pBuffer[i] );
if( nTextIndex == -1 || nTextIndex < s_nBelowVowelStartIndex || nTextIndex == 13 ) // <20><><EFBFBD><EFBFBD>, <20><>/<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0xE33 <20><> <20><><EFBFBD>츸 üũ
{
nCount++;
if( nCount > nMoveCount )
break;
}
}
}
}
else
{
nResultMoveCount = nMoveCount;
}
return nResultMoveCount;
}