DXUTgui.cpp
资源名称:Direct3D.rar [点击查看]
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:284k
源码类别:
DirextX编程
开发平台:
Visual C++
- m_pDialog->DrawText( m_strText, pElement, &rcWindow );
- }
- //--------------------------------------------------------------------------------------
- // CDXUTCheckBox class
- //--------------------------------------------------------------------------------------
- //--------------------------------------------------------------------------------------
- CDXUTCheckBox::CDXUTCheckBox( CDXUTDialog *pDialog )
- {
- m_Type = DXUT_CONTROL_CHECKBOX;
- m_pDialog = pDialog;
- m_bChecked = false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTCheckBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- case WM_KEYDOWN:
- {
- switch( wParam )
- {
- case VK_SPACE:
- m_bPressed = true;
- return true;
- }
- }
- case WM_KEYUP:
- {
- switch( wParam )
- {
- case VK_SPACE:
- if( m_bPressed == true )
- {
- m_bPressed = false;
- SetCheckedInternal( !m_bChecked, true );
- }
- return true;
- }
- }
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTCheckBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- {
- if( ContainsPoint( pt ) )
- {
- // Pressed while inside the control
- m_bPressed = true;
- SetCapture( DXUTGetHWND() );
- if( !m_bHasFocus )
- m_pDialog->RequestFocus( this );
- return true;
- }
- break;
- }
- case WM_LBUTTONUP:
- {
- if( m_bPressed )
- {
- m_bPressed = false;
- ReleaseCapture();
- // Button click
- if( ContainsPoint( pt ) )
- SetCheckedInternal( !m_bChecked, true );
- return true;
- }
- break;
- }
- };
- return false;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTCheckBox::SetCheckedInternal( bool bChecked, bool bFromInput )
- {
- m_bChecked = bChecked;
- m_pDialog->SendEvent( EVENT_CHECKBOX_CHANGED, bFromInput, this );
- }
- //--------------------------------------------------------------------------------------
- BOOL CDXUTCheckBox::ContainsPoint( POINT pt )
- {
- return ( PtInRect( &m_rcBoundingBox, pt ) ||
- PtInRect( &m_rcButton, pt ) );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTCheckBox::UpdateRects()
- {
- CDXUTButton::UpdateRects();
- m_rcButton = m_rcBoundingBox;
- m_rcButton.right = m_rcButton.left + RectHeight( m_rcButton );
- m_rcText = m_rcBoundingBox;
- m_rcText.left += (int) ( 1.25f * RectWidth( m_rcButton ) );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTCheckBox::Render( IDirect3DDevice9* pd3dDevice, float fElapsedTime )
- {
- DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
- if( m_bVisible == false )
- iState = DXUT_STATE_HIDDEN;
- else if( m_bEnabled == false )
- iState = DXUT_STATE_DISABLED;
- else if( m_bPressed )
- iState = DXUT_STATE_PRESSED;
- else if( m_bMouseOver )
- iState = DXUT_STATE_MOUSEOVER;
- else if( m_bHasFocus )
- iState = DXUT_STATE_FOCUS;
- CDXUTElement* pElement = m_Elements.GetAt( 0 );
- float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcButton );
- m_pDialog->DrawText( m_strText, pElement, &m_rcText, true );
- if( !m_bChecked )
- iState = DXUT_STATE_HIDDEN;
- pElement = m_Elements.GetAt( 1 );
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcButton );
- }
- //--------------------------------------------------------------------------------------
- // CDXUTRadioButton class
- //--------------------------------------------------------------------------------------
- //--------------------------------------------------------------------------------------
- CDXUTRadioButton::CDXUTRadioButton( CDXUTDialog *pDialog )
- {
- m_Type = DXUT_CONTROL_RADIOBUTTON;
- m_pDialog = pDialog;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTRadioButton::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- case WM_KEYDOWN:
- {
- switch( wParam )
- {
- case VK_SPACE:
- m_bPressed = true;
- return true;
- }
- }
- case WM_KEYUP:
- {
- switch( wParam )
- {
- case VK_SPACE:
- if( m_bPressed == true )
- {
- m_bPressed = false;
- m_pDialog->ClearRadioButtonGroup( m_nButtonGroup );
- m_bChecked = !m_bChecked;
- m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, true, this );
- }
- return true;
- }
- }
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTRadioButton::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- {
- if( ContainsPoint( pt ) )
- {
- // Pressed while inside the control
- m_bPressed = true;
- SetCapture( DXUTGetHWND() );
- if( !m_bHasFocus )
- m_pDialog->RequestFocus( this );
- return true;
- }
- break;
- }
- case WM_LBUTTONUP:
- {
- if( m_bPressed )
- {
- m_bPressed = false;
- ReleaseCapture();
- // Button click
- if( ContainsPoint( pt ) )
- {
- m_pDialog->ClearRadioButtonGroup( m_nButtonGroup );
- m_bChecked = !m_bChecked;
- m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, true, this );
- }
- return true;
- }
- break;
- }
- };
- return false;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTRadioButton::SetCheckedInternal( bool bChecked, bool bClearGroup, bool bFromInput )
- {
- if( bChecked && bClearGroup )
- m_pDialog->ClearRadioButtonGroup( m_nButtonGroup );
- m_bChecked = bChecked;
- m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, bFromInput, this );
- }
- //--------------------------------------------------------------------------------------
- // CDXUTComboBox class
- //--------------------------------------------------------------------------------------
- //--------------------------------------------------------------------------------------
- CDXUTComboBox::CDXUTComboBox( CDXUTDialog *pDialog ) :
- m_ScrollBar( pDialog )
- {
- m_Type = DXUT_CONTROL_COMBOBOX;
- m_pDialog = pDialog;
- m_nDropHeight = 100;
- m_nSBWidth = 16;
- m_bOpened = false;
- m_iSelected = -1;
- m_iFocused = -1;
- }
- //--------------------------------------------------------------------------------------
- CDXUTComboBox::~CDXUTComboBox()
- {
- RemoveAllItems();
- }
- //--------------------------------------------------------------------------------------
- void CDXUTComboBox::SetTextColor( D3DCOLOR Color )
- {
- CDXUTElement* pElement = m_Elements.GetAt( 0 );
- if( pElement )
- pElement->FontColor.States[DXUT_STATE_NORMAL] = Color;
- pElement = m_Elements.GetAt( 2 );
- if( pElement )
- pElement->FontColor.States[DXUT_STATE_NORMAL] = Color;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTComboBox::UpdateRects()
- {
- CDXUTButton::UpdateRects();
- m_rcButton = m_rcBoundingBox;
- m_rcButton.left = m_rcButton.right - RectHeight( m_rcButton );
- m_rcText = m_rcBoundingBox;
- m_rcText.right = m_rcButton.left;
- m_rcDropdown = m_rcText;
- OffsetRect( &m_rcDropdown, 0, (int) (0.90f * RectHeight( m_rcText )) );
- m_rcDropdown.bottom += m_nDropHeight;
- m_rcDropdown.right -= m_nSBWidth;
- m_rcDropdownText = m_rcDropdown;
- m_rcDropdownText.left += (int) (0.1f * RectWidth( m_rcDropdown ));
- m_rcDropdownText.right -= (int) (0.1f * RectWidth( m_rcDropdown ));
- m_rcDropdownText.top += (int) (0.1f * RectHeight( m_rcDropdown ));
- m_rcDropdownText.bottom -= (int) (0.1f * RectHeight( m_rcDropdown ));
- // Update the scrollbar's rects
- m_ScrollBar.SetLocation( m_rcDropdown.right, m_rcDropdown.top+2 );
- m_ScrollBar.SetSize( m_nSBWidth, RectHeight( m_rcDropdown )-2 );
- DXUTFontNode* pFontNode = m_pDialog->GetManager()->GetFontNode( m_Elements.GetAt( 2 )->iFont );
- if( pFontNode && pFontNode->nHeight )
- {
- m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) / pFontNode->nHeight );
- // The selected item may have been scrolled off the page.
- // Ensure that it is in page again.
- m_ScrollBar.ShowItem( m_iSelected );
- }
- }
- //--------------------------------------------------------------------------------------
- void CDXUTComboBox::OnFocusOut()
- {
- CDXUTButton::OnFocusOut();
- m_bOpened = false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTComboBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- const DWORD REPEAT_MASK = (0x40000000);
- if( !m_bEnabled || !m_bVisible )
- return false;
- // Let the scroll bar have a chance to handle it first
- if( m_ScrollBar.HandleKeyboard( uMsg, wParam, lParam ) )
- return true;
- switch( uMsg )
- {
- case WM_KEYDOWN:
- {
- switch( wParam )
- {
- case VK_RETURN:
- if( m_bOpened )
- {
- if( m_iSelected != m_iFocused )
- {
- m_iSelected = m_iFocused;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- }
- m_bOpened = false;
- if( !m_pDialog->m_bKeyboardInput )
- m_pDialog->ClearFocus();
- return true;
- }
- break;
- case VK_F4:
- // Filter out auto-repeats
- if( lParam & REPEAT_MASK )
- return true;
- m_bOpened = !m_bOpened;
- if( !m_bOpened )
- {
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- if( !m_pDialog->m_bKeyboardInput )
- m_pDialog->ClearFocus();
- }
- return true;
- case VK_LEFT:
- case VK_UP:
- if( m_iFocused > 0 )
- {
- m_iFocused--;
- m_iSelected = m_iFocused;
- if( !m_bOpened )
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- }
- return true;
- case VK_RIGHT:
- case VK_DOWN:
- if( m_iFocused+1 < (int)GetNumItems() )
- {
- m_iFocused++;
- m_iSelected = m_iFocused;
- if( !m_bOpened )
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- }
- return true;
- }
- break;
- }
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTComboBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- // Let the scroll bar handle it first.
- if( m_ScrollBar.HandleMouse( uMsg, pt, wParam, lParam ) )
- return true;
- switch( uMsg )
- {
- case WM_MOUSEMOVE:
- {
- if( m_bOpened && PtInRect( &m_rcDropdown, pt ) )
- {
- // Determine which item has been selected
- for( int i=0; i < m_Items.GetSize(); i++ )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt( i );
- if( pItem -> bVisible &&
- PtInRect( &pItem->rcActive, pt ) )
- {
- m_iFocused = i;
- }
- }
- return true;
- }
- break;
- }
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- {
- if( ContainsPoint( pt ) )
- {
- // Pressed while inside the control
- m_bPressed = true;
- SetCapture( DXUTGetHWND() );
- if( !m_bHasFocus )
- m_pDialog->RequestFocus( this );
- // Toggle dropdown
- if( m_bHasFocus )
- {
- m_bOpened = !m_bOpened;
- if( !m_bOpened )
- {
- if( !m_pDialog->m_bKeyboardInput )
- m_pDialog->ClearFocus();
- }
- }
- return true;
- }
- // Perhaps this click is within the dropdown
- if( m_bOpened && PtInRect( &m_rcDropdown, pt ) )
- {
- // Determine which item has been selected
- for( int i=m_ScrollBar.GetTrackPos(); i < m_Items.GetSize(); i++ )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt( i );
- if( pItem -> bVisible &&
- PtInRect( &pItem->rcActive, pt ) )
- {
- m_iFocused = m_iSelected = i;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- m_bOpened = false;
- if( !m_pDialog->m_bKeyboardInput )
- m_pDialog->ClearFocus();
- break;
- }
- }
- return true;
- }
- // Mouse click not on main control or in dropdown, fire an event if needed
- if( m_bOpened )
- {
- m_iFocused = m_iSelected;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- m_bOpened = false;
- }
- // Make sure the control is no longer in a pressed state
- m_bPressed = false;
- // Release focus if appropriate
- if( !m_pDialog->m_bKeyboardInput )
- {
- m_pDialog->ClearFocus();
- }
- break;
- }
- case WM_LBUTTONUP:
- {
- if( m_bPressed && ContainsPoint( pt ) )
- {
- // Button click
- m_bPressed = false;
- ReleaseCapture();
- return true;
- }
- break;
- }
- case WM_MOUSEWHEEL:
- {
- int zDelta = (short) HIWORD(wParam) / WHEEL_DELTA;
- if( m_bOpened )
- {
- UINT uLines;
- SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &uLines, 0 );
- m_ScrollBar.Scroll( -zDelta * uLines );
- } else
- {
- if( zDelta > 0 )
- {
- if( m_iFocused > 0 )
- {
- m_iFocused--;
- m_iSelected = m_iFocused;
- if( !m_bOpened )
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- }
- }
- else
- {
- if( m_iFocused+1 < (int)GetNumItems() )
- {
- m_iFocused++;
- m_iSelected = m_iFocused;
- if( !m_bOpened )
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- }
- }
- }
- return true;
- }
- };
- return false;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTComboBox::OnHotkey()
- {
- if( m_bOpened )
- return;
- if( m_iSelected == -1 )
- return;
- if( m_pDialog->IsKeyboardInputEnabled() )
- m_pDialog->RequestFocus( this );
- m_iSelected++;
- if( m_iSelected >= (int) m_Items.GetSize() )
- m_iSelected = 0;
- m_iFocused = m_iSelected;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTComboBox::Render( IDirect3DDevice9* pd3dDevice, float fElapsedTime )
- {
- DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
- if( !m_bOpened )
- iState = DXUT_STATE_HIDDEN;
- // Dropdown box
- CDXUTElement* pElement = m_Elements.GetAt( 2 );
- // If we have not initialized the scroll bar page size,
- // do that now.
- static bool bSBInit;
- if( !bSBInit )
- {
- // Update the page size of the scroll bar
- if( m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight )
- m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) / m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight );
- else
- m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) );
- bSBInit = true;
- }
- // Scroll bar
- if( m_bOpened )
- m_ScrollBar.Render( pd3dDevice, fElapsedTime );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime );
- pElement->FontColor.Blend( iState, fElapsedTime );
- m_pDialog->DrawSprite( pElement, &m_rcDropdown );
- // Selection outline
- CDXUTElement* pSelectionElement = m_Elements.GetAt( 3 );
- pSelectionElement->TextureColor.Current = pElement->TextureColor.Current;
- pSelectionElement->FontColor.Current = pSelectionElement->FontColor.States[ DXUT_STATE_NORMAL ];
- DXUTFontNode* pFont = m_pDialog->GetFont( pElement->iFont );
- if( pFont )
- {
- int curY = m_rcDropdownText.top;
- int nRemainingHeight = RectHeight( m_rcDropdownText );
- //WCHAR strDropdown[4096] = {0};
- for( int i = m_ScrollBar.GetTrackPos(); i < m_Items.GetSize(); i++ )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt( i );
- // Make sure there's room left in the dropdown
- nRemainingHeight -= pFont->nHeight;
- if( nRemainingHeight < 0 )
- {
- pItem->bVisible = false;
- continue;
- }
- SetRect( &pItem->rcActive, m_rcDropdownText.left, curY, m_rcDropdownText.right, curY + pFont->nHeight );
- curY += pFont->nHeight;
- //debug
- //int blue = 50 * i;
- //m_pDialog->DrawRect( &pItem->rcActive, 0xFFFF0000 | blue );
- pItem->bVisible = true;
- if( m_bOpened )
- {
- if( (int)i == m_iFocused )
- {
- RECT rc;
- SetRect( &rc, m_rcDropdown.left, pItem->rcActive.top-2, m_rcDropdown.right, pItem->rcActive.bottom+2 );
- m_pDialog->DrawSprite( pSelectionElement, &rc );
- m_pDialog->DrawText( pItem->strText, pSelectionElement, &pItem->rcActive );
- }
- else
- {
- m_pDialog->DrawText( pItem->strText, pElement, &pItem->rcActive );
- }
- }
- }
- }
- int nOffsetX = 0;
- int nOffsetY = 0;
- iState = DXUT_STATE_NORMAL;
- if( m_bVisible == false )
- iState = DXUT_STATE_HIDDEN;
- else if( m_bEnabled == false )
- iState = DXUT_STATE_DISABLED;
- else if( m_bPressed )
- {
- iState = DXUT_STATE_PRESSED;
- nOffsetX = 1;
- nOffsetY = 2;
- }
- else if( m_bMouseOver )
- {
- iState = DXUT_STATE_MOUSEOVER;
- nOffsetX = -1;
- nOffsetY = -2;
- }
- else if( m_bHasFocus )
- iState = DXUT_STATE_FOCUS;
- float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
- // Button
- pElement = m_Elements.GetAt( 1 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- RECT rcWindow = m_rcButton;
- OffsetRect( &rcWindow, nOffsetX, nOffsetY );
- m_pDialog->DrawSprite( pElement, &rcWindow );
- if( m_bOpened )
- iState = DXUT_STATE_PRESSED;
- // Main text box
- //TODO: remove magic numbers
- pElement = m_Elements.GetAt( 0 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcText);
- if( m_iSelected >= 0 && m_iSelected < (int) m_Items.GetSize() )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt( m_iSelected );
- if( pItem != NULL )
- {
- m_pDialog->DrawText( pItem->strText, pElement, &m_rcText );
- }
- }
- }
- //--------------------------------------------------------------------------------------
- HRESULT CDXUTComboBox::AddItem( const WCHAR* strText, void* pData )
- {
- // Validate parameters
- if( strText== NULL )
- {
- return E_INVALIDARG;
- }
- // Create a new item and set the data
- DXUTComboBoxItem* pItem = new DXUTComboBoxItem;
- if( pItem == NULL )
- {
- return DXTRACE_ERR_MSGBOX( L"new", E_OUTOFMEMORY );
- }
- ZeroMemory( pItem, sizeof(DXUTComboBoxItem) );
- StringCchCopy( pItem->strText, 256, strText );
- pItem->pData = pData;
- m_Items.Add( pItem );
- // Update the scroll bar with new range
- m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
- // If this is the only item in the list, it's selected
- if( GetNumItems() == 1 )
- {
- m_iSelected = 0;
- m_iFocused = 0;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
- }
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTComboBox::RemoveItem( UINT index )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt( index );
- SAFE_DELETE( pItem );
- m_Items.Remove( index );
- m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
- if( m_iSelected >= m_Items.GetSize() )
- m_iSelected = m_Items.GetSize() - 1;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTComboBox::RemoveAllItems()
- {
- for( int i=0; i < m_Items.GetSize(); i++ )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt( i );
- SAFE_DELETE( pItem );
- }
- m_Items.RemoveAll();
- m_ScrollBar.SetTrackRange( 0, 1 );
- m_iFocused = m_iSelected = -1;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTComboBox::ContainsItem( const WCHAR* strText, UINT iStart )
- {
- return ( -1 != FindItem( strText, iStart ) );
- }
- //--------------------------------------------------------------------------------------
- int CDXUTComboBox::FindItem( const WCHAR* strText, UINT iStart )
- {
- if( strText == NULL )
- return -1;
- for( int i = iStart; i < m_Items.GetSize(); i++ )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt(i);
- if( 0 == wcscmp( pItem->strText, strText ) )
- {
- return i;
- }
- }
- return -1;
- }
- //--------------------------------------------------------------------------------------
- void* CDXUTComboBox::GetSelectedData()
- {
- if( m_iSelected < 0 )
- return NULL;
- DXUTComboBoxItem* pItem = m_Items.GetAt( m_iSelected );
- return pItem->pData;
- }
- //--------------------------------------------------------------------------------------
- DXUTComboBoxItem* CDXUTComboBox::GetSelectedItem()
- {
- if( m_iSelected < 0 )
- return NULL;
- return m_Items.GetAt( m_iSelected );
- }
- //--------------------------------------------------------------------------------------
- void* CDXUTComboBox::GetItemData( const WCHAR* strText )
- {
- int index = FindItem( strText );
- if( index == -1 )
- {
- return NULL;
- }
- DXUTComboBoxItem* pItem = m_Items.GetAt(index);
- if( pItem == NULL )
- {
- DXTRACE_ERR( L"CGrowableArray::GetAt", E_FAIL );
- return NULL;
- }
- return pItem->pData;
- }
- //--------------------------------------------------------------------------------------
- void* CDXUTComboBox::GetItemData( int nIndex )
- {
- if( nIndex < 0 || nIndex >= m_Items.GetSize() )
- return NULL;
- return m_Items.GetAt( nIndex )->pData;
- }
- //--------------------------------------------------------------------------------------
- HRESULT CDXUTComboBox::SetSelectedByIndex( UINT index )
- {
- if( index >= GetNumItems() )
- return E_INVALIDARG;
- m_iFocused = m_iSelected = index;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- HRESULT CDXUTComboBox::SetSelectedByText( const WCHAR* strText )
- {
- if( strText == NULL )
- return E_INVALIDARG;
- int index = FindItem( strText );
- if( index == -1 )
- return E_FAIL;
- m_iFocused = m_iSelected = index;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- HRESULT CDXUTComboBox::SetSelectedByData( void* pData )
- {
- for( int i=0; i < m_Items.GetSize(); i++ )
- {
- DXUTComboBoxItem* pItem = m_Items.GetAt(i);
- if( pItem->pData == pData )
- {
- m_iFocused = m_iSelected = i;
- m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
- return S_OK;
- }
- }
- return E_FAIL;
- }
- //--------------------------------------------------------------------------------------
- CDXUTSlider::CDXUTSlider( CDXUTDialog *pDialog )
- {
- m_Type = DXUT_CONTROL_SLIDER;
- m_pDialog = pDialog;
- m_nMin = 0;
- m_nMax = 100;
- m_nValue = 50;
- m_bPressed = false;
- }
- //--------------------------------------------------------------------------------------
- BOOL CDXUTSlider::ContainsPoint( POINT pt )
- {
- return ( PtInRect( &m_rcBoundingBox, pt ) ||
- PtInRect( &m_rcButton, pt ) );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTSlider::UpdateRects()
- {
- CDXUTControl::UpdateRects();
- m_rcButton = m_rcBoundingBox;
- m_rcButton.right = m_rcButton.left + RectHeight( m_rcButton );
- OffsetRect( &m_rcButton, -RectWidth( m_rcButton )/2, 0 );
- m_nButtonX = (int) ( (m_nValue - m_nMin) * (float)RectWidth( m_rcBoundingBox ) / (m_nMax - m_nMin) );
- OffsetRect( &m_rcButton, m_nButtonX, 0 );
- }
- int CDXUTSlider::ValueFromPos( int x )
- {
- float fValuePerPixel = (float)(m_nMax - m_nMin) / RectWidth( m_rcBoundingBox );
- return (int) (0.5f + m_nMin + fValuePerPixel * (x - m_rcBoundingBox.left)) ;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTSlider::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- case WM_KEYDOWN:
- {
- switch( wParam )
- {
- case VK_HOME:
- SetValueInternal( m_nMin, true );
- return true;
- case VK_END:
- SetValueInternal( m_nMax, true );
- return true;
- case VK_LEFT:
- case VK_DOWN:
- SetValueInternal( m_nValue - 1, true );
- return true;
- case VK_RIGHT:
- case VK_UP:
- SetValueInternal( m_nValue + 1, true );
- return true;
- case VK_NEXT:
- SetValueInternal( m_nValue - ( 10 > (m_nMax - m_nMin) / 10 ? 10 : (m_nMax - m_nMin) / 10 ), true );
- return true;
- case VK_PRIOR:
- SetValueInternal( m_nValue + ( 10 > (m_nMax - m_nMin) / 10 ? 10 : (m_nMax - m_nMin) / 10 ), true );
- return true;
- }
- break;
- }
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTSlider::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- {
- if( PtInRect( &m_rcButton, pt ) )
- {
- // Pressed while inside the control
- m_bPressed = true;
- SetCapture( DXUTGetHWND() );
- m_nDragX = pt.x;
- //m_nDragY = pt.y;
- m_nDragOffset = m_nButtonX - m_nDragX;
- //m_nDragValue = m_nValue;
- if( !m_bHasFocus )
- m_pDialog->RequestFocus( this );
- return true;
- }
- if( PtInRect( &m_rcBoundingBox, pt ) )
- {
- m_nDragX = pt.x;
- m_nDragOffset = 0;
- m_bPressed = true;
- if( !m_bHasFocus )
- m_pDialog->RequestFocus( this );
- if( pt.x > m_nButtonX + m_x )
- {
- SetValueInternal( m_nValue + 1, true );
- return true;
- }
- if( pt.x < m_nButtonX + m_x )
- {
- SetValueInternal( m_nValue - 1, true );
- return true;
- }
- }
- break;
- }
- case WM_LBUTTONUP:
- {
- if( m_bPressed )
- {
- m_bPressed = false;
- ReleaseCapture();
- m_pDialog->SendEvent( EVENT_SLIDER_VALUE_CHANGED, true, this );
- return true;
- }
- break;
- }
- case WM_MOUSEMOVE:
- {
- if( m_bPressed )
- {
- SetValueInternal( ValueFromPos( m_x + pt.x + m_nDragOffset ), true );
- return true;
- }
- break;
- }
- case WM_MOUSEWHEEL:
- {
- int nScrollAmount = int((short)HIWORD(wParam)) / WHEEL_DELTA;
- SetValueInternal( m_nValue - nScrollAmount, true );
- return true;
- }
- };
- return false;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTSlider::SetRange( int nMin, int nMax )
- {
- m_nMin = nMin;
- m_nMax = nMax;
- SetValueInternal( m_nValue, false );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTSlider::SetValueInternal( int nValue, bool bFromInput )
- {
- // Clamp to range
- nValue = __max( m_nMin, nValue );
- nValue = __min( m_nMax, nValue );
- if( nValue == m_nValue )
- return;
- m_nValue = nValue;
- UpdateRects();
- m_pDialog->SendEvent( EVENT_SLIDER_VALUE_CHANGED, bFromInput, this );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTSlider::Render( IDirect3DDevice9* pd3dDevice, float fElapsedTime )
- {
- int nOffsetX = 0;
- int nOffsetY = 0;
- DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
- if( m_bVisible == false )
- {
- iState = DXUT_STATE_HIDDEN;
- }
- else if( m_bEnabled == false )
- {
- iState = DXUT_STATE_DISABLED;
- }
- else if( m_bPressed )
- {
- iState = DXUT_STATE_PRESSED;
- nOffsetX = 1;
- nOffsetY = 2;
- }
- else if( m_bMouseOver )
- {
- iState = DXUT_STATE_MOUSEOVER;
- nOffsetX = -1;
- nOffsetY = -2;
- }
- else if( m_bHasFocus )
- {
- iState = DXUT_STATE_FOCUS;
- }
- float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
- CDXUTElement* pElement = m_Elements.GetAt( 0 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcBoundingBox );
- //TODO: remove magic numbers
- pElement = m_Elements.GetAt( 1 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcButton );
- }
- //--------------------------------------------------------------------------------------
- // CDXUTScrollBar class
- //--------------------------------------------------------------------------------------
- //--------------------------------------------------------------------------------------
- CDXUTScrollBar::CDXUTScrollBar( CDXUTDialog *pDialog )
- {
- m_Type = DXUT_CONTROL_SCROLLBAR;
- m_pDialog = pDialog;
- m_bShowThumb = true;
- m_bDrag = false;
- SetRect( &m_rcUpButton, 0, 0, 0, 0 );
- SetRect( &m_rcDownButton, 0, 0, 0, 0 );
- SetRect( &m_rcTrack, 0, 0, 0, 0 );
- SetRect( &m_rcThumb, 0, 0, 0, 0 );
- m_nPosition = 0;
- m_nPageSize = 1;
- m_nStart = 0;
- m_nEnd = 1;
- m_Arrow = CLEAR;
- m_dArrowTS = 0.0;
- }
- //--------------------------------------------------------------------------------------
- CDXUTScrollBar::~CDXUTScrollBar()
- {
- }
- //--------------------------------------------------------------------------------------
- void CDXUTScrollBar::UpdateRects()
- {
- CDXUTControl::UpdateRects();
- // Make the buttons square
- SetRect( &m_rcUpButton, m_rcBoundingBox.left, m_rcBoundingBox.top,
- m_rcBoundingBox.right, m_rcBoundingBox.top + RectWidth( m_rcBoundingBox ) );
- SetRect( &m_rcDownButton, m_rcBoundingBox.left, m_rcBoundingBox.bottom - RectWidth( m_rcBoundingBox ),
- m_rcBoundingBox.right, m_rcBoundingBox.bottom );
- SetRect( &m_rcTrack, m_rcUpButton.left, m_rcUpButton.bottom,
- m_rcDownButton.right, m_rcDownButton.top );
- m_rcThumb.left = m_rcUpButton.left;
- m_rcThumb.right = m_rcUpButton.right;
- UpdateThumbRect();
- }
- //--------------------------------------------------------------------------------------
- // Compute the dimension of the scroll thumb
- void CDXUTScrollBar::UpdateThumbRect()
- {
- if( m_nEnd - m_nStart > m_nPageSize )
- {
- int nThumbHeight = __max( RectHeight( m_rcTrack ) * m_nPageSize / ( m_nEnd - m_nStart ), SCROLLBAR_MINTHUMBSIZE );
- int nMaxPosition = m_nEnd - m_nStart - m_nPageSize;
- m_rcThumb.top = m_rcTrack.top + ( m_nPosition - m_nStart ) * ( RectHeight( m_rcTrack ) - nThumbHeight )
- / nMaxPosition;
- m_rcThumb.bottom = m_rcThumb.top + nThumbHeight;
- m_bShowThumb = true;
- }
- else
- {
- // No content to scroll
- m_rcThumb.bottom = m_rcThumb.top;
- m_bShowThumb = false;
- }
- }
- //--------------------------------------------------------------------------------------
- // Scroll() scrolls by nDelta items. A positive value scrolls down, while a negative
- // value scrolls up.
- void CDXUTScrollBar::Scroll( int nDelta )
- {
- // Perform scroll
- m_nPosition += nDelta;
- // Cap position
- Cap();
- // Update thumb position
- UpdateThumbRect();
- }
- //--------------------------------------------------------------------------------------
- void CDXUTScrollBar::ShowItem( int nIndex )
- {
- // Cap the index
- if( nIndex < 0 )
- nIndex = 0;
- if( nIndex >= m_nEnd )
- nIndex = m_nEnd - 1;
- // Adjust position
- if( m_nPosition > nIndex )
- m_nPosition = nIndex;
- else
- if( m_nPosition + m_nPageSize <= nIndex )
- m_nPosition = nIndex - m_nPageSize + 1;
- UpdateThumbRect();
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTScrollBar::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTScrollBar::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
- {
- static int ThumbOffsetY;
- m_LastMouse = pt;
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- {
- // Check for click on up button
- if( PtInRect( &m_rcUpButton, pt ) )
- {
- SetCapture( DXUTGetHWND() );
- if( m_nPosition > m_nStart )
- --m_nPosition;
- UpdateThumbRect();
- m_Arrow = CLICKED_UP;
- m_dArrowTS = DXUTGetTime();
- return true;
- }
- // Check for click on down button
- if( PtInRect( &m_rcDownButton, pt ) )
- {
- SetCapture( DXUTGetHWND() );
- if( m_nPosition + m_nPageSize < m_nEnd )
- ++m_nPosition;
- UpdateThumbRect();
- m_Arrow = CLICKED_DOWN;
- m_dArrowTS = DXUTGetTime();
- return true;
- }
- // Check for click on thumb
- if( PtInRect( &m_rcThumb, pt ) )
- {
- SetCapture( DXUTGetHWND() );
- m_bDrag = true;
- ThumbOffsetY = pt.y - m_rcThumb.top;
- return true;
- }
- // Check for click on track
- if( m_rcThumb.left <= pt.x &&
- m_rcThumb.right > pt.x )
- {
- SetCapture( DXUTGetHWND() );
- if( m_rcThumb.top > pt.y &&
- m_rcTrack.top <= pt.y )
- {
- Scroll( -( m_nPageSize - 1 ) );
- return true;
- } else
- if( m_rcThumb.bottom <= pt.y &&
- m_rcTrack.bottom > pt.y )
- {
- Scroll( m_nPageSize - 1 );
- return true;
- }
- }
- break;
- }
- case WM_LBUTTONUP:
- {
- m_bDrag = false;
- ReleaseCapture();
- UpdateThumbRect();
- m_Arrow = CLEAR;
- break;
- }
- case WM_MOUSEMOVE:
- {
- if( m_bDrag )
- {
- m_rcThumb.bottom += pt.y - ThumbOffsetY - m_rcThumb.top;
- m_rcThumb.top = pt.y - ThumbOffsetY;
- if( m_rcThumb.top < m_rcTrack.top )
- OffsetRect( &m_rcThumb, 0, m_rcTrack.top - m_rcThumb.top );
- else
- if( m_rcThumb.bottom > m_rcTrack.bottom )
- OffsetRect( &m_rcThumb, 0, m_rcTrack.bottom - m_rcThumb.bottom );
- // Compute first item index based on thumb position
- int nMaxFirstItem = m_nEnd - m_nStart - m_nPageSize; // Largest possible index for first item
- int nMaxThumb = RectHeight( m_rcTrack ) - RectHeight( m_rcThumb ); // Largest possible thumb position from the top
- m_nPosition = m_nStart +
- ( m_rcThumb.top - m_rcTrack.top +
- nMaxThumb / ( nMaxFirstItem * 2 ) ) * // Shift by half a row to avoid last row covered by only one pixel
- nMaxFirstItem / nMaxThumb;
- return true;
- }
- break;
- }
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTScrollBar::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( WM_CAPTURECHANGED == uMsg )
- {
- // The application just lost mouse capture. We may not have gotten
- // the WM_MOUSEUP message, so reset m_bDrag here.
- if( (HWND)lParam != DXUTGetHWND() )
- m_bDrag = false;
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTScrollBar::Render( IDirect3DDevice9* pd3dDevice, float fElapsedTime )
- {
- // Check if the arrow button has been held for a while.
- // If so, update the thumb position to simulate repeated
- // scroll.
- if( m_Arrow != CLEAR )
- {
- double dCurrTime = DXUTGetTime();
- if( PtInRect( &m_rcUpButton, m_LastMouse ) )
- {
- switch( m_Arrow )
- {
- case CLICKED_UP:
- if( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS )
- {
- Scroll( -1 );
- m_Arrow = HELD_UP;
- m_dArrowTS = dCurrTime;
- }
- break;
- case HELD_UP:
- if( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS )
- {
- Scroll( -1 );
- m_dArrowTS = dCurrTime;
- }
- break;
- }
- } else
- if( PtInRect( &m_rcDownButton, m_LastMouse ) )
- {
- switch( m_Arrow )
- {
- case CLICKED_DOWN:
- if( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS )
- {
- Scroll( 1 );
- m_Arrow = HELD_DOWN;
- m_dArrowTS = dCurrTime;
- }
- break;
- case HELD_DOWN:
- if( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS )
- {
- Scroll( 1 );
- m_dArrowTS = dCurrTime;
- }
- break;
- }
- }
- }
- DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
- if( m_bVisible == false )
- iState = DXUT_STATE_HIDDEN;
- else if( m_bEnabled == false || m_bShowThumb == false )
- iState = DXUT_STATE_DISABLED;
- else if( m_bMouseOver )
- iState = DXUT_STATE_MOUSEOVER;
- else if( m_bHasFocus )
- iState = DXUT_STATE_FOCUS;
- float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
- // Background track layer
- CDXUTElement* pElement = m_Elements.GetAt( 0 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcTrack );
- // Up Arrow
- pElement = m_Elements.GetAt( 1 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcUpButton );
- // Down Arrow
- pElement = m_Elements.GetAt( 2 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcDownButton );
- // Thumb button
- pElement = m_Elements.GetAt( 3 );
- // Blend current color
- pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
- m_pDialog->DrawSprite( pElement, &m_rcThumb );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTScrollBar::SetTrackRange( int nStart, int nEnd )
- {
- m_nStart = nStart; m_nEnd = nEnd;
- Cap();
- UpdateThumbRect();
- }
- //--------------------------------------------------------------------------------------
- void CDXUTScrollBar::Cap() // Clips position at boundaries. Ensures it stays within legal range.
- {
- if( m_nPosition < m_nStart ||
- m_nEnd - m_nStart <= m_nPageSize )
- {
- m_nPosition = m_nStart;
- }
- else
- if( m_nPosition + m_nPageSize > m_nEnd )
- m_nPosition = m_nEnd - m_nPageSize;
- }
- //--------------------------------------------------------------------------------------
- // CDXUTListBox class
- //--------------------------------------------------------------------------------------
- //--------------------------------------------------------------------------------------
- CDXUTListBox::CDXUTListBox( CDXUTDialog *pDialog ) :
- m_ScrollBar( pDialog )
- {
- m_Type = DXUT_CONTROL_LISTBOX;
- m_pDialog = pDialog;
- m_dwStyle = 0;
- m_nSBWidth = 16;
- m_nSelected = -1;
- m_nSelStart = 0;
- m_bDrag = false;
- m_nBorder = 6;
- m_nMargin = 5;
- m_nTextHeight = 0;
- }
- //--------------------------------------------------------------------------------------
- CDXUTListBox::~CDXUTListBox()
- {
- RemoveAllItems();
- }
- //--------------------------------------------------------------------------------------
- void CDXUTListBox::UpdateRects()
- {
- CDXUTControl::UpdateRects();
- m_rcSelection = m_rcBoundingBox;
- m_rcSelection.right -= m_nSBWidth;
- InflateRect( &m_rcSelection, -m_nBorder, -m_nBorder );
- m_rcText = m_rcSelection;
- InflateRect( &m_rcText, -m_nMargin, 0 );
- // Update the scrollbar's rects
- m_ScrollBar.SetLocation( m_rcBoundingBox.right - m_nSBWidth, m_rcBoundingBox.top );
- m_ScrollBar.SetSize( m_nSBWidth, m_height );
- DXUTFontNode* pFontNode = m_pDialog->GetManager()->GetFontNode( m_Elements.GetAt( 0 )->iFont );
- if( pFontNode && pFontNode->nHeight )
- {
- m_ScrollBar.SetPageSize( RectHeight( m_rcText ) / pFontNode->nHeight );
- // The selected item may have been scrolled off the page.
- // Ensure that it is in page again.
- m_ScrollBar.ShowItem( m_nSelected );
- }
- }
- //--------------------------------------------------------------------------------------
- HRESULT CDXUTListBox::AddItem( const WCHAR *wszText, void *pData )
- {
- DXUTListBoxItem *pNewItem = new DXUTListBoxItem;
- if( !pNewItem )
- return E_OUTOFMEMORY;
- StringCchCopy( pNewItem->strText, 256, wszText );
- pNewItem->pData = pData;
- SetRect( &pNewItem->rcActive, 0, 0, 0, 0 );
- pNewItem->bSelected = false;
- HRESULT hr = m_Items.Add( pNewItem );
- if( FAILED(hr) )
- {
- SAFE_DELETE( pNewItem );
- }
- else
- {
- m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
- }
- return hr;
- }
- //--------------------------------------------------------------------------------------
- HRESULT CDXUTListBox::InsertItem( int nIndex, const WCHAR *wszText, void *pData )
- {
- DXUTListBoxItem *pNewItem = new DXUTListBoxItem;
- if( !pNewItem )
- return E_OUTOFMEMORY;
- StringCchCopy( pNewItem->strText, 256, wszText );
- pNewItem->pData = pData;
- SetRect( &pNewItem->rcActive, 0, 0, 0, 0 );
- pNewItem->bSelected = false;
- HRESULT hr = m_Items.Insert( nIndex, pNewItem );
- if( SUCCEEDED( hr ) )
- m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
- else
- SAFE_DELETE( pNewItem );
- return hr;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTListBox::RemoveItem( int nIndex )
- {
- if( nIndex < 0 || nIndex >= (int)m_Items.GetSize() )
- return;
- DXUTListBoxItem *pItem = m_Items.GetAt( nIndex );
- delete pItem;
- m_Items.Remove( nIndex );
- m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
- if( m_nSelected >= (int)m_Items.GetSize() )
- m_nSelected = m_Items.GetSize() - 1;
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTListBox::RemoveItemByText( WCHAR *wszText )
- {
- }
- //--------------------------------------------------------------------------------------
- void CDXUTListBox::RemoveItemByData( void *pData )
- {
- }
- //--------------------------------------------------------------------------------------
- void CDXUTListBox::RemoveAllItems()
- {
- for( int i = 0; i < m_Items.GetSize(); ++i )
- {
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- delete pItem;
- }
- m_Items.RemoveAll();
- m_ScrollBar.SetTrackRange( 0, 1 );
- }
- //--------------------------------------------------------------------------------------
- DXUTListBoxItem *CDXUTListBox::GetItem( int nIndex )
- {
- if( nIndex < 0 || nIndex >= (int)m_Items.GetSize() )
- return NULL;
- return m_Items[nIndex];
- }
- //--------------------------------------------------------------------------------------
- // For single-selection listbox, returns the index of the selected item.
- // For multi-selection, returns the first selected item after the nPreviousSelected position.
- // To search for the first selected item, the app passes -1 for nPreviousSelected. For
- // subsequent searches, the app passes the returned index back to GetSelectedIndex as.
- // nPreviousSelected.
- // Returns -1 on error or if no item is selected.
- int CDXUTListBox::GetSelectedIndex( int nPreviousSelected )
- {
- if( nPreviousSelected < -1 )
- return -1;
- if( m_dwStyle & MULTISELECTION )
- {
- // Multiple selection enabled. Search for the next item with the selected flag.
- for( int i = nPreviousSelected + 1; i < (int)m_Items.GetSize(); ++i )
- {
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- if( pItem->bSelected )
- return i;
- }
- return -1;
- }
- else
- {
- // Single selection
- return m_nSelected;
- }
- }
- //--------------------------------------------------------------------------------------
- void CDXUTListBox::SelectItem( int nNewIndex )
- {
- // If no item exists, do nothing.
- if( m_Items.GetSize() == 0 )
- return;
- int nOldSelected = m_nSelected;
- // Adjust m_nSelected
- m_nSelected = nNewIndex;
- // Perform capping
- if( m_nSelected < 0 )
- m_nSelected = 0;
- if( m_nSelected >= (int)m_Items.GetSize() )
- m_nSelected = m_Items.GetSize() - 1;
- if( nOldSelected != m_nSelected )
- {
- if( m_dwStyle & MULTISELECTION )
- {
- m_Items[m_nSelected]->bSelected = true;
- }
- // Update selection start
- m_nSelStart = m_nSelected;
- // Adjust scroll bar
- m_ScrollBar.ShowItem( m_nSelected );
- }
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTListBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- // Let the scroll bar have a chance to handle it first
- if( m_ScrollBar.HandleKeyboard( uMsg, wParam, lParam ) )
- return true;
- switch( uMsg )
- {
- case WM_KEYDOWN:
- switch( wParam )
- {
- case VK_UP:
- case VK_DOWN:
- case VK_NEXT:
- case VK_PRIOR:
- case VK_HOME:
- case VK_END:
- {
- // If no item exists, do nothing.
- if( m_Items.GetSize() == 0 )
- return true;
- int nOldSelected = m_nSelected;
- // Adjust m_nSelected
- switch( wParam )
- {
- case VK_UP: --m_nSelected; break;
- case VK_DOWN: ++m_nSelected; break;
- case VK_NEXT: m_nSelected += m_ScrollBar.GetPageSize() - 1; break;
- case VK_PRIOR: m_nSelected -= m_ScrollBar.GetPageSize() - 1; break;
- case VK_HOME: m_nSelected = 0; break;
- case VK_END: m_nSelected = m_Items.GetSize() - 1; break;
- }
- // Perform capping
- if( m_nSelected < 0 )
- m_nSelected = 0;
- if( m_nSelected >= (int)m_Items.GetSize() )
- m_nSelected = m_Items.GetSize() - 1;
- if( nOldSelected != m_nSelected )
- {
- if( m_dwStyle & MULTISELECTION )
- {
- // Multiple selection
- // Clear all selection
- for( int i = 0; i < (int)m_Items.GetSize(); ++i )
- {
- DXUTListBoxItem *pItem = m_Items[i];
- pItem->bSelected = false;
- }
- if( GetKeyState( VK_SHIFT ) < 0 )
- {
- // Select all items from m_nSelStart to
- // m_nSelected
- int nEnd = __max( m_nSelStart, m_nSelected );
- for( int n = __min( m_nSelStart, m_nSelected ); n <= nEnd; ++n )
- m_Items[n]->bSelected = true;
- }
- else
- {
- m_Items[m_nSelected]->bSelected = true;
- // Update selection start
- m_nSelStart = m_nSelected;
- }
- } else
- m_nSelStart = m_nSelected;
- // Adjust scroll bar
- m_ScrollBar.ShowItem( m_nSelected );
- // Send notification
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- }
- return true;
- }
- // Space is the hotkey for double-clicking an item.
- //
- case VK_SPACE:
- m_pDialog->SendEvent( EVENT_LISTBOX_ITEM_DBLCLK, true, this );
- return true;
- }
- break;
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTListBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- // First acquire focus
- if( WM_LBUTTONDOWN == uMsg )
- if( !m_bHasFocus )
- m_pDialog->RequestFocus( this );
- // Let the scroll bar handle it first.
- if( m_ScrollBar.HandleMouse( uMsg, pt, wParam, lParam ) )
- return true;
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- // Check for clicks in the text area
- if( m_Items.GetSize() > 0 && PtInRect( &m_rcSelection, pt ) )
- {
- // Compute the index of the clicked item
- int nClicked;
- if( m_nTextHeight )
- nClicked = m_ScrollBar.GetTrackPos() + ( pt.y - m_rcText.top ) / m_nTextHeight;
- else
- nClicked = -1;
- // Only proceed if the click falls on top of an item.
- if( nClicked >= m_ScrollBar.GetTrackPos() &&
- nClicked < (int)m_Items.GetSize() &&
- nClicked < m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() )
- {
- SetCapture( DXUTGetHWND() );
- m_bDrag = true;
- // If this is a double click, fire off an event and exit
- // since the first click would have taken care of the selection
- // updating.
- if( uMsg == WM_LBUTTONDBLCLK )
- {
- m_pDialog->SendEvent( EVENT_LISTBOX_ITEM_DBLCLK, true, this );
- return true;
- }
- m_nSelected = nClicked;
- if( !( wParam & MK_SHIFT ) )
- m_nSelStart = m_nSelected;
- // If this is a multi-selection listbox, update per-item
- // selection data.
- if( m_dwStyle & MULTISELECTION )
- {
- // Determine behavior based on the state of Shift and Ctrl
- DXUTListBoxItem *pSelItem = m_Items.GetAt( m_nSelected );
- if( ( wParam & (MK_SHIFT|MK_CONTROL) ) == MK_CONTROL )
- {
- // Control click. Reverse the selection of this item.
- pSelItem->bSelected = !pSelItem->bSelected;
- } else
- if( ( wParam & (MK_SHIFT|MK_CONTROL) ) == MK_SHIFT )
- {
- // Shift click. Set the selection for all items
- // from last selected item to the current item.
- // Clear everything else.
- int nBegin = __min( m_nSelStart, m_nSelected );
- int nEnd = __max( m_nSelStart, m_nSelected );
- for( int i = 0; i < nBegin; ++i )
- {
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- pItem->bSelected = false;
- }
- for( int i = nEnd + 1; i < (int)m_Items.GetSize(); ++i )
- {
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- pItem->bSelected = false;
- }
- for( int i = nBegin; i <= nEnd; ++i )
- {
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- pItem->bSelected = true;
- }
- } else
- if( ( wParam & (MK_SHIFT|MK_CONTROL) ) == ( MK_SHIFT|MK_CONTROL ) )
- {
- // Control-Shift-click.
- // The behavior is:
- // Set all items from m_nSelStart to m_nSelected to
- // the same state as m_nSelStart, not including m_nSelected.
- // Set m_nSelected to selected.
- int nBegin = __min( m_nSelStart, m_nSelected );
- int nEnd = __max( m_nSelStart, m_nSelected );
- // The two ends do not need to be set here.
- bool bLastSelected = m_Items.GetAt( m_nSelStart )->bSelected;
- for( int i = nBegin + 1; i < nEnd; ++i )
- {
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- pItem->bSelected = bLastSelected;
- }
- pSelItem->bSelected = true;
- // Restore m_nSelected to the previous value
- // This matches the Windows behavior
- m_nSelected = m_nSelStart;
- } else
- {
- // Simple click. Clear all items and select the clicked
- // item.
- for( int i = 0; i < (int)m_Items.GetSize(); ++i )
- {
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- pItem->bSelected = false;
- }
- pSelItem->bSelected = true;
- }
- } // End of multi-selection case
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- }
- return true;
- }
- break;
- case WM_LBUTTONUP:
- {
- ReleaseCapture();
- m_bDrag = false;
- if( m_nSelected != -1 )
- {
- // Set all items between m_nSelStart and m_nSelected to
- // the same state as m_nSelStart
- int nEnd = __max( m_nSelStart, m_nSelected );
- for( int n = __min( m_nSelStart, m_nSelected ) + 1; n < nEnd; ++n )
- m_Items[n]->bSelected = m_Items[m_nSelStart]->bSelected;
- m_Items[m_nSelected]->bSelected = m_Items[m_nSelStart]->bSelected;
- // If m_nSelStart and m_nSelected are not the same,
- // the user has dragged the mouse to make a selection.
- // Notify the application of this.
- if( m_nSelStart != m_nSelected )
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION_END, true, this );
- }
- return false;
- }
- case WM_MOUSEMOVE:
- if( m_bDrag )
- {
- // Compute the index of the item below cursor
- int nItem;
- if( m_nTextHeight )
- nItem = m_ScrollBar.GetTrackPos() + ( pt.y - m_rcText.top ) / m_nTextHeight;
- else
- nItem = -1;
- // Only proceed if the cursor is on top of an item.
- if( nItem >= (int)m_ScrollBar.GetTrackPos() &&
- nItem < (int)m_Items.GetSize() &&
- nItem < m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() )
- {
- m_nSelected = nItem;
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- } else
- if( nItem < (int)m_ScrollBar.GetTrackPos() )
- {
- // User drags the mouse above window top
- m_ScrollBar.Scroll( -1 );
- m_nSelected = m_ScrollBar.GetTrackPos();
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- } else
- if( nItem >= m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() )
- {
- // User drags the mouse below window bottom
- m_ScrollBar.Scroll( 1 );
- m_nSelected = __min( (int)m_Items.GetSize(), m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() ) - 1;
- m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
- }
- }
- break;
- case WM_MOUSEWHEEL:
- {
- UINT uLines;
- SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &uLines, 0 );
- int nScrollAmount = int((short)HIWORD(wParam)) / WHEEL_DELTA * uLines;
- m_ScrollBar.Scroll( -nScrollAmount );
- return true;
- }
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTListBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( WM_CAPTURECHANGED == uMsg )
- {
- // The application just lost mouse capture. We may not have gotten
- // the WM_MOUSEUP message, so reset m_bDrag here.
- if( (HWND)lParam != DXUTGetHWND() )
- m_bDrag = false;
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTListBox::Render( IDirect3DDevice9* pd3dDevice, float fElapsedTime )
- {
- if( m_bVisible == false )
- return;
- CDXUTElement* pElement = m_Elements.GetAt( 0 );
- pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
- pElement->FontColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
- CDXUTElement* pSelElement = m_Elements.GetAt( 1 );
- pSelElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
- pSelElement->FontColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
- m_pDialog->DrawSprite( pElement, &m_rcBoundingBox );
- // Render the text
- if( m_Items.GetSize() > 0 )
- {
- // Find out the height of a single line of text
- RECT rc = m_rcText;
- RECT rcSel = m_rcSelection;
- rc.bottom = rc.top + m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight;
- // Update the line height formation
- m_nTextHeight = rc.bottom - rc.top;
- static bool bSBInit;
- if( !bSBInit )
- {
- // Update the page size of the scroll bar
- if( m_nTextHeight )
- m_ScrollBar.SetPageSize( RectHeight( m_rcText ) / m_nTextHeight );
- else
- m_ScrollBar.SetPageSize( RectHeight( m_rcText ) );
- bSBInit = true;
- }
- rc.right = m_rcText.right;
- for( int i = m_ScrollBar.GetTrackPos(); i < (int)m_Items.GetSize(); ++i )
- {
- if( rc.bottom > m_rcText.bottom )
- break;
- DXUTListBoxItem *pItem = m_Items.GetAt( i );
- // Determine if we need to render this item with the
- // selected element.
- bool bSelectedStyle = false;
- if( !( m_dwStyle & MULTISELECTION ) && i == m_nSelected )
- bSelectedStyle = true;
- else
- if( m_dwStyle & MULTISELECTION )
- {
- if( m_bDrag &&
- ( ( i >= m_nSelected && i < m_nSelStart ) ||
- ( i <= m_nSelected && i > m_nSelStart ) ) )
- bSelectedStyle = m_Items[m_nSelStart]->bSelected;
- else
- if( pItem->bSelected )
- bSelectedStyle = true;
- }
- if( bSelectedStyle )
- {
- rcSel.top = rc.top; rcSel.bottom = rc.bottom;
- m_pDialog->DrawSprite( pSelElement, &rcSel );
- m_pDialog->DrawText( pItem->strText, pSelElement, &rc );
- }
- else
- m_pDialog->DrawText( pItem->strText, pElement, &rc );
- OffsetRect( &rc, 0, m_nTextHeight );
- }
- }
- // Render the scroll bar
- m_ScrollBar.Render( pd3dDevice, fElapsedTime );
- }
- // Static member initialization
- HINSTANCE CUniBuffer::s_hDll = NULL;
- HRESULT (WINAPI *CUniBuffer::_ScriptApplyDigitSubstitution)( const SCRIPT_DIGITSUBSTITUTE*, SCRIPT_CONTROL*, SCRIPT_STATE* ) = Dummy_ScriptApplyDigitSubstitution;
- HRESULT (WINAPI *CUniBuffer::_ScriptStringAnalyse)( HDC, const void *, int, int, int, DWORD, int, SCRIPT_CONTROL*, SCRIPT_STATE*, const int*, SCRIPT_TABDEF*, const BYTE*, SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringAnalyse;
- HRESULT (WINAPI *CUniBuffer::_ScriptStringCPtoX)( SCRIPT_STRING_ANALYSIS, int, BOOL, int* ) = Dummy_ScriptStringCPtoX;
- HRESULT (WINAPI *CUniBuffer::_ScriptStringXtoCP)( SCRIPT_STRING_ANALYSIS, int, int*, int* ) = Dummy_ScriptStringXtoCP;
- HRESULT (WINAPI *CUniBuffer::_ScriptStringFree)( SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringFree;
- const SCRIPT_LOGATTR* (WINAPI *CUniBuffer::_ScriptString_pLogAttr)( SCRIPT_STRING_ANALYSIS ) = Dummy_ScriptString_pLogAttr;
- const int* (WINAPI *CUniBuffer::_ScriptString_pcOutChars)( SCRIPT_STRING_ANALYSIS ) = Dummy_ScriptString_pcOutChars;
- bool CDXUTEditBox::s_bHideCaret; // If true, we don't render the caret.
- //--------------------------------------------------------------------------------------
- // CDXUTEditBox class
- //--------------------------------------------------------------------------------------
- // When scrolling, EDITBOX_SCROLLEXTENT is reciprocal of the amount to scroll.
- // If EDITBOX_SCROLLEXTENT = 4, then we scroll 1/4 of the control each time.
- #define EDITBOX_SCROLLEXTENT 4
- //--------------------------------------------------------------------------------------
- CDXUTEditBox::CDXUTEditBox( CDXUTDialog *pDialog )
- {
- m_Type = DXUT_CONTROL_EDITBOX;
- m_pDialog = pDialog;
- m_nBorder = 5; // Default border width
- m_nSpacing = 4; // Default spacing
- m_bCaretOn = true;
- m_dfBlink = GetCaretBlinkTime() * 0.001f;
- m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime();
- s_bHideCaret = false;
- m_nFirstVisible = 0;
- m_TextColor = D3DCOLOR_ARGB( 255, 16, 16, 16 );
- m_SelTextColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
- m_SelBkColor = D3DCOLOR_ARGB( 255, 40, 50, 92 );
- m_CaretColor = D3DCOLOR_ARGB( 255, 0, 0, 0 );
- m_nCaret = m_nSelStart = 0;
- m_bInsertMode = true;
- m_bMouseDrag = false;
- }
- //--------------------------------------------------------------------------------------
- CDXUTEditBox::~CDXUTEditBox()
- {
- }
- //--------------------------------------------------------------------------------------
- // PlaceCaret: Set the caret to a character position, and adjust the scrolling if
- // necessary.
- //--------------------------------------------------------------------------------------
- void CDXUTEditBox::PlaceCaret( int nCP )
- {
- assert( nCP >= 0 && nCP <= m_Buffer.GetTextSize() );
- m_nCaret = nCP;
- // Obtain the X offset of the character.
- int nX1st, nX, nX2;
- m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // 1st visible char
- m_Buffer.CPtoX( nCP, FALSE, &nX ); // LEAD
- // If nCP is the NULL terminator, get the leading edge instead of trailing.
- if( nCP == m_Buffer.GetTextSize() )
- nX2 = nX;
- else
- m_Buffer.CPtoX( nCP, TRUE, &nX2 ); // TRAIL
- // If the left edge of the char is smaller than the left edge of the 1st visible char,
- // we need to scroll left until this char is visible.
- if( nX < nX1st )
- {
- // Simply make the first visible character the char at the new caret position.
- m_nFirstVisible = nCP;
- }
- else
- // If the right of the character is bigger than the offset of the control's
- // right edge, we need to scroll right to this character.
- if( nX2 > nX1st + RectWidth( m_rcText ) )
- {
- // Compute the X of the new left-most pixel
- int nXNewLeft = nX2 - RectWidth( m_rcText );
- // Compute the char position of this character
- int nCPNew1st, nNewTrail;
- m_Buffer.XtoCP( nXNewLeft, &nCPNew1st, &nNewTrail );
- // If this coordinate is not on a character border,
- // start from the next character so that the caret
- // position does not fall outside the text rectangle.
- int nXNew1st;
- m_Buffer.CPtoX( nCPNew1st, FALSE, &nXNew1st );
- if( nXNew1st < nXNewLeft )
- ++nCPNew1st;
- m_nFirstVisible = nCPNew1st;
- }
- }
- //--------------------------------------------------------------------------------------
- void CDXUTEditBox::ClearText()
- {
- m_Buffer.Clear();
- m_nFirstVisible = 0;
- PlaceCaret( 0 );
- m_nSelStart = 0;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTEditBox::SetText( LPCWSTR wszText, bool bSelected )
- {
- assert( wszText != NULL );
- m_Buffer.SetText( wszText );
- m_nFirstVisible = 0;
- // Move the caret to the end of the text
- PlaceCaret( m_Buffer.GetTextSize() );
- m_nSelStart = bSelected ? 0 : m_nCaret;
- }
- //--------------------------------------------------------------------------------------
- HRESULT CDXUTEditBox::GetTextCopy( LPWSTR strDest, UINT bufferCount )
- {
- assert( strDest );
- StringCchCopy( strDest, bufferCount, m_Buffer.GetBuffer() );
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTEditBox::DeleteSelectionText()
- {
- int nFirst = __min( m_nCaret, m_nSelStart );
- int nLast = __max( m_nCaret, m_nSelStart );
- // Update caret and selection
- PlaceCaret( nFirst );
- m_nSelStart = m_nCaret;
- // Remove the characters
- for( int i = nFirst; i < nLast; ++i )
- m_Buffer.RemoveChar( nFirst );
- }
- //--------------------------------------------------------------------------------------
- void CDXUTEditBox::UpdateRects()
- {
- CDXUTControl::UpdateRects();
- // Update the text rectangle
- m_rcText = m_rcBoundingBox;
- // First inflate by m_nBorder to compute render rects
- InflateRect( &m_rcText, -m_nBorder, -m_nBorder );
- // Update the render rectangles
- m_rcRender[0] = m_rcText;
- SetRect( &m_rcRender[1], m_rcBoundingBox.left, m_rcBoundingBox.top, m_rcText.left, m_rcText.top );
- SetRect( &m_rcRender[2], m_rcText.left, m_rcBoundingBox.top, m_rcText.right, m_rcText.top );
- SetRect( &m_rcRender[3], m_rcText.right, m_rcBoundingBox.top, m_rcBoundingBox.right, m_rcText.top );
- SetRect( &m_rcRender[4], m_rcBoundingBox.left, m_rcText.top, m_rcText.left, m_rcText.bottom );
- SetRect( &m_rcRender[5], m_rcText.right, m_rcText.top, m_rcBoundingBox.right, m_rcText.bottom );
- SetRect( &m_rcRender[6], m_rcBoundingBox.left, m_rcText.bottom, m_rcText.left, m_rcBoundingBox.bottom );
- SetRect( &m_rcRender[7], m_rcText.left, m_rcText.bottom, m_rcText.right, m_rcBoundingBox.bottom );
- SetRect( &m_rcRender[8], m_rcText.right, m_rcText.bottom, m_rcBoundingBox.right, m_rcBoundingBox.bottom );
- // Inflate further by m_nSpacing
- InflateRect( &m_rcText, -m_nSpacing, -m_nSpacing );
- }
- void CDXUTEditBox::CopyToClipboard()
- {
- // Copy the selection text to the clipboard
- if( m_nCaret != m_nSelStart && OpenClipboard( NULL ) )
- {
- EmptyClipboard();
- HGLOBAL hBlock = GlobalAlloc( GMEM_MOVEABLE, sizeof(WCHAR) * ( m_Buffer.GetTextSize() + 1 ) );
- if( hBlock )
- {
- WCHAR *pwszText = (WCHAR*)GlobalLock( hBlock );
- if( pwszText )
- {
- int nFirst = __min( m_nCaret, m_nSelStart );
- int nLast = __max( m_nCaret, m_nSelStart );
- if( nLast - nFirst > 0 )
- CopyMemory( pwszText, m_Buffer.GetBuffer() + nFirst, (nLast - nFirst) * sizeof(WCHAR) );
- pwszText[nLast - nFirst] = L' '; // Terminate it
- GlobalUnlock( hBlock );
- }
- SetClipboardData( CF_UNICODETEXT, hBlock );
- }
- CloseClipboard();
- // We must not free the object until CloseClipboard is called.
- if( hBlock )
- GlobalFree( hBlock );
- }
- }
- void CDXUTEditBox::PasteFromClipboard()
- {
- DeleteSelectionText();
- if( OpenClipboard( NULL ) )
- {
- HANDLE handle = GetClipboardData( CF_UNICODETEXT );
- if( handle )
- {
- // Convert the ANSI string to Unicode, then
- // insert to our buffer.
- WCHAR *pwszText = (WCHAR*)GlobalLock( handle );
- if( pwszText )
- {
- // Copy all characters up to null.
- if( m_Buffer.InsertString( m_nCaret, pwszText ) )
- PlaceCaret( m_nCaret + lstrlenW( pwszText ) );
- m_nSelStart = m_nCaret;
- GlobalUnlock( handle );
- }
- }
- CloseClipboard();
- }
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTEditBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- bool bHandled = false;
- switch( uMsg )
- {
- case WM_KEYDOWN:
- {
- switch( wParam )
- {
- case VK_TAB:
- // We don't process Tab in case keyboard input is enabled and the user
- // wishes to Tab to other controls.
- break;
- case VK_HOME:
- PlaceCaret( 0 );
- if( GetKeyState( VK_SHIFT ) >= 0 )
- // Shift is not down. Update selection
- // start along with the caret.
- m_nSelStart = m_nCaret;
- ResetCaretBlink();
- bHandled = true;
- break;
- case VK_END:
- PlaceCaret( m_Buffer.GetTextSize() );
- if( GetKeyState( VK_SHIFT ) >= 0 )
- // Shift is not down. Update selection
- // start along with the caret.
- m_nSelStart = m_nCaret;
- ResetCaretBlink();
- bHandled = true;
- break;
- case VK_INSERT:
- if( GetKeyState( VK_CONTROL ) < 0 )
- {
- // Control Insert. Copy to clipboard
- CopyToClipboard();
- } else
- if( GetKeyState( VK_SHIFT ) < 0 )
- {
- // Shift Insert. Paste from clipboard
- PasteFromClipboard();
- } else
- {
- // Toggle caret insert mode
- m_bInsertMode = !m_bInsertMode;
- }
- break;
- case VK_DELETE:
- // Check if there is a text selection.
- if( m_nCaret != m_nSelStart )
- {
- DeleteSelectionText();
- m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
- }
- else
- {
- // Deleting one character
- if( m_Buffer.RemoveChar( m_nCaret ) )
- m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
- }
- ResetCaretBlink();
- bHandled = true;
- break;
- case VK_LEFT:
- if( GetKeyState( VK_CONTROL ) < 0 )
- {
- // Control is down. Move the caret to a new item
- // instead of a character.
- m_Buffer.GetPriorItemPos( m_nCaret, &m_nCaret );
- PlaceCaret( m_nCaret );
- }
- else
- if( m_nCaret > 0 )
- PlaceCaret( m_nCaret - 1 );
- if( GetKeyState( VK_SHIFT ) >= 0 )
- // Shift is not down. Update selection
- // start along with the caret.
- m_nSelStart = m_nCaret;
- ResetCaretBlink();
- bHandled = true;
- break;
- case VK_RIGHT:
- if( GetKeyState( VK_CONTROL ) < 0 )
- {
- // Control is down. Move the caret to a new item
- // instead of a character.
- m_Buffer.GetNextItemPos( m_nCaret, &m_nCaret );
- PlaceCaret( m_nCaret );
- }
- else
- if( m_nCaret < m_Buffer.GetTextSize() )
- PlaceCaret( m_nCaret + 1 );
- if( GetKeyState( VK_SHIFT ) >= 0 )
- // Shift is not down. Update selection
- // start along with the caret.
- m_nSelStart = m_nCaret;
- ResetCaretBlink();
- bHandled = true;
- break;
- case VK_UP:
- case VK_DOWN:
- // Trap up and down arrows so that the dialog
- // does not switch focus to another control.
- bHandled = true;
- break;
- default:
- bHandled = wParam != VK_ESCAPE; // Let the application handle Esc.
- }
- }
- }
- return bHandled;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTEditBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- {
- if( !m_bHasFocus )
- m_pDialog->RequestFocus( this );
- if( !ContainsPoint( pt ) )
- return false;
- m_bMouseDrag = true;
- SetCapture( DXUTGetHWND() );
- // Determine the character corresponding to the coordinates.
- int nCP, nTrail, nX1st;
- m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // X offset of the 1st visible char
- if( SUCCEEDED( m_Buffer.XtoCP( pt.x - m_rcText.left + nX1st, &nCP, &nTrail ) ) )
- {
- // Cap at the NULL character.
- 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 )
- {
- // Determine the character corresponding to the coordinates.
- int nCP, nTrail, nX1st;
- m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // X offset of the 1st visible char
- if( SUCCEEDED( m_Buffer.XtoCP( pt.x - m_rcText.left + nX1st, &nCP, &nTrail ) ) )
- {
- // Cap at the NULL character.
- if( nTrail && nCP < m_Buffer.GetTextSize() )
- PlaceCaret( nCP + 1 );
- else
- PlaceCaret( nCP );
- }
- }
- break;
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTEditBox::OnFocusIn()
- {
- CDXUTControl::OnFocusIn();
- ResetCaretBlink();
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if( !m_bEnabled || !m_bVisible )
- return false;
- switch( uMsg )
- {
- // Make sure that while editing, the keyup and keydown messages associated with
- // WM_CHAR messages don't go to any non-focused controls or cameras
- case WM_KEYUP:
- case WM_KEYDOWN:
- return true;
- case WM_CHAR:
- {
- switch( (WCHAR)wParam )
- {
- // Backspace
- case VK_BACK:
- {
- // If there's a selection, treat this
- // like a delete key.
- if( m_nCaret != m_nSelStart )
- {
- DeleteSelectionText();
- m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
- }
- else
- if( m_nCaret > 0 )
- {
- // Move the caret, then delete the char.
- PlaceCaret( m_nCaret - 1 );
- m_nSelStart = m_nCaret;
- m_Buffer.RemoveChar( m_nCaret );
- m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
- }
- ResetCaretBlink();
- break;
- }
- case 24: // Ctrl-X Cut
- case VK_CANCEL: // Ctrl-C Copy
- {
- CopyToClipboard();
- // If the key is Ctrl-X, delete the selection too.
- if( (WCHAR)wParam == 24 )
- {
- DeleteSelectionText();
- m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
- }
- break;
- }
- // Ctrl-V Paste
- case 22:
- {
- PasteFromClipboard();
- m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
- break;
- }
- // Ctrl-A Select All
- case 1:
- if( m_nSelStart == m_nCaret )
- {
- m_nSelStart = 0;
- PlaceCaret( m_Buffer.GetTextSize() );
- }
- break;
- case VK_RETURN: