📄 dxutguiime.cpp
字号:
// If we are rendering the candidate window, save the position
// so that mouse clicks are checked properly.
if( !bReading )
s_CandList.rcCandidate = rc;
// Render the elements
m_pDialog->DrawRect( &rc, TextBkColor );
if( ( ImeUi_IsVerticalCand() && !bReading ) ||
( !ImeUi_IsHorizontalReading() && bReading ) )
{
// Vertical candidate window
for( UINT i = 0; i < nNumEntries; ++i )
{
// Here we are rendering one line at a time
rc.bottom = rc.top + nSingleLineHeight;
// Use a different color for the selected string
if( ImeUi_GetCandidateSelection() == i )
{
m_pDialog->DrawRect( &rc, SelBkColor );
m_Elements.GetAt( 1 )->FontColor.Current = SelTextColor;
} else
m_Elements.GetAt( 1 )->FontColor.Current = TextColor;
m_pDialog->DrawText( ImeUi_GetCandidate( i ), m_Elements.GetAt( 1 ), &rc );
rc.top += nSingleLineHeight;
}
} else
{
// Horizontal candidate window
m_Elements.GetAt( 1 )->FontColor.Current = TextColor;
if( bReading )
m_pDialog->DrawText( s_wszReadingString, m_Elements.GetAt( 1 ), &rc );
else
m_pDialog->DrawText( s_CandList.HoriCand.GetBuffer(), m_Elements.GetAt( 1 ), &rc );
// Render the selected entry differently
if( !bReading )
{
int nXLeft, nXRight;
s_CandList.HoriCand.CPtoX( s_CandList.nFirstSelected, FALSE, &nXLeft );
s_CandList.HoriCand.CPtoX( s_CandList.nFirstSelected + s_CandList.nHoriSelectedLen, FALSE, &nXRight );
rc.right = rc.left + nXRight;
rc.left += nXLeft;
m_pDialog->DrawRect( &rc, SelBkColor );
m_Elements.GetAt( 1 )->FontColor.Current = SelTextColor;
m_pDialog->DrawText( s_CandList.HoriCand.GetBuffer() + s_CandList.nFirstSelected,
m_Elements.GetAt( 1 ), &rc, false, s_CandList.nHoriSelectedLen );
}
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::RenderComposition( float fElapsedTime )
{
s_CompString.SetText( ImeUi_GetCompositionString() );
RECT rcCaret = { 0, 0, 0, 0 };
int nX, nXFirst;
m_Buffer.CPtoX( m_nCaret, FALSE, &nX );
m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst );
CDXUTElement *pElement = m_Elements.GetAt( 1 );
// Get the required width
RECT rc = { m_rcText.left + nX - nXFirst, m_rcText.top,
m_rcText.left + nX - nXFirst, m_rcText.bottom };
m_pDialog->CalcTextRect( s_CompString.GetBuffer(), pElement, &rc );
// If the composition string is too long to fit within
// the text area, move it to below the current line.
// This matches the behavior of the default IME.
if( rc.right > m_rcText.right )
OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top );
// Save the rectangle position for processing highlighted text.
RECT rcFirst = rc;
// Update s_ptCompString for RenderCandidateReadingWindow().
s_ptCompString.x = rc.left; s_ptCompString.y = rc.top;
D3DCOLOR TextColor = m_CompColor;
// Render the window and string.
// If the string is too long, we must wrap the line.
pElement->FontColor.Current = TextColor;
const WCHAR *pwszComp = s_CompString.GetBuffer();
int nCharLeft = s_CompString.GetTextSize() ;
for( ; ; )
{
// Find the last character that can be drawn on the same line.
int nLastInLine;
int bTrail;
s_CompString.XtoCP( m_rcText.right - rc.left, &nLastInLine, &bTrail );
int nNumCharToDraw = __min( nCharLeft, nLastInLine );
m_pDialog->CalcTextRect( pwszComp, pElement, &rc, nNumCharToDraw );
// Draw the background
// For Korean IME, blink the composition window background as if it
// is a cursor.
if( GetPrimaryLanguage() == LANG_KOREAN )
{
if( m_bCaretOn )
{
m_pDialog->DrawRect( &rc, m_CompWinColor );
}
else
{
// Not drawing composition string background. We
// use the editbox's text color for composition
// string text.
TextColor = m_Elements.GetAt(0)->FontColor.States[DXUT_STATE_NORMAL];
}
} else
{
// Non-Korean IME. Always draw composition background.
m_pDialog->DrawRect( &rc, m_CompWinColor );
}
// Draw the text
pElement->FontColor.Current = TextColor;
m_pDialog->DrawText( pwszComp, pElement, &rc, false, nNumCharToDraw );
// Advance pointer and counter
nCharLeft -= nNumCharToDraw;
pwszComp += nNumCharToDraw;
if( nCharLeft <= 0 )
break;
// Advance rectangle coordinates to beginning of next line
OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top );
}
// Load the rect for the first line again.
rc = rcFirst;
// Inspect each character in the comp string.
// For target-converted and target-non-converted characters,
// we display a different background color so they appear highlighted.
int nCharFirst = 0;
nXFirst = 0;
s_nFirstTargetConv = -1;
BYTE *pAttr;
const WCHAR *pcComp;
for( pcComp = s_CompString.GetBuffer(), pAttr = ImeUi_GetCompStringAttr();
*pcComp != L'\0'; ++pcComp, ++pAttr )
{
D3DCOLOR bkColor;
// Render a different background for this character
int nXLeft, nXRight;
s_CompString.CPtoX( int(pcComp - s_CompString.GetBuffer() ), FALSE, &nXLeft );
s_CompString.CPtoX( int(pcComp - s_CompString.GetBuffer() ), TRUE, &nXRight );
// Check if this character is off the right edge and should
// be wrapped to the next line.
if( nXRight - nXFirst > m_rcText.right - rc.left )
{
// Advance rectangle coordinates to beginning of next line
OffsetRect( &rc, m_rcText.left - rc.left, rc.bottom - rc.top );
// Update the line's first character information
nCharFirst = int( pcComp - s_CompString.GetBuffer() );
s_CompString.CPtoX( nCharFirst, FALSE, &nXFirst );
}
// If the caret is on this character, save the coordinates
// for drawing the caret later.
if( ImeUi_GetImeCursorChars() == (DWORD)(pcComp - s_CompString.GetBuffer() ) )
{
rcCaret = rc;
rcCaret.left += nXLeft - nXFirst - 1;
rcCaret.right = rcCaret.left + 2;
}
// Set up color based on the character attribute
if( *pAttr == ATTR_TARGET_CONVERTED )
{
pElement->FontColor.Current = m_CompTargetColor;
bkColor = m_CompTargetBkColor;
}
else
if( *pAttr == ATTR_TARGET_NOTCONVERTED )
{
pElement->FontColor.Current = m_CompTargetNonColor;
bkColor = m_CompTargetNonBkColor;
}
else
{
continue;
}
RECT rcTarget = { rc.left + nXLeft - nXFirst, rc.top, rc.left + nXRight - nXFirst, rc.bottom };
m_pDialog->DrawRect( &rcTarget, bkColor );
m_pDialog->DrawText( pcComp, pElement, &rcTarget, false, 1 );
// Record the first target converted character's index
if( -1 == s_nFirstTargetConv )
s_nFirstTargetConv = int(pAttr - ImeUi_GetCompStringAttr() );
}
// Render the composition caret
if( m_bCaretOn )
{
// If the caret is at the very end, its position would not have
// been computed in the above loop. We compute it here.
if( ImeUi_GetImeCursorChars() == (DWORD)s_CompString.GetTextSize() )
{
s_CompString.CPtoX( ImeUi_GetImeCursorChars(), FALSE, &nX );
rcCaret = rc;
rcCaret.left += nX - nXFirst - 1;
rcCaret.right = rcCaret.left + 2;
}
m_pDialog->DrawRect( &rcCaret, m_CompCaretColor );
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::RenderIndicator( float fElapsedTime )
{
CDXUTElement *pElement = m_Elements.GetAt( 9 );
pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
m_pDialog->DrawSprite( pElement, &m_rcIndicator, DXUT_NEAR_BUTTON_DEPTH );
RECT rc = m_rcIndicator;
InflateRect( &rc, -m_nSpacing, -m_nSpacing );
pElement->FontColor.Current = m_IndicatorImeColor;
RECT rcCalc = { 0, 0, 0, 0 };
// If IME system is off, draw English indicator.
WCHAR *pwszIndicator = ImeUi_IsEnabled() ? ImeUi_GetIndicatior() : L"En";
m_pDialog->CalcTextRect( pwszIndicator, pElement, &rcCalc );
m_pDialog->DrawText( pwszIndicator, pElement, &rc );
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::Render( float fElapsedTime )
{
if( m_bVisible == false )
return;
// If we have not computed the indicator symbol width,
// do it.
if( !m_nIndicatorWidth )
{
RECT rc = { 0, 0, 0, 0 };
m_pDialog->CalcTextRect( L"En", m_Elements.GetAt( 9 ), &rc );
m_nIndicatorWidth = rc.right - rc.left;
// Update the rectangles now that we have the indicator's width
UpdateRects();
}
// Let the parent render first (edit control)
CDXUTEditBox::Render( fElapsedTime );
CDXUTElement* pElement = GetElement( 1 );
if( pElement )
{
s_CompString.SetFontNode( m_pDialog->GetFont( pElement->iFont ) );
s_CandList.HoriCand.SetFontNode( m_pDialog->GetFont( pElement->iFont ) );
}
//
// Now render the IME elements
//
ImeUi_RenderUI();
if( m_bHasFocus )
{
// Render the input locale indicator
RenderIndicator( fElapsedTime );
// Display the composition string.
// This method should also update s_ptCompString
// for RenderCandidateReadingWindow.
RenderComposition( fElapsedTime );
// Display the reading/candidate window. RenderCandidateReadingWindow()
// uses s_ptCompString to position itself. s_ptCompString must have
// been filled in by RenderComposition().
if( ImeUi_IsShowReadingWindow() )
// Reading window
RenderCandidateReadingWindow( fElapsedTime, true );
else
if( ImeUi_IsShowCandListWindow() )
// Candidate list window
RenderCandidateReadingWindow( fElapsedTime, false );
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::SetImeEnableFlag(bool bFlag)
{
s_bImeFlag = bFlag;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::Initialize( HWND hWnd )
{
ImeUiCallback_DrawRect = NULL;
ImeUiCallback_Malloc = malloc;
ImeUiCallback_Free = free;
ImeUiCallback_DrawFans = NULL;
ImeUi_Initialize( hWnd );
s_CompString.SetBufferSize( MAX_COMPSTRING_SIZE );
ImeUi_EnableIme( true );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -