diff options
| author | Jason Maskell <[email protected]> | 2016-05-16 15:00:36 +0200 |
|---|---|---|
| committer | Jason Maskell <[email protected]> | 2016-05-16 15:00:36 +0200 |
| commit | 3eb017d032e0c542401ea202f7a62b7c7ddcd498 (patch) | |
| tree | 6470077bdc344f1493778976917f7217a3159707 /test/d3d11/common/DXUTgui.cpp | |
| parent | Project now compiles with Cmake. (diff) | |
| download | waveworks_archive-3eb017d032e0c542401ea202f7a62b7c7ddcd498.tar.xz waveworks_archive-3eb017d032e0c542401ea202f7a62b7c7ddcd498.zip | |
Added the test_d3d11 app to the solution. Not compiling yet, mostly a paranoia commit.
Diffstat (limited to 'test/d3d11/common/DXUTgui.cpp')
| -rw-r--r-- | test/d3d11/common/DXUTgui.cpp | 7241 |
1 files changed, 0 insertions, 7241 deletions
diff --git a/test/d3d11/common/DXUTgui.cpp b/test/d3d11/common/DXUTgui.cpp deleted file mode 100644 index 65d7c08..0000000 --- a/test/d3d11/common/DXUTgui.cpp +++ /dev/null @@ -1,7241 +0,0 @@ -//-------------------------------------------------------------------------------------- -// File: DXUTgui.cpp -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- -#include "DXUT.h" -#include "DXUTgui.h" -#include "DXUTsettingsDlg.h" -#include "DXUTres.h" - -#include "SDKMisc.h" - -#undef min // use __min instead -#undef max // use __max instead - -#ifndef WM_XBUTTONDOWN -#define WM_XBUTTONDOWN 0x020B // (not always defined) -#endif -#ifndef WM_XBUTTONUP -#define WM_XBUTTONUP 0x020C // (not always defined) -#endif -#ifndef WM_MOUSEWHEEL -#define WM_MOUSEWHEEL 0x020A // (not always defined) -#endif -#ifndef WHEEL_DELTA -#define WHEEL_DELTA 120 // (not always defined) -#endif - -// Minimum scroll bar thumb size -#define SCROLLBAR_MINTHUMBSIZE 8 - -// Delay and repeat period when clicking on the scroll bar arrows -#define SCROLLBAR_ARROWCLICK_DELAY 0.33 -#define SCROLLBAR_ARROWCLICK_REPEAT 0.05 - -#define DXUT_NEAR_BUTTON_DEPTH 0.6f -#define DXUT_FAR_BUTTON_DEPTH 0.8f - -#define DXUT_MAX_GUI_SPRITES 500 - -D3DCOLORVALUE D3DCOLOR_TO_D3DCOLORVALUE( D3DCOLOR c ) -{ - D3DCOLORVALUE cv = - { - ( ( c >> 16 ) & 0xFF ) / 255.0f, - ( ( c >> 8 ) & 0xFF ) / 255.0f, - ( c & 0xFF ) / 255.0f, - ( ( c >> 24 ) & 0xFF ) / 255.0f - }; - return cv; -} - -#define UNISCRIBE_DLLNAME L"usp10.dll" - -#define GETPROCADDRESS( Module, APIName, Temp ) \ - Temp = GetProcAddress( Module, #APIName ); \ - if( Temp ) \ - *(FARPROC*)&_##APIName = Temp - -#define PLACEHOLDERPROC( APIName ) \ - _##APIName = Dummy_##APIName - -#define IMM32_DLLNAME L"imm32.dll" -#define VER_DLLNAME L"version.dll" - -CHAR g_strUIEffectFile[] = \ - "Texture2D g_Texture;"\ - ""\ - "SamplerState Sampler"\ - "{"\ - " Filter = MIN_MAG_MIP_LINEAR;"\ - " AddressU = Wrap;"\ - " AddressV = Wrap;"\ - "};"\ - ""\ - "BlendState UIBlend"\ - "{"\ - " AlphaToCoverageEnable = FALSE;"\ - " BlendEnable[0] = TRUE;"\ - " SrcBlend = SRC_ALPHA;"\ - " DestBlend = INV_SRC_ALPHA;"\ - " BlendOp = ADD;"\ - " SrcBlendAlpha = ONE;"\ - " DestBlendAlpha = ZERO;"\ - " BlendOpAlpha = ADD;"\ - " RenderTargetWriteMask[0] = 0x0F;"\ - "};"\ - ""\ - "BlendState NoBlending"\ - "{"\ - " BlendEnable[0] = FALSE;"\ - " RenderTargetWriteMask[0] = 0x0F;"\ - "};"\ - ""\ - "DepthStencilState DisableDepth"\ - "{"\ - " DepthEnable = false;"\ - "};"\ - "DepthStencilState EnableDepth"\ - "{"\ - " DepthEnable = true;"\ - "};"\ - "struct VS_OUTPUT"\ - "{"\ - " float4 Pos : POSITION;"\ - " float4 Dif : COLOR;"\ - " float2 Tex : TEXCOORD;"\ - "};"\ - ""\ - "VS_OUTPUT VS( float3 vPos : POSITION,"\ - " float4 Dif : COLOR,"\ - " float2 vTexCoord0 : TEXCOORD )"\ - "{"\ - " VS_OUTPUT Output;"\ - ""\ - " Output.Pos = float4( vPos, 1.0f );"\ - " Output.Dif = Dif;"\ - " Output.Tex = vTexCoord0;"\ - ""\ - " return Output;"\ - "}"\ - ""\ - "float4 PS( VS_OUTPUT In ) : SV_Target"\ - "{"\ - " return g_Texture.Sample( Sampler, In.Tex ) * In.Dif;"\ - "}"\ - ""\ - "float4 PSUntex( VS_OUTPUT In ) : SV_Target"\ - "{"\ - " return In.Dif;"\ - "}"\ - ""\ - "technique10 RenderUI"\ - "{"\ - " pass P0"\ - " {"\ - " SetVertexShader( CompileShader( vs_4_0, VS() ) );"\ - " SetGeometryShader( NULL );"\ - " SetPixelShader( CompileShader( ps_4_0, PS() ) );"\ - " SetDepthStencilState( DisableDepth, 0 );"\ - " SetBlendState( UIBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\ - " }"\ - "}"\ - "technique10 RenderUIUntex"\ - "{"\ - " pass P0"\ - " {"\ - " SetVertexShader( CompileShader( vs_4_0, VS() ) );"\ - " SetGeometryShader( NULL );"\ - " SetPixelShader( CompileShader( ps_4_0, PSUntex() ) );"\ - " SetDepthStencilState( DisableDepth, 0 );"\ - " SetBlendState( UIBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\ - " }"\ - "}"\ - "technique10 RestoreState"\ - "{"\ - " pass P0"\ - " {"\ - " SetDepthStencilState( EnableDepth, 0 );"\ - " SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\ - " }"\ - "}"; -const UINT g_uUIEffectFileSize = sizeof( g_strUIEffectFile ); - - -// DXUT_MAX_EDITBOXLENGTH is the maximum string length allowed in edit boxes, -// including the NULL terminator. -// -// Uniscribe does not support strings having bigger-than-16-bits length. -// This means that the string must be less than 65536 characters long, -// including the NULL terminator. -#define DXUT_MAX_EDITBOXLENGTH 0xFFFF - - -double CDXUTDialog::s_fTimeRefresh = 0.0f; -CDXUTControl* CDXUTDialog::s_pControlFocus = NULL; // The control which has focus -CDXUTControl* CDXUTDialog::s_pControlPressed = NULL; // The control currently pressed - - -struct DXUT_SCREEN_VERTEX -{ - float x, y, z, h; - D3DCOLOR color; - float tu, tv; - - static DWORD FVF; -}; -DWORD DXUT_SCREEN_VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1; - - -struct DXUT_SCREEN_VERTEX_UNTEX -{ - float x, y, z, h; - D3DCOLOR color; - - static DWORD FVF; -}; -DWORD DXUT_SCREEN_VERTEX_UNTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE; - - -struct DXUT_SCREEN_VERTEX_10 -{ - float x, y, z; - D3DCOLORVALUE color; - float tu, tv; -}; - - -inline int RectWidth( RECT& rc ) -{ - return ( ( rc ).right - ( rc ).left ); -} -inline int RectHeight( RECT& rc ) -{ - return ( ( rc ).bottom - ( rc ).top ); -} - - -HRESULT InitFont11( ID3D11Device* pd3d11Device, ID3D11InputLayout* pInputLayout ); -void EndFont11(); - -//-------------------------------------------------------------------------------------- -// CDXUTDialog class -//-------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------- -CDXUTDialog::CDXUTDialog() -{ - m_x = 0; - m_y = 0; - m_width = 0; - m_height = 0; - - m_pManager = NULL; - m_bVisible = true; - m_bCaption = false; - m_bMinimized = false; - m_bDrag = false; - m_wszCaption[0] = L'\0'; - m_nCaptionHeight = 18; - - m_colorTopLeft = 0; - m_colorTopRight = 0; - m_colorBottomLeft = 0; - m_colorBottomRight = 0; - - m_pCallbackEvent = NULL; - m_pCallbackEventUserContext = NULL; - - m_fTimeLastRefresh = 0; - - m_pControlMouseOver = NULL; - - m_pNextDialog = this; - m_pPrevDialog = this; - - m_nDefaultControlID = 0xffff; - m_bNonUserEvents = false; - m_bKeyboardInput = false; - m_bMouseInput = true; -} - - -//-------------------------------------------------------------------------------------- -CDXUTDialog::~CDXUTDialog() -{ - int i = 0; - - RemoveAllControls(); - - m_Fonts.RemoveAll(); - m_Textures.RemoveAll(); - - for( i = 0; i < m_DefaultElements.GetSize(); i++ ) - { - DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); - SAFE_DELETE( pElementHolder ); - } - - m_DefaultElements.RemoveAll(); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog ) -{ - m_pManager = pManager; - if( bRegisterDialog ) - pManager->RegisterDialog( this ); - - SetTexture( 0, MAKEINTRESOURCE( 0xFFFF ), ( HMODULE )0xFFFF ); - InitDefaultElements(); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, LPCWSTR pszControlTextureFilename ) -{ - m_pManager = pManager; - if( bRegisterDialog ) - pManager->RegisterDialog( this ); - SetTexture( 0, pszControlTextureFilename ); - InitDefaultElements(); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, - LPCWSTR szControlTextureResourceName, HMODULE hControlTextureResourceModule ) -{ - m_pManager = pManager; - if( bRegisterDialog ) - pManager->RegisterDialog( this ); - - SetTexture( 0, szControlTextureResourceName, hControlTextureResourceModule ); - InitDefaultElements(); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::SetCallback( PCALLBACKDXUTGUIEVENT pCallback, void* pUserContext ) -{ - // If this assert triggers, you need to call CDXUTDialog::Init() first. This change - // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The - // creation and interfacing with CDXUTDialogResourceManager is now the responsibility - // of the application if it wishes to use DXUT's GUI. - assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first. See comments for details." ); - - m_pCallbackEvent = pCallback; - m_pCallbackEventUserContext = pUserContext; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::RemoveControl( int ID ) -{ - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - if( pControl->GetID() == ID ) - { - // Clean focus first - ClearFocus(); - - // Clear references to this control - if( s_pControlFocus == pControl ) - s_pControlFocus = NULL; - if( s_pControlPressed == pControl ) - s_pControlPressed = NULL; - if( m_pControlMouseOver == pControl ) - m_pControlMouseOver = NULL; - - SAFE_DELETE( pControl ); - m_Controls.Remove( i ); - - return; - } - } -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::RemoveAllControls() -{ - if( s_pControlFocus && s_pControlFocus->m_pDialog == this ) - s_pControlFocus = NULL; - if( s_pControlPressed && s_pControlPressed->m_pDialog == this ) - s_pControlPressed = NULL; - m_pControlMouseOver = NULL; - - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - SAFE_DELETE( pControl ); - } - - m_Controls.RemoveAll(); -} - - -//-------------------------------------------------------------------------------------- -CDXUTDialogResourceManager::CDXUTDialogResourceManager() -{ - // Begin D3D9-specific - m_pd3d9Device = NULL; - m_pStateBlock = NULL; - m_pSprite = NULL; - - // Begin D3D11-specific - // Shaders - m_pVSRenderUI11 = NULL; - m_pPSRenderUI11 = NULL; - m_pPSRenderUIUntex11 = NULL; - - // States - m_pDepthStencilStateUI11 = NULL; - m_pRasterizerStateUI11 = NULL; - m_pBlendStateUI11 = NULL; - m_pSamplerStateUI11 = NULL; - m_pDepthStencilStateStored11 = NULL; - m_pRasterizerStateStored11 = NULL; - m_pBlendStateStored11 = NULL; - m_pSamplerStateStored11 = NULL; - - m_pInputLayout11 = NULL; - m_pVBScreenQuad11 = NULL; - m_pSpriteBuffer11 = NULL; -} - - -//-------------------------------------------------------------------------------------- -CDXUTDialogResourceManager::~CDXUTDialogResourceManager() -{ - int i; - for( i = 0; i < m_FontCache.GetSize(); i++ ) - { - DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); - SAFE_DELETE( pFontNode ); - } - m_FontCache.RemoveAll(); - - for( i = 0; i < m_TextureCache.GetSize(); i++ ) - { - DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); - SAFE_DELETE( pTextureNode ); - } - m_TextureCache.RemoveAll(); - - CUniBuffer::Uninitialize(); -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialogResourceManager::OnD3D9CreateDevice( LPDIRECT3DDEVICE9 pd3dDevice ) -{ - HRESULT hr = S_OK; - int i = 0; - - m_pd3d9Device = pd3dDevice; - - for( i = 0; i < m_FontCache.GetSize(); i++ ) - { - hr = CreateFont9( i ); - if( FAILED( hr ) ) - return hr; - } - - for( i = 0; i < m_TextureCache.GetSize(); i++ ) - { - hr = CreateTexture9( i ); - if( FAILED( hr ) ) - return hr; - } - - hr = D3DXCreateSprite( pd3dDevice, &m_pSprite ); - if( FAILED( hr ) ) - return DXUT_ERR( L"D3DXCreateSprite", hr ); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialogResourceManager::OnD3D9ResetDevice() -{ - HRESULT hr = S_OK; - - for( int i = 0; i < m_FontCache.GetSize(); i++ ) - { - DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); - - if( pFontNode->pFont9 ) - pFontNode->pFont9->OnResetDevice(); - } - - if( m_pSprite ) - m_pSprite->OnResetDevice(); - - V_RETURN( m_pd3d9Device->CreateStateBlock( D3DSBT_ALL, &m_pStateBlock ) ); - - return S_OK; -} - -//-------------------------------------------------------------------------------------- -bool CDXUTDialogResourceManager::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) -{ - return false; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::OnD3D9LostDevice() -{ - for( int i = 0; i < m_FontCache.GetSize(); i++ ) - { - DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); - - if( pFontNode->pFont9 ) - pFontNode->pFont9->OnLostDevice(); - } - - if( m_pSprite ) - m_pSprite->OnLostDevice(); - - SAFE_RELEASE( m_pStateBlock ); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::OnD3D9DestroyDevice() -{ - int i = 0; - - m_pd3d9Device = NULL; - - // Release the resources but don't clear the cache, as these will need to be - // recreated if the device is recreated - for( i = 0; i < m_FontCache.GetSize(); i++ ) - { - DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); - SAFE_RELEASE( pFontNode->pFont9 ); - } - - for( i = 0; i < m_TextureCache.GetSize(); i++ ) - { - DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); - SAFE_RELEASE( pTextureNode->pTexture9 ); - } - - SAFE_RELEASE( m_pSprite ); -} - - - -HRESULT CDXUTDialogResourceManager::OnD3D11CreateDevice( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext ) -{ - m_pd3d11Device = pd3dDevice; - m_pd3d11DeviceContext = pd3d11DeviceContext; - - HRESULT hr = S_OK; - - // Compile Shaders - ID3DBlob* pVSBlob = NULL; - ID3DBlob* pPSBlob = NULL; - ID3DBlob* pPSUntexBlob = NULL; - V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "VS", "vs_4_0_level_9_1", - D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pVSBlob, NULL ) ); - V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "PS", "ps_4_0_level_9_1", - D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pPSBlob, NULL ) ); - V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "PSUntex", "ps_4_0_level_9_1", - D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pPSUntexBlob, NULL ) ); -//D3D10_SHADER_ENABLE_STRICTNESS - - // Create Shaders - V_RETURN( pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &m_pVSRenderUI11 ) ); - V_RETURN( pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &m_pPSRenderUI11 ) ); - V_RETURN( pd3dDevice->CreatePixelShader( pPSUntexBlob->GetBufferPointer(), pPSUntexBlob->GetBufferSize(), NULL, &m_pPSRenderUIUntex11 ) ); - - // States - D3D11_DEPTH_STENCIL_DESC DSDesc; - ZeroMemory( &DSDesc, sizeof( D3D11_DEPTH_STENCIL_DESC ) ); - DSDesc.DepthEnable = FALSE; - DSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - DSDesc.DepthFunc = D3D11_COMPARISON_LESS; - DSDesc.StencilEnable = FALSE; - V_RETURN( pd3dDevice->CreateDepthStencilState( &DSDesc, &m_pDepthStencilStateUI11 ) ); - - D3D11_RASTERIZER_DESC RSDesc; - RSDesc.AntialiasedLineEnable = FALSE; - RSDesc.CullMode = D3D11_CULL_BACK; - RSDesc.DepthBias = 0; - RSDesc.DepthBiasClamp = 0.0f; - RSDesc.DepthClipEnable = TRUE; - RSDesc.FillMode = D3D11_FILL_SOLID; - RSDesc.FrontCounterClockwise = FALSE; - RSDesc.MultisampleEnable = TRUE; - RSDesc.ScissorEnable = FALSE; - RSDesc.SlopeScaledDepthBias = 0.0f; - V_RETURN( pd3dDevice->CreateRasterizerState( &RSDesc, &m_pRasterizerStateUI11 ) ); - - D3D11_BLEND_DESC BSDesc; - ZeroMemory( &BSDesc, sizeof( D3D11_BLEND_DESC ) ); - - BSDesc.RenderTarget[0].BlendEnable = TRUE; - BSDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - BSDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - BSDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - BSDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - BSDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - BSDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - BSDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; - - V_RETURN( pd3dDevice->CreateBlendState( &BSDesc, &m_pBlendStateUI11 ) ); - - D3D11_SAMPLER_DESC SSDesc; - ZeroMemory( &SSDesc, sizeof( D3D11_SAMPLER_DESC ) ); - SSDesc.Filter = D3D11_FILTER_ANISOTROPIC ; - SSDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - SSDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - SSDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - SSDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; - SSDesc.MaxAnisotropy = 16; - SSDesc.MinLOD = 0; - SSDesc.MaxLOD = D3D11_FLOAT32_MAX; - if ( pd3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3 ) { - SSDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - SSDesc.MaxAnisotropy = 0; - } - V_RETURN( pd3dDevice->CreateSamplerState( &SSDesc, &m_pSamplerStateUI11 ) ); - - // Create the font and texture objects in the cache arrays. - int i = 0; - for( i = 0; i < m_FontCache.GetSize(); i++ ) - { - hr = CreateFont11( i ); - if( FAILED( hr ) ) - return hr; - } - - for( i = 0; i < m_TextureCache.GetSize(); i++ ) - { - hr = CreateTexture11( i ); - if( FAILED( hr ) ) - return hr; - } - - // Create input layout - const D3D11_INPUT_ELEMENT_DESC layout[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - - V_RETURN( pd3dDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &m_pInputLayout11 ) ); - - // Release the blobs - SAFE_RELEASE( pVSBlob ); - SAFE_RELEASE( pPSBlob ); - SAFE_RELEASE( pPSUntexBlob ); - - // Create a vertex buffer quad for rendering later - D3D11_BUFFER_DESC BufDesc; - BufDesc.ByteWidth = sizeof( DXUT_SCREEN_VERTEX_10 ) * 4; - BufDesc.Usage = D3D11_USAGE_DYNAMIC; - BufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - BufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - BufDesc.MiscFlags = 0; - V_RETURN( pd3dDevice->CreateBuffer( &BufDesc, NULL, &m_pVBScreenQuad11 ) ); - - // Init the D3D11 font - InitFont11( pd3dDevice, m_pInputLayout11 ); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialogResourceManager::OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, - const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc ) -{ - HRESULT hr = S_OK; - - m_nBackBufferWidth = pBackBufferSurfaceDesc->Width; - m_nBackBufferHeight = pBackBufferSurfaceDesc->Height; - - return hr; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::OnD3D11ReleasingSwapChain() -{ -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::OnD3D11DestroyDevice() -{ - int i; - - // Release the resources but don't clear the cache, as these will need to be - // recreated if the device is recreated - - for( i = 0; i < m_TextureCache.GetSize(); i++ ) - { - DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); - SAFE_RELEASE( pTextureNode->pTexResView11 ); - SAFE_RELEASE( pTextureNode->pTexture11 ); - } - - // D3D11 - SAFE_RELEASE( m_pVBScreenQuad11 ); - SAFE_RELEASE( m_pSpriteBuffer11 ); - m_SpriteBufferBytes11 = 0; - SAFE_RELEASE( m_pInputLayout11 ); - - // Shaders - SAFE_RELEASE( m_pVSRenderUI11 ); - SAFE_RELEASE( m_pPSRenderUI11 ); - SAFE_RELEASE( m_pPSRenderUIUntex11 ); - - // States - SAFE_RELEASE( m_pDepthStencilStateUI11 ); - SAFE_RELEASE( m_pRasterizerStateUI11 ); - SAFE_RELEASE( m_pBlendStateUI11 ); - SAFE_RELEASE( m_pSamplerStateUI11 ); - - SAFE_RELEASE( m_pDepthStencilStateStored11 ); - SAFE_RELEASE( m_pRasterizerStateStored11 ); - SAFE_RELEASE( m_pBlendStateStored11 ); - SAFE_RELEASE( m_pSamplerStateStored11 ); - - EndFont11(); -} - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::StoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext ) -{ - pd3dImmediateContext->OMGetDepthStencilState( &m_pDepthStencilStateStored11, &m_StencilRefStored11 ); - pd3dImmediateContext->RSGetState( &m_pRasterizerStateStored11 ); - pd3dImmediateContext->OMGetBlendState( &m_pBlendStateStored11, m_BlendFactorStored11, &m_SampleMaskStored11 ); - pd3dImmediateContext->PSGetSamplers( 0, 1, &m_pSamplerStateStored11 ); -} - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::RestoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext ) -{ - pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateStored11, m_StencilRefStored11 ); - pd3dImmediateContext->RSSetState( m_pRasterizerStateStored11 ); - pd3dImmediateContext->OMSetBlendState( m_pBlendStateStored11, m_BlendFactorStored11, m_SampleMaskStored11 ); - pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateStored11 ); - - SAFE_RELEASE( m_pDepthStencilStateStored11 ); - SAFE_RELEASE( m_pRasterizerStateStored11 ); - SAFE_RELEASE( m_pBlendStateStored11 ); - SAFE_RELEASE( m_pSamplerStateStored11 ); -} - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::ApplyRenderUI11( ID3D11DeviceContext* pd3dImmediateContext ) -{ - // Shaders - pd3dImmediateContext->VSSetShader( m_pVSRenderUI11, NULL, 0 ); - pd3dImmediateContext->HSSetShader( NULL, NULL, 0 ); - pd3dImmediateContext->DSSetShader( NULL, NULL, 0 ); - pd3dImmediateContext->GSSetShader( NULL, NULL, 0 ); - pd3dImmediateContext->PSSetShader( m_pPSRenderUI11, NULL, 0 ); - - // States - pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateUI11, 0 ); - pd3dImmediateContext->RSSetState( m_pRasterizerStateUI11 ); - float BlendFactor[4] = { 0, 0, 0, 0 }; - pd3dImmediateContext->OMSetBlendState( m_pBlendStateUI11, BlendFactor, 0xFFFFFFFF ); - pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateUI11 ); -} - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::ApplyRenderUIUntex11( ID3D11DeviceContext* pd3dImmediateContext ) -{ - // Shaders - pd3dImmediateContext->VSSetShader( m_pVSRenderUI11, NULL, 0 ); - pd3dImmediateContext->HSSetShader( NULL, NULL, 0 ); - pd3dImmediateContext->DSSetShader( NULL, NULL, 0 ); - pd3dImmediateContext->GSSetShader( NULL, NULL, 0 ); - pd3dImmediateContext->PSSetShader( m_pPSRenderUIUntex11, NULL, 0 ); - - // States - pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateUI11, 0 ); - pd3dImmediateContext->RSSetState( m_pRasterizerStateUI11 ); - float BlendFactor[4] = { 0, 0, 0, 0 }; - pd3dImmediateContext->OMSetBlendState( m_pBlendStateUI11, BlendFactor, 0xFFFFFFFF ); - pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateUI11 ); -} - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::BeginSprites11( ) -{ - m_SpriteVertices.Reset(); -} - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::EndSprites11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext ) -{ - - // ensure our buffer size can hold our sprites - UINT SpriteDataBytes = m_SpriteVertices.GetSize() * sizeof( DXUTSpriteVertex ); - if( m_SpriteBufferBytes11 < SpriteDataBytes ) - { - SAFE_RELEASE( m_pSpriteBuffer11 ); - m_SpriteBufferBytes11 = SpriteDataBytes; - - D3D11_BUFFER_DESC BufferDesc; - BufferDesc.ByteWidth = m_SpriteBufferBytes11; - BufferDesc.Usage = D3D11_USAGE_DYNAMIC; - BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - BufferDesc.MiscFlags = 0; - - pd3dDevice->CreateBuffer( &BufferDesc, NULL, &m_pSpriteBuffer11 ); - } - - // Copy the sprites over - D3D11_BOX destRegion; - destRegion.left = 0; - destRegion.right = SpriteDataBytes; - destRegion.top = 0; - destRegion.bottom = 1; - destRegion.front = 0; - destRegion.back = 1; - D3D11_MAPPED_SUBRESOURCE MappedResource; - if ( S_OK == pd3dImmediateContext->Map( m_pSpriteBuffer11, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) { - CopyMemory( MappedResource.pData, (void*)m_SpriteVertices.GetData(), SpriteDataBytes ); - pd3dImmediateContext->Unmap(m_pSpriteBuffer11, 0); - } - - // Draw - UINT Stride = sizeof( DXUTSpriteVertex ); - UINT Offset = 0; - pd3dImmediateContext->IASetVertexBuffers( 0, 1, &m_pSpriteBuffer11, &Stride, &Offset ); - pd3dImmediateContext->IASetInputLayout( m_pInputLayout11 ); - pd3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); - pd3dImmediateContext->Draw( m_SpriteVertices.GetSize(), 0 ); - - m_SpriteVertices.Reset(); -} - -//-------------------------------------------------------------------------------------- -bool CDXUTDialogResourceManager::RegisterDialog( CDXUTDialog* pDialog ) -{ - // Check that the dialog isn't already registered. - for( int i = 0; i < m_Dialogs.GetSize(); ++i ) - if( m_Dialogs.GetAt( i ) == pDialog ) - return true; - - // Add to the list. - if( FAILED( m_Dialogs.Add( pDialog ) ) ) - return false; - - // Set up next and prev pointers. - if( m_Dialogs.GetSize() > 1 ) - m_Dialogs[m_Dialogs.GetSize() - 2]->SetNextDialog( pDialog ); - m_Dialogs[m_Dialogs.GetSize() - 1]->SetNextDialog( m_Dialogs[0] ); - - return true; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::UnregisterDialog( CDXUTDialog* pDialog ) -{ - // Search for the dialog in the list. - for( int i = 0; i < m_Dialogs.GetSize(); ++i ) - if( m_Dialogs.GetAt( i ) == pDialog ) - { - m_Dialogs.Remove( i ); - if( m_Dialogs.GetSize() > 0 ) - { - int l, r; - - if( 0 == i ) - l = m_Dialogs.GetSize() - 1; - else - l = i - 1; - - if( m_Dialogs.GetSize() == i ) - r = 0; - else - r = i; - - m_Dialogs[l]->SetNextDialog( m_Dialogs[r] ); - } - return; - } -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialogResourceManager::EnableKeyboardInputForAllDialogs() -{ - // Enable keyboard input for all registered dialogs - for( int i = 0; i < m_Dialogs.GetSize(); ++i ) - m_Dialogs[i]->EnableKeyboardInput( true ); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::Refresh() -{ - if( s_pControlFocus ) - s_pControlFocus->OnFocusOut(); - - if( m_pControlMouseOver ) - m_pControlMouseOver->OnMouseLeave(); - - s_pControlFocus = NULL; - s_pControlPressed = NULL; - m_pControlMouseOver = NULL; - - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - pControl->Refresh(); - } - - if( m_bKeyboardInput ) - FocusDefaultControl(); -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::OnRender( float fElapsedTime ) -{ - if( m_pManager->GetD3D9Device() ) - return OnRender9( fElapsedTime ); - else - return OnRender11( fElapsedTime ); -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::OnRender9( float fElapsedTime ) -{ - // If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside - // the application's device callbacks. See the SDK samples for an example of how to do this. - assert( m_pManager->GetD3D9Device() && m_pManager->m_pStateBlock && - L"To fix hook up CDXUTDialogResourceManager to device callbacks. See comments for details" ); - - // See if the dialog needs to be refreshed - if( m_fTimeLastRefresh < s_fTimeRefresh ) - { - m_fTimeLastRefresh = DXUTGetTime(); - Refresh(); - } - - // For invisible dialog, out now. - if( !m_bVisible || - ( m_bMinimized && !m_bCaption ) ) - return S_OK; - - IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device(); - - // Set up a state block here and restore it when finished drawing all the controls - m_pManager->m_pStateBlock->Capture(); - - //pd3dDevice->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, TRUE); - //pd3dDevice->SetRenderState( D3DRS_SRGBWRITEENABLE, TRUE ); - - pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); - pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); - pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); - pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE ); - pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, FALSE ); - pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD ); - pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | - D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED ); - pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); - pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE ); - pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); - pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); - pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_RESULTARG, D3DTA_CURRENT ); - pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - BOOL bBackgroundIsVisible = ( m_colorTopLeft | m_colorTopRight | m_colorBottomRight | m_colorBottomLeft ) & - 0xff000000; - if( !m_bMinimized && bBackgroundIsVisible ) - { - DXUT_SCREEN_VERTEX_UNTEX vertices[4] = - { - ( float )m_x, ( float )m_y, 0.5f, 1.0f, m_colorTopLeft, - ( float )m_x + m_width, ( float )m_y, 0.5f, 1.0f, m_colorTopRight, - ( float )m_x + m_width, ( float )m_y + m_height, 0.5f, 1.0f, m_colorBottomRight, - ( float )m_x, ( float )m_y + m_height, 0.5f, 1.0f, m_colorBottomLeft, - }; - - pd3dDevice->SetVertexShader( NULL ); - pd3dDevice->SetPixelShader( NULL ); - - pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); - - pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX_UNTEX::FVF ); - pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof( DXUT_SCREEN_VERTEX_UNTEX ) ); - } - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - - pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); - - DXUTTextureNode* pTextureNode = GetTexture( 0 ); - pd3dDevice->SetTexture( 0, pTextureNode->pTexture9 ); - - m_pManager->m_pSprite->Begin( D3DXSPRITE_DONOTSAVESTATE ); - - // Render the caption if it's enabled. - if( m_bCaption ) - { - // DrawSprite will offset the rect down by - // m_nCaptionHeight, so adjust the rect higher - // here to negate the effect. - RECT rc = - { - 0, -m_nCaptionHeight, m_width, 0 - }; - DrawSprite9( &m_CapElement, &rc ); - rc.left += 5; // Make a left margin - WCHAR wszOutput[256]; - wcscpy_s( wszOutput, 256, m_wszCaption ); - if( m_bMinimized ) - wcscat_s( wszOutput, 256, L" (Minimized)" ); - DrawText9( wszOutput, &m_CapElement, &rc, true ); - } - - // If the dialog is minimized, skip rendering - // its controls. - if( !m_bMinimized ) - { - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - - // Focused control is drawn last - if( pControl == s_pControlFocus ) - continue; - - pControl->Render( fElapsedTime ); - } - - if( s_pControlFocus != NULL && s_pControlFocus->m_pDialog == this ) - s_pControlFocus->Render( fElapsedTime ); - } - - m_pManager->m_pSprite->End(); - - m_pManager->m_pStateBlock->Apply(); - - return S_OK; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::OnRender11( float fElapsedTime ) -{ - // If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside - // the application's device callbacks. See the SDK samples for an example of how to do this. - assert( m_pManager->GetD3D11Device() && - L"To fix hook up CDXUTDialogResourceManager to device callbacks. See comments for details" ); - - // See if the dialog needs to be refreshed - if( m_fTimeLastRefresh < s_fTimeRefresh ) - { - m_fTimeLastRefresh = DXUTGetTime(); - Refresh(); - } - - // For invisible dialog, out now. - if( !m_bVisible || - ( m_bMinimized && !m_bCaption ) ) - return S_OK; - - ID3D11Device* pd3dDevice = m_pManager->GetD3D11Device(); - ID3D11DeviceContext* pd3dDeviceContext = m_pManager->GetD3D11DeviceContext(); - - // Set up a state block here and restore it when finished drawing all the controls - m_pManager->StoreD3D11State( pd3dDeviceContext ); - - BOOL bBackgroundIsVisible = ( m_colorTopLeft | m_colorTopRight | m_colorBottomRight | m_colorBottomLeft ) & - 0xff000000; - if( !m_bMinimized && bBackgroundIsVisible ) - { - // Convert the draw rectangle from screen coordinates to clip space coordinates. - float Left, Right, Top, Bottom; - Left = m_x * 2.0f / m_pManager->m_nBackBufferWidth - 1.0f; - Right = ( m_x + m_width ) * 2.0f / m_pManager->m_nBackBufferWidth - 1.0f; - Top = 1.0f - m_y * 2.0f / m_pManager->m_nBackBufferHeight; - Bottom = 1.0f - ( m_y + m_height ) * 2.0f / m_pManager->m_nBackBufferHeight; - - DXUT_SCREEN_VERTEX_10 vertices[4] = - { - Left, Top, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorTopLeft ), 0.0f, 0.0f, - Right, Top, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorTopRight ), 1.0f, 0.0f, - Left, Bottom, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorBottomLeft ), 0.0f, 1.0f, - Right, Bottom, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorBottomRight ), 1.0f, 1.0f, - }; - - //DXUT_SCREEN_VERTEX_10 *pVB; - D3D11_MAPPED_SUBRESOURCE MappedData; - if( SUCCEEDED( pd3dDeviceContext->Map( m_pManager->m_pVBScreenQuad11, 0, D3D11_MAP_WRITE_DISCARD, - 0, &MappedData ) ) ) - { - CopyMemory( MappedData.pData, vertices, sizeof( vertices ) ); - pd3dDeviceContext->Unmap( m_pManager->m_pVBScreenQuad11, 0 ); - } - - // Set the quad VB as current - UINT stride = sizeof( DXUT_SCREEN_VERTEX_10 ); - UINT offset = 0; - pd3dDeviceContext->IASetVertexBuffers( 0, 1, &m_pManager->m_pVBScreenQuad11, &stride, &offset ); - pd3dDeviceContext->IASetInputLayout( m_pManager->m_pInputLayout11 ); - pd3dDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ); - - // Setup for rendering - m_pManager->ApplyRenderUIUntex11( pd3dDeviceContext ); - pd3dDeviceContext->Draw( 4, 0 ); - } - - DXUTTextureNode* pTextureNode = GetTexture( 0 ); - pd3dDeviceContext->PSSetShaderResources( 0, 1, &pTextureNode->pTexResView11 ); - - // Sort depth back to front - m_pManager->BeginSprites11(); - BeginText11(); - - m_pManager->ApplyRenderUI11( pd3dDeviceContext ); - - // Render the caption if it's enabled. - if( m_bCaption ) - { - // DrawSprite will offset the rect down by - // m_nCaptionHeight, so adjust the rect higher - // here to negate the effect. - RECT rc = { 0, -m_nCaptionHeight, m_width, 0 }; - DrawSprite11( &m_CapElement, &rc, 0.99f ); - rc.left += 5; // Make a left margin - WCHAR wszOutput[256]; - wcscpy_s( wszOutput, 256, m_wszCaption ); - if( m_bMinimized ) - wcscat_s( wszOutput, 256, L" (Minimized)" ); - DrawText11( pd3dDevice, pd3dDeviceContext, wszOutput, &m_CapElement, &rc, true ); - } - - // If the dialog is minimized, skip rendering - // its controls. - if( !m_bMinimized ) - { - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - - // Focused control is drawn last - if( pControl == s_pControlFocus ) - continue; - - pControl->Render( fElapsedTime ); - } - - if( s_pControlFocus != NULL && s_pControlFocus->m_pDialog == this ) - s_pControlFocus->Render( fElapsedTime ); - } - - // End sprites - if( m_bCaption ) - { - m_pManager->EndSprites11( pd3dDevice, pd3dDeviceContext ); - EndText11( pd3dDevice, pd3dDeviceContext ); - } - m_pManager->RestoreD3D11State( pd3dDeviceContext ); - - return S_OK; -} - -//-------------------------------------------------------------------------------------- -VOID CDXUTDialog::SendEvent( UINT nEvent, bool bTriggeredByUser, CDXUTControl* pControl ) -{ - // If no callback has been registered there's nowhere to send the event to - if( m_pCallbackEvent == NULL ) - return; - - // Discard events triggered programatically if these types of events haven't been - // enabled - if( !bTriggeredByUser && !m_bNonUserEvents ) - return; - - m_pCallbackEvent( nEvent, pControl->GetID(), pControl, m_pCallbackEventUserContext ); -} - - -//-------------------------------------------------------------------------------------- -int CDXUTDialogResourceManager::AddFont( LPCWSTR strFaceName, LONG height, LONG weight ) -{ - // See if this font already exists - for( int i = 0; i < m_FontCache.GetSize(); i++ ) - { - DXUTFontNode* pFontNode = m_FontCache.GetAt( i ); - size_t nLen = 0; - nLen = wcsnlen( strFaceName, MAX_PATH); - if( 0 == _wcsnicmp( pFontNode->strFace, strFaceName, nLen ) && - pFontNode->nHeight == height && - pFontNode->nWeight == weight ) - { - return i; - } - } - - // Add a new font and try to create it - DXUTFontNode* pNewFontNode = new DXUTFontNode; - if( pNewFontNode == NULL ) - return -1; - - ZeroMemory( pNewFontNode, sizeof( DXUTFontNode ) ); - wcscpy_s( pNewFontNode->strFace, MAX_PATH, strFaceName ); - pNewFontNode->nHeight = height; - pNewFontNode->nWeight = weight; - m_FontCache.Add( pNewFontNode ); - - int iFont = m_FontCache.GetSize() - 1; - - // If a device is available, try to create immediately - if( m_pd3d9Device ) - CreateFont9( iFont ); - - return iFont; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::SetFont( UINT index, LPCWSTR strFaceName, LONG height, LONG weight ) -{ - // If this assert triggers, you need to call CDXUTDialog::Init() first. This change - // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The - // creation and interfacing with CDXUTDialogResourceManager is now the responsibility - // of the application if it wishes to use DXUT's GUI. - assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first. See comments for details." ); - - // Make sure the list is at least as large as the index being set - UINT i; - for( i = m_Fonts.GetSize(); i <= index; i++ ) - { - m_Fonts.Add( -1 ); - } - - int iFont = m_pManager->AddFont( strFaceName, height, weight ); - m_Fonts.SetAt( index, iFont ); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -DXUTFontNode* CDXUTDialog::GetFont( UINT index ) -{ - if( NULL == m_pManager ) - return NULL; - return m_pManager->GetFontNode( m_Fonts.GetAt( index ) ); -} - - -//-------------------------------------------------------------------------------------- -int CDXUTDialogResourceManager::AddTexture( LPCWSTR strFilename ) -{ - // See if this texture already exists - for( int i = 0; i < m_TextureCache.GetSize(); i++ ) - { - DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); - size_t nLen = 0; - nLen = wcsnlen( strFilename, MAX_PATH); - if( pTextureNode->bFileSource && // Sources must match - 0 == _wcsnicmp( pTextureNode->strFilename, strFilename, nLen ) ) - { - return i; - } - } - - // Add a new texture and try to create it - DXUTTextureNode* pNewTextureNode = new DXUTTextureNode; - if( pNewTextureNode == NULL ) - return -1; - - ZeroMemory( pNewTextureNode, sizeof( DXUTTextureNode ) ); - pNewTextureNode->bFileSource = true; - wcscpy_s( pNewTextureNode->strFilename, MAX_PATH, strFilename ); - - m_TextureCache.Add( pNewTextureNode ); - - int iTexture = m_TextureCache.GetSize() - 1; - - // If a device is available, try to create immediately - if( m_pd3d9Device ) - CreateTexture9( iTexture ); - - return iTexture; -} - - -//-------------------------------------------------------------------------------------- -int CDXUTDialogResourceManager::AddTexture( LPCWSTR strResourceName, HMODULE hResourceModule ) -{ - // See if this texture already exists - for( int i = 0; i < m_TextureCache.GetSize(); i++ ) - { - DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i ); - if( !pTextureNode->bFileSource && // Sources must match - pTextureNode->hResourceModule == hResourceModule ) // Module handles must match - { - if( IS_INTRESOURCE( strResourceName ) ) - { - // Integer-based ID - if( ( INT_PTR )strResourceName == pTextureNode->nResourceID ) - return i; - } - else - { - // String-based ID - size_t nLen = 0; - nLen = wcsnlen ( strResourceName, MAX_PATH ); - if( 0 == _wcsnicmp( pTextureNode->strFilename, strResourceName, nLen ) ) - return i; - } - } - } - - // Add a new texture and try to create it - DXUTTextureNode* pNewTextureNode = new DXUTTextureNode; - if( pNewTextureNode == NULL ) - return -1; - - ZeroMemory( pNewTextureNode, sizeof( DXUTTextureNode ) ); - pNewTextureNode->hResourceModule = hResourceModule; - if( IS_INTRESOURCE( strResourceName ) ) - { - pNewTextureNode->nResourceID = ( int )( size_t )strResourceName; - } - else - { - pNewTextureNode->nResourceID = 0; - wcscpy_s( pNewTextureNode->strFilename, MAX_PATH, strResourceName ); - } - - m_TextureCache.Add( pNewTextureNode ); - - int iTexture = m_TextureCache.GetSize() - 1; - - // If a device is available, try to create immediately - if( m_pd3d9Device ) - CreateTexture9( iTexture ); - - return iTexture; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strFilename ) -{ - // If this assert triggers, you need to call CDXUTDialog::Init() first. This change - // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The - // creation and interfacing with CDXUTDialogResourceManager is now the responsibility - // of the application if it wishes to use DXUT's GUI. - assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first. See comments for details." ); - - // Make sure the list is at least as large as the index being set - for( UINT i = m_Textures.GetSize(); i <= index; i++ ) - { - m_Textures.Add( -1 ); - } - - int iTexture = m_pManager->AddTexture( strFilename ); - - m_Textures.SetAt( index, iTexture ); - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strResourceName, HMODULE hResourceModule ) -{ - // If this assert triggers, you need to call CDXUTDialog::Init() first. This change - // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The - // creation and interfacing with CDXUTDialogResourceManager is now the responsibility - // of the application if it wishes to use DXUT's GUI. - assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first. See comments for details." ); - - // Make sure the list is at least as large as the index being set - for( UINT i = m_Textures.GetSize(); i <= index; i++ ) - { - m_Textures.Add( -1 ); - } - - int iTexture = m_pManager->AddTexture( strResourceName, hResourceModule ); - - m_Textures.SetAt( index, iTexture ); - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -DXUTTextureNode* CDXUTDialog::GetTexture( UINT index ) -{ - if( NULL == m_pManager ) - return NULL; - return m_pManager->GetTextureNode( m_Textures.GetAt( index ) ); -} - - - -//-------------------------------------------------------------------------------------- -bool CDXUTDialog::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) -{ - bool bHandled = false; - - // For invisible dialog, do not handle anything. - if( !m_bVisible ) - return false; - - // If automation command-line switch is on, enable this dialog's keyboard input - // upon any key press or mouse click. - if( DXUTGetAutomation() && - ( WM_LBUTTONDOWN == uMsg || WM_LBUTTONDBLCLK == uMsg || WM_KEYDOWN == uMsg ) ) - { - m_pManager->EnableKeyboardInputForAllDialogs(); - } - - // If caption is enable, check for clicks in the caption area. - if( m_bCaption ) - { - if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) - { - POINT mousePoint = - { - short( LOWORD( lParam ) ), short( HIWORD( lParam ) ) - }; - - if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width && - mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight ) - { - m_bDrag = true; - SetCapture( DXUTGetHWND() ); - return true; - } - } - else if( uMsg == WM_LBUTTONUP && m_bDrag ) - { - POINT mousePoint = - { - short( LOWORD( lParam ) ), short( HIWORD( lParam ) ) - }; - - if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width && - mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight ) - { - ReleaseCapture(); - m_bDrag = false; - m_bMinimized = !m_bMinimized; - return true; - } - } - } - - // If the dialog is minimized, don't send any messages to controls. - if( m_bMinimized ) - return false; - - // If a control is in focus, it belongs to this dialog, and it's enabled, then give - // it the first chance at handling the message. - if( s_pControlFocus && - s_pControlFocus->m_pDialog == this && - s_pControlFocus->GetEnabled() ) - { - // If the control MsgProc handles it, then we don't. - if( s_pControlFocus->MsgProc( uMsg, wParam, lParam ) ) - return true; - } - - switch( uMsg ) - { - case WM_SIZE: - case WM_MOVE: - { - // Handle sizing and moving messages so that in case the mouse cursor is moved out - // of an UI control because of the window adjustment, we can properly - // unhighlight the highlighted control. - POINT pt = - { - -1, -1 - }; - OnMouseMove( pt ); - break; - } - - case WM_ACTIVATEAPP: - // Call OnFocusIn()/OnFocusOut() of the control that currently has the focus - // as the application is activated/deactivated. This matches the Windows - // behavior. - if( s_pControlFocus && - s_pControlFocus->m_pDialog == this && - s_pControlFocus->GetEnabled() ) - { - if( wParam ) - s_pControlFocus->OnFocusIn(); - else - s_pControlFocus->OnFocusOut(); - } - break; - - // Keyboard messages - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - { - // If a control is in focus, it belongs to this dialog, and it's enabled, then give - // it the first chance at handling the message. - if( s_pControlFocus && - s_pControlFocus->m_pDialog == this && - s_pControlFocus->GetEnabled() ) - { - if( s_pControlFocus->HandleKeyboard( uMsg, wParam, lParam ) ) - return true; - } - - // Not yet handled, see if this matches a control's hotkey - // Activate the hotkey if the focus doesn't belong to an - // edit box. - if( uMsg == WM_KEYDOWN && ( !s_pControlFocus || - ( s_pControlFocus->GetType() != DXUT_CONTROL_EDITBOX - && s_pControlFocus->GetType() != DXUT_CONTROL_IMEEDITBOX ) ) ) - { - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - if( pControl->GetHotkey() == wParam ) - { - pControl->OnHotkey(); - return true; - } - } - } - - // Not yet handled, check for focus messages - if( uMsg == WM_KEYDOWN ) - { - // If keyboard input is not enabled, this message should be ignored - if( !m_bKeyboardInput ) - return false; - - switch( wParam ) - { - case VK_RIGHT: - case VK_DOWN: - if( s_pControlFocus != NULL ) - { - return OnCycleFocus( true ); - } - break; - - case VK_LEFT: - case VK_UP: - if( s_pControlFocus != NULL ) - { - return OnCycleFocus( false ); - } - break; - - case VK_TAB: - { - bool bShiftDown = ( ( GetKeyState( VK_SHIFT ) & 0x8000 ) != 0 ); - return OnCycleFocus( !bShiftDown ); - } - } - } - - break; - } - - - // Mouse messages - case WM_MOUSEMOVE: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDBLCLK: - case WM_XBUTTONDBLCLK: - case WM_MOUSEWHEEL: - { - // If not accepting mouse input, return false to indicate the message should still - // be handled by the application (usually to move the camera). - if( !m_bMouseInput ) - return false; - - POINT mousePoint = - { - short( LOWORD( lParam ) ), short( HIWORD( lParam ) ) - }; - mousePoint.x -= m_x; - mousePoint.y -= m_y; - - // If caption is enabled, offset the Y coordinate by the negative of its height. - if( m_bCaption ) - mousePoint.y -= m_nCaptionHeight; - - // If a control is in focus, it belongs to this dialog, and it's enabled, then give - // it the first chance at handling the message. - if( s_pControlFocus && - s_pControlFocus->m_pDialog == this && - s_pControlFocus->GetEnabled() ) - { - if( s_pControlFocus->HandleMouse( uMsg, mousePoint, wParam, lParam ) ) - return true; - } - - // Not yet handled, see if the mouse is over any controls - CDXUTControl* pControl = GetControlAtPoint( mousePoint ); - if( pControl != NULL && pControl->GetEnabled() ) - { - bHandled = pControl->HandleMouse( uMsg, mousePoint, wParam, lParam ); - if( bHandled ) - return true; - } - else - { - // Mouse not over any controls in this dialog, if there was a control - // which had focus it just lost it - if( uMsg == WM_LBUTTONDOWN && - s_pControlFocus && - s_pControlFocus->m_pDialog == this ) - { - s_pControlFocus->OnFocusOut(); - s_pControlFocus = NULL; - } - } - - // Still not handled, hand this off to the dialog. Return false to indicate the - // message should still be handled by the application (usually to move the camera). - switch( uMsg ) - { - case WM_MOUSEMOVE: - OnMouseMove( mousePoint ); - return false; - } - - break; - } - - case WM_CAPTURECHANGED: - { - // The application has lost mouse capture. - // The dialog object may not have received - // a WM_MOUSEUP when capture changed. Reset - // m_bDrag so that the dialog does not mistakenly - // think the mouse button is still held down. - if( ( HWND )lParam != hWnd ) - m_bDrag = false; - } - } - - return false; -} - -//-------------------------------------------------------------------------------------- -CDXUTControl* CDXUTDialog::GetControlAtPoint( POINT pt ) -{ - // Search through all child controls for the first one which - // contains the mouse point - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - - if( pControl == NULL ) - { - continue; - } - - // We only return the current control if it is visible - // and enabled. Because GetControlAtPoint() is used to do mouse - // hittest, it makes sense to perform this filtering. - if( pControl->ContainsPoint( pt ) && pControl->GetEnabled() && pControl->GetVisible() ) - { - return pControl; - } - } - - return NULL; -} - - -//-------------------------------------------------------------------------------------- -bool CDXUTDialog::GetControlEnabled( int ID ) -{ - CDXUTControl* pControl = GetControl( ID ); - if( pControl == NULL ) - return false; - - return pControl->GetEnabled(); -} - - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::SetControlEnabled( int ID, bool bEnabled ) -{ - CDXUTControl* pControl = GetControl( ID ); - if( pControl == NULL ) - return; - - pControl->SetEnabled( bEnabled ); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::OnMouseUp( POINT pt ) -{ - s_pControlPressed = NULL; - m_pControlMouseOver = NULL; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::OnMouseMove( POINT pt ) -{ - // Figure out which control the mouse is over now - CDXUTControl* pControl = GetControlAtPoint( pt ); - - // If the mouse is still over the same control, nothing needs to be done - if( pControl == m_pControlMouseOver ) - return; - - // Handle mouse leaving the old control - if( m_pControlMouseOver ) - m_pControlMouseOver->OnMouseLeave(); - - // Handle mouse entering the new control - m_pControlMouseOver = pControl; - if( pControl != NULL ) - m_pControlMouseOver->OnMouseEnter(); -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::SetDefaultElement( UINT nControlType, UINT iElement, CDXUTElement* pElement ) -{ - // If this Element type already exist in the list, simply update the stored Element - for( int i = 0; i < m_DefaultElements.GetSize(); i++ ) - { - DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); - - if( pElementHolder->nControlType == nControlType && - pElementHolder->iElement == iElement ) - { - pElementHolder->Element = *pElement; - return S_OK; - } - } - - // Otherwise, add a new entry - DXUTElementHolder* pNewHolder; - pNewHolder = new DXUTElementHolder; - if( pNewHolder == NULL ) - return E_OUTOFMEMORY; - - pNewHolder->nControlType = nControlType; - pNewHolder->iElement = iElement; - pNewHolder->Element = *pElement; - - HRESULT hr = m_DefaultElements.Add( pNewHolder ); - if( FAILED( hr ) ) - { - delete pNewHolder; - } - return hr; -} - - -//-------------------------------------------------------------------------------------- -CDXUTElement* CDXUTDialog::GetDefaultElement( UINT nControlType, UINT iElement ) -{ - for( int i = 0; i < m_DefaultElements.GetSize(); i++ ) - { - DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); - - if( pElementHolder->nControlType == nControlType && - pElementHolder->iElement == iElement ) - { - return &pElementHolder->Element; - } - } - - return NULL; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddStatic( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, - CDXUTStatic** ppCreated ) -{ - HRESULT hr = S_OK; - - CDXUTStatic* pStatic = new CDXUTStatic( this ); - - if( ppCreated != NULL ) - *ppCreated = pStatic; - - if( pStatic == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pStatic ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and list index - pStatic->SetID( ID ); - pStatic->SetText( strText ); - pStatic->SetLocation( x, y ); - pStatic->SetSize( width, height ); - pStatic->m_bIsDefault = bIsDefault; - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddButton( int ID, LPCWSTR strText, int x, int y, int width, int height, UINT nHotkey, - bool bIsDefault, CDXUTButton** ppCreated ) -{ - HRESULT hr = S_OK; - - CDXUTButton* pButton = new CDXUTButton( this ); - - if( ppCreated != NULL ) - *ppCreated = pButton; - - if( pButton == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pButton ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and list index - pButton->SetID( ID ); - pButton->SetText( strText ); - pButton->SetLocation( x, y ); - pButton->SetSize( width, height ); - pButton->SetHotkey( nHotkey ); - pButton->m_bIsDefault = bIsDefault; - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddCheckBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bChecked, - UINT nHotkey, bool bIsDefault, CDXUTCheckBox** ppCreated ) -{ - HRESULT hr = S_OK; - - CDXUTCheckBox* pCheckBox = new CDXUTCheckBox( this ); - - if( ppCreated != NULL ) - *ppCreated = pCheckBox; - - if( pCheckBox == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pCheckBox ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and list index - pCheckBox->SetID( ID ); - pCheckBox->SetText( strText ); - pCheckBox->SetLocation( x, y ); - pCheckBox->SetSize( width, height ); - pCheckBox->SetHotkey( nHotkey ); - pCheckBox->m_bIsDefault = bIsDefault; - pCheckBox->SetChecked( bChecked ); - - return S_OK; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddRadioButton( int ID, UINT nButtonGroup, LPCWSTR strText, int x, int y, int width, int height, - bool bChecked, UINT nHotkey, bool bIsDefault, CDXUTRadioButton** ppCreated ) -{ - HRESULT hr = S_OK; - - CDXUTRadioButton* pRadioButton = new CDXUTRadioButton( this ); - - if( ppCreated != NULL ) - *ppCreated = pRadioButton; - - if( pRadioButton == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pRadioButton ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and list index - pRadioButton->SetID( ID ); - pRadioButton->SetText( strText ); - pRadioButton->SetButtonGroup( nButtonGroup ); - pRadioButton->SetLocation( x, y ); - pRadioButton->SetSize( width, height ); - pRadioButton->SetHotkey( nHotkey ); - pRadioButton->SetChecked( bChecked ); - pRadioButton->m_bIsDefault = bIsDefault; - pRadioButton->SetChecked( bChecked ); - - return S_OK; -} - - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddComboBox( int ID, int x, int y, int width, int height, UINT nHotkey, bool bIsDefault, - CDXUTComboBox** ppCreated ) -{ - HRESULT hr = S_OK; - - CDXUTComboBox* pComboBox = new CDXUTComboBox( this ); - - if( ppCreated != NULL ) - *ppCreated = pComboBox; - - if( pComboBox == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pComboBox ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and list index - pComboBox->SetID( ID ); - pComboBox->SetLocation( x, y ); - pComboBox->SetSize( width, height ); - pComboBox->SetHotkey( nHotkey ); - pComboBox->m_bIsDefault = bIsDefault; - - return S_OK; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddSlider( int ID, int x, int y, int width, int height, int min, int max, int value, - bool bIsDefault, CDXUTSlider** ppCreated ) -{ - HRESULT hr = S_OK; - - CDXUTSlider* pSlider = new CDXUTSlider( this ); - - if( ppCreated != NULL ) - *ppCreated = pSlider; - - if( pSlider == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pSlider ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and list index - pSlider->SetID( ID ); - pSlider->SetLocation( x, y ); - pSlider->SetSize( width, height ); - pSlider->m_bIsDefault = bIsDefault; - pSlider->SetRange( min, max ); - pSlider->SetValue( value ); - pSlider->UpdateRects(); - - return S_OK; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddEditBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, - CDXUTEditBox** ppCreated ) -{ - HRESULT hr = S_OK; - - CDXUTEditBox* pEditBox = new CDXUTEditBox( this ); - - if( ppCreated != NULL ) - *ppCreated = pEditBox; - - if( pEditBox == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pEditBox ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and position - pEditBox->SetID( ID ); - pEditBox->SetLocation( x, y ); - pEditBox->SetSize( width, height ); - pEditBox->m_bIsDefault = bIsDefault; - - if( strText ) - pEditBox->SetText( strText ); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddListBox( int ID, int x, int y, int width, int height, DWORD dwStyle, CDXUTListBox** ppCreated ) -{ - HRESULT hr = S_OK; - CDXUTListBox* pListBox = new CDXUTListBox( this ); - - if( ppCreated != NULL ) - *ppCreated = pListBox; - - if( pListBox == NULL ) - return E_OUTOFMEMORY; - - hr = AddControl( pListBox ); - if( FAILED( hr ) ) - return hr; - - // Set the ID and position - pListBox->SetID( ID ); - pListBox->SetLocation( x, y ); - pListBox->SetSize( width, height ); - pListBox->SetStyle( dwStyle ); - - return S_OK; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::InitControl( CDXUTControl* pControl ) -{ - HRESULT hr; - - if( pControl == NULL ) - return E_INVALIDARG; - - pControl->m_Index = m_Controls.GetSize(); - - // Look for a default Element entries - for( int i = 0; i < m_DefaultElements.GetSize(); i++ ) - { - DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i ); - if( pElementHolder->nControlType == pControl->GetType() ) - pControl->SetElement( pElementHolder->iElement, &pElementHolder->Element ); - } - - V_RETURN( pControl->OnInit() ); - - return S_OK; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::AddControl( CDXUTControl* pControl ) -{ - HRESULT hr = S_OK; - - hr = InitControl( pControl ); - if( FAILED( hr ) ) - return DXTRACE_ERR( L"CDXUTDialog::InitControl", hr ); - - // Add to the list - hr = m_Controls.Add( pControl ); - if( FAILED( hr ) ) - { - return DXTRACE_ERR( L"CGrowableArray::Add", hr ); - } - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -CDXUTControl* CDXUTDialog::GetControl( int ID ) -{ - // Try to find the control with the given ID - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - - if( pControl->GetID() == ID ) - { - return pControl; - } - } - - // Not found - return NULL; -} - - - -//-------------------------------------------------------------------------------------- -CDXUTControl* CDXUTDialog::GetControl( int ID, UINT nControlType ) -{ - // Try to find the control with the given ID - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - - if( pControl->GetID() == ID && pControl->GetType() == nControlType ) - { - return pControl; - } - } - - // Not found - return NULL; -} - - - -//-------------------------------------------------------------------------------------- -CDXUTControl* CDXUTDialog::GetNextControl( CDXUTControl* pControl ) -{ - int index = pControl->m_Index + 1; - - CDXUTDialog* pDialog = pControl->m_pDialog; - - // Cycle through dialogs in the loop to find the next control. Note - // that if only one control exists in all looped dialogs it will - // be the returned 'next' control. - while( index >= ( int )pDialog->m_Controls.GetSize() ) - { - pDialog = pDialog->m_pNextDialog; - index = 0; - } - - return pDialog->m_Controls.GetAt( index ); -} - -//-------------------------------------------------------------------------------------- -CDXUTControl* CDXUTDialog::GetPrevControl( CDXUTControl* pControl ) -{ - int index = pControl->m_Index - 1; - - CDXUTDialog* pDialog = pControl->m_pDialog; - - // Cycle through dialogs in the loop to find the next control. Note - // that if only one control exists in all looped dialogs it will - // be the returned 'previous' control. - while( index < 0 ) - { - pDialog = pDialog->m_pPrevDialog; - if( pDialog == NULL ) - pDialog = pControl->m_pDialog; - - index = pDialog->m_Controls.GetSize() - 1; - } - - return pDialog->m_Controls.GetAt( index ); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::ClearRadioButtonGroup( UINT nButtonGroup ) -{ - // Find all radio buttons with the given group number - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - - if( pControl->GetType() == DXUT_CONTROL_RADIOBUTTON ) - { - CDXUTRadioButton* pRadioButton = ( CDXUTRadioButton* )pControl; - - if( pRadioButton->GetButtonGroup() == nButtonGroup ) - pRadioButton->SetChecked( false, false ); - } - } -} - - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::ClearComboBox( int ID ) -{ - CDXUTComboBox* pComboBox = GetComboBox( ID ); - if( pComboBox == NULL ) - return; - - pComboBox->RemoveAllItems(); -} - - - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::RequestFocus( CDXUTControl* pControl ) -{ - if( s_pControlFocus == pControl ) - return; - - if( !pControl->CanHaveFocus() ) - return; - - if( s_pControlFocus ) - s_pControlFocus->OnFocusOut(); - - pControl->OnFocusIn(); - s_pControlFocus = pControl; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawRect( RECT* pRect, D3DCOLOR color ) -{ - if( m_pManager->GetD3D9Device() ) - return DrawRect9( pRect, color ); - return E_FAIL; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawRect9( RECT* pRect, D3DCOLOR color ) -{ - RECT rcScreen = *pRect; - OffsetRect( &rcScreen, m_x, m_y ); - - // If caption is enabled, offset the Y position by its height. - if( m_bCaption ) - OffsetRect( &rcScreen, 0, m_nCaptionHeight ); - - DXUT_SCREEN_VERTEX vertices[4] = - { - ( float )rcScreen.left - 0.5f, ( float )rcScreen.top - 0.5f, 0.5f, 1.0f, color, 0, 0, - ( float )rcScreen.right - 0.5f, ( float )rcScreen.top - 0.5f, 0.5f, 1.0f, color, 0, 0, - ( float )rcScreen.right - 0.5f, ( float )rcScreen.bottom - 0.5f, 0.5f, 1.0f, color, 0, 0, - ( float )rcScreen.left - 0.5f, ( float )rcScreen.bottom - 0.5f, 0.5f, 1.0f, color, 0, 0, - }; - - IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device(); - - // Since we're doing our own drawing here we need to flush the sprites - m_pManager->m_pSprite->Flush(); - IDirect3DVertexDeclaration9* pDecl = NULL; - pd3dDevice->GetVertexDeclaration( &pDecl ); // Preserve the sprite's current vertex decl - pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF ); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); - - pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof( DXUT_SCREEN_VERTEX ) ); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - - // Restore the vertex decl - pd3dDevice->SetVertexDeclaration( pDecl ); - pDecl->Release(); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawPolyLine( POINT* apPoints, UINT nNumPoints, D3DCOLOR color ) -{ - DXUT_SCREEN_VERTEX* vertices = new DXUT_SCREEN_VERTEX[ nNumPoints ]; - if( vertices == NULL ) - return E_OUTOFMEMORY; - - DXUT_SCREEN_VERTEX* pVertex = vertices; - POINT* pt = apPoints; - for( UINT i = 0; i < nNumPoints; i++ ) - { - pVertex->x = m_x + ( float )pt->x; - pVertex->y = m_y + ( float )pt->y; - pVertex->z = 0.5f; - pVertex->h = 1.0f; - pVertex->color = color; - pVertex->tu = 0.0f; - pVertex->tv = 0.0f; - - pVertex++; - pt++; - } - - IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device(); - - // Since we're doing our own drawing here we need to flush the sprites - m_pManager->m_pSprite->Flush(); - IDirect3DVertexDeclaration9* pDecl = NULL; - pd3dDevice->GetVertexDeclaration( &pDecl ); // Preserve the sprite's current vertex decl - pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF ); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); - - pd3dDevice->DrawPrimitiveUP( D3DPT_LINESTRIP, nNumPoints - 1, vertices, sizeof( DXUT_SCREEN_VERTEX ) ); - - pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - - // Restore the vertex decl - pd3dDevice->SetVertexDeclaration( pDecl ); - pDecl->Release(); - - SAFE_DELETE_ARRAY( vertices ); - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawSprite( CDXUTElement* pElement, RECT* prcDest, float fDepth ) -{ - if( m_pManager->GetD3D9Device() ) - return DrawSprite9( pElement, prcDest ); - else - return DrawSprite11( pElement, prcDest, fDepth ); -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawSprite9( CDXUTElement* pElement, RECT* prcDest ) -{ - // No need to draw fully transparent layers - if( pElement->TextureColor.Current.a == 0 ) - return S_OK; - - RECT rcTexture = pElement->rcTexture; - - RECT rcScreen = *prcDest; - OffsetRect( &rcScreen, m_x, m_y ); - - // If caption is enabled, offset the Y position by its height. - if( m_bCaption ) - OffsetRect( &rcScreen, 0, m_nCaptionHeight ); - - DXUTTextureNode* pTextureNode = GetTexture( pElement->iTexture ); - if( pTextureNode == NULL ) - return E_FAIL; - - float fScaleX = ( float )RectWidth( rcScreen ) / RectWidth( rcTexture ); - float fScaleY = ( float )RectHeight( rcScreen ) / RectHeight( rcTexture ); - - D3DXMATRIXA16 matTransform; - D3DXMatrixScaling( &matTransform, fScaleX, fScaleY, 1.0f ); - - m_pManager->m_pSprite->SetTransform( &matTransform ); - - D3DXVECTOR3 vPos( ( float )rcScreen.left, ( float )rcScreen.top, 0.0f ); - - vPos.x /= fScaleX; - vPos.y /= fScaleY; - - return m_pManager->m_pSprite->Draw( pTextureNode->pTexture9, &rcTexture, NULL, &vPos, - pElement->TextureColor.Current ); -} - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawSprite11( CDXUTElement* pElement, RECT* prcDest, float fDepth ) -{ - // No need to draw fully transparent layers - if( pElement->TextureColor.Current.a == 0 ) - return S_OK; - - RECT rcTexture = pElement->rcTexture; - - RECT rcScreen = *prcDest; - OffsetRect( &rcScreen, m_x, m_y ); - - // If caption is enabled, offset the Y position by its height. - if( m_bCaption ) - OffsetRect( &rcScreen, 0, m_nCaptionHeight ); - - DXUTTextureNode* pTextureNode = GetTexture( pElement->iTexture ); - if( pTextureNode == NULL ) - return E_FAIL; - - float fBBWidth = ( float )m_pManager->m_nBackBufferWidth; - float fBBHeight = ( float )m_pManager->m_nBackBufferHeight; - float fTexWidth = ( float )pTextureNode->dwWidth; - float fTexHeight = ( float )pTextureNode->dwHeight; - - float fRectLeft = rcScreen.left / fBBWidth; - float fRectTop = 1.0f - rcScreen.top / fBBHeight; - float fRectRight = rcScreen.right / fBBWidth; - float fRectBottom = 1.0f - rcScreen.bottom / fBBHeight; - - fRectLeft = fRectLeft * 2.0f - 1.0f; - fRectTop = fRectTop * 2.0f - 1.0f; - fRectRight = fRectRight * 2.0f - 1.0f; - fRectBottom = fRectBottom * 2.0f - 1.0f; - - float fTexLeft = rcTexture.left / fTexWidth; - float fTexTop = rcTexture.top / fTexHeight; - float fTexRight = rcTexture.right / fTexWidth; - float fTexBottom = rcTexture.bottom / fTexHeight; - - // Add 6 sprite vertices - DXUTSpriteVertex SpriteVertex; - - // tri1 - SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectTop, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexTop ); - SpriteVertex.vColor = pElement->TextureColor.Current; - m_pManager->m_SpriteVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); - SpriteVertex.vColor = pElement->TextureColor.Current; - m_pManager->m_SpriteVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); - SpriteVertex.vColor = pElement->TextureColor.Current; - m_pManager->m_SpriteVertices.Add( SpriteVertex ); - - // tri2 - SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); - SpriteVertex.vColor = pElement->TextureColor.Current; - m_pManager->m_SpriteVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectBottom, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexBottom ); - SpriteVertex.vColor = pElement->TextureColor.Current; - m_pManager->m_SpriteVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); - SpriteVertex.vColor = pElement->TextureColor.Current; - m_pManager->m_SpriteVertices.Add( SpriteVertex ); - - // TODO: Why are we drawing the sprite every time? This is very inefficient, but the sprite workaround doesn't have support for sorting now, so we have to - // draw a sprite every time to keep the order correct between sprites and text. - m_pManager->EndSprites11( DXUTGetD3D11Device(), DXUTGetD3D11DeviceContext() ); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::CalcTextRect( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, int nCount ) -{ - HRESULT hr = S_OK; - - DXUTFontNode* pFontNode = GetFont( pElement->iFont ); - if( pFontNode == NULL ) - return E_FAIL; - - DWORD dwTextFormat = pElement->dwTextFormat | DT_CALCRECT; - // Since we are only computing the rectangle, we don't need a sprite. - if( pFontNode->pFont9 ) - { - hr = pFontNode->pFont9->DrawText( NULL, strText, nCount, prcDest, dwTextFormat, pElement->FontColor.Current ); - if( FAILED( hr ) ) - return hr; - } - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawText( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount, bool bCenter ) -{ - if( m_pManager->GetD3D9Device() ) - return DrawText9( strText, pElement, prcDest, bShadow, nCount ); - else - return DrawText11( m_pManager->GetD3D11Device(), m_pManager->GetD3D11DeviceContext(), strText, pElement, prcDest, bShadow, nCount, bCenter ); -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawText9( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount ) -{ - HRESULT hr = S_OK; - - // No need to draw fully transparent layers - if( pElement->FontColor.Current.a == 0 ) - return S_OK; - - RECT rcScreen = *prcDest; - OffsetRect( &rcScreen, m_x, m_y ); - - // If caption is enabled, offset the Y position by its height. - if( m_bCaption ) - OffsetRect( &rcScreen, 0, m_nCaptionHeight ); - - D3DXMATRIX matTransform; - D3DXMatrixIdentity( &matTransform ); - m_pManager->m_pSprite->SetTransform( &matTransform ); - - DXUTFontNode* pFontNode = GetFont( pElement->iFont ); - - if( bShadow ) - { - RECT rcShadow = rcScreen; - OffsetRect( &rcShadow, 1, 1 ); - hr = pFontNode->pFont9->DrawText( m_pManager->m_pSprite, strText, nCount, &rcShadow, pElement->dwTextFormat, - D3DCOLOR_ARGB( DWORD( pElement->FontColor.Current.a * 255 ), 0, 0, 0 ) ); - if( FAILED( hr ) ) - return hr; - } - - hr = pFontNode->pFont9->DrawText( m_pManager->m_pSprite, strText, nCount, &rcScreen, pElement->dwTextFormat, - pElement->FontColor.Current ); - if( FAILED( hr ) ) - return hr; - - return S_OK; -} - -ID3D11Buffer* g_pFontBuffer11 = NULL; -UINT g_FontBufferBytes11 = 0; -CGrowableArray<DXUTSpriteVertex> g_FontVertices; -ID3D11ShaderResourceView* g_pFont11 = NULL; -ID3D11InputLayout* g_pInputLayout11 = NULL; -HRESULT InitFont11( ID3D11Device* pd3d11Device, ID3D11InputLayout* pInputLayout ) -{ - HRESULT hr = S_OK; - WCHAR str[MAX_PATH]; - V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"UI\\Font.dds" ) ); - - if (pd3d11Device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0 ) { - - D3DX11_IMAGE_INFO dii; - D3DX11GetImageInfoFromFile( str, NULL, &dii, NULL ); - - D3DX11_IMAGE_LOAD_INFO dili; - dili.BindFlags = D3DX11_DEFAULT; - dili.CpuAccessFlags = D3DX11_DEFAULT; - dili.Depth = D3DX11_DEFAULT; - dili.Filter = D3DX11_DEFAULT; - dili.FirstMipLevel = 0; - dili.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - dili.Height = D3DX11_DEFAULT; - dili.MipFilter = D3DX11_DEFAULT; - dili.MipLevels = 1; - dili.MiscFlags = D3DX11_DEFAULT; - dili.pSrcInfo = &dii; - dili.Usage = D3D11_USAGE_DEFAULT ; - dili.Width = D3DX11_DEFAULT; - - V_RETURN( D3DX11CreateShaderResourceViewFromFile( pd3d11Device, str, &dili, NULL, &g_pFont11, &hr) ); - } else { - V_RETURN( D3DX11CreateShaderResourceViewFromFile( pd3d11Device, str, NULL, NULL, &g_pFont11, &hr) ); - - } - - - g_pInputLayout11 = pInputLayout; - return hr; -} - -void EndFont11() -{ - SAFE_RELEASE( g_pFontBuffer11 ); - g_FontBufferBytes11 = 0; - SAFE_RELEASE( g_pFont11 ); -} - -void BeginText11() -{ - g_FontVertices.Reset(); -} - -void DrawText11DXUT( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext, - LPCWSTR strText, RECT rcScreen, D3DXCOLOR vFontColor, - float fBBWidth, float fBBHeight, bool bCenter ) -{ - float fCharTexSizeX = 0.010526315f; - //float fGlyphSizeX = 14.0f / fBBWidth; - //float fGlyphSizeY = 32.0f / fBBHeight; - float fGlyphSizeX = 15.0f / fBBWidth; - float fGlyphSizeY = 42.0f / fBBHeight; - - - float fRectLeft = rcScreen.left / fBBWidth; - float fRectTop = 1.0f - rcScreen.top / fBBHeight; - - fRectLeft = fRectLeft * 2.0f - 1.0f; - fRectTop = fRectTop * 2.0f - 1.0f; - - int NumChars = (int)wcslen( strText ); - if (bCenter) { - float fRectRight = rcScreen.right / fBBWidth; - fRectRight = fRectRight * 2.0f - 1.0f; - float fRectBottom = 1.0f - rcScreen.bottom / fBBHeight; - fRectBottom = fRectBottom * 2.0f - 1.0f; - float fcenterx = ((fRectRight - fRectLeft) - (float)NumChars*fGlyphSizeX) *0.5f; - float fcentery = ((fRectTop - fRectBottom) - (float)1*fGlyphSizeY) *0.5f; - fRectLeft += fcenterx ; - fRectTop -= fcentery; - } - float fOriginalLeft = fRectLeft; - float fTexTop = 0.0f; - float fTexBottom = 1.0f; - - float fDepth = 0.5f; - for( int i=0; i<NumChars; i++ ) - { - if( strText[i] == '\n' ) - { - fRectLeft = fOriginalLeft; - fRectTop -= fGlyphSizeY; - - continue; - } - else if( strText[i] < 32 || strText[i] > 126 ) - { - continue; - } - - // Add 6 sprite vertices - DXUTSpriteVertex SpriteVertex; - float fRectRight = fRectLeft + fGlyphSizeX; - float fRectBottom = fRectTop - fGlyphSizeY; - float fTexLeft = ( strText[i] - 32 ) * fCharTexSizeX; - float fTexRight = fTexLeft + fCharTexSizeX; - - // tri1 - SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectTop, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexTop ); - SpriteVertex.vColor = vFontColor; - g_FontVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); - SpriteVertex.vColor = vFontColor; - g_FontVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); - SpriteVertex.vColor = vFontColor; - g_FontVertices.Add( SpriteVertex ); - - // tri2 - SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); - SpriteVertex.vColor = vFontColor; - g_FontVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectBottom, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexBottom ); - SpriteVertex.vColor = vFontColor; - g_FontVertices.Add( SpriteVertex ); - - SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); - SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); - SpriteVertex.vColor = vFontColor; - g_FontVertices.Add( SpriteVertex ); - - fRectLeft += fGlyphSizeX; - - } - - // TODO: We have to end text after every line so that rendering order between sprites and fonts is preserved - EndText11( pd3dDevice, pd3d11DeviceContext ); -} - -void EndText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext ) -{ - - // ensure our buffer size can hold our sprites - UINT FontDataBytes = g_FontVertices.GetSize() * sizeof( DXUTSpriteVertex ); - if( g_FontBufferBytes11 < FontDataBytes ) - { - SAFE_RELEASE( g_pFontBuffer11 ); - g_FontBufferBytes11 = FontDataBytes; - - D3D11_BUFFER_DESC BufferDesc; - BufferDesc.ByteWidth = g_FontBufferBytes11; - BufferDesc.Usage = D3D11_USAGE_DYNAMIC; - BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - BufferDesc.MiscFlags = 0; - - pd3dDevice->CreateBuffer( &BufferDesc, NULL, &g_pFontBuffer11 ); - } - - // Copy the sprites over - D3D11_BOX destRegion; - destRegion.left = 0; - destRegion.right = FontDataBytes; - destRegion.top = 0; - destRegion.bottom = 1; - destRegion.front = 0; - destRegion.back = 1; - D3D11_MAPPED_SUBRESOURCE MappedResource; - if ( S_OK == pd3d11DeviceContext->Map( g_pFontBuffer11, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) { - CopyMemory( MappedResource.pData, (void*)g_FontVertices.GetData(), FontDataBytes ); - pd3d11DeviceContext->Unmap(g_pFontBuffer11, 0); - } - - ID3D11ShaderResourceView* pOldTexture = NULL; - pd3d11DeviceContext->PSGetShaderResources( 0, 1, &pOldTexture ); - pd3d11DeviceContext->PSSetShaderResources( 0, 1, &g_pFont11 ); - - // Draw - UINT Stride = sizeof( DXUTSpriteVertex ); - UINT Offset = 0; - pd3d11DeviceContext->IASetVertexBuffers( 0, 1, &g_pFontBuffer11, &Stride, &Offset ); - pd3d11DeviceContext->IASetInputLayout( g_pInputLayout11 ); - pd3d11DeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); - pd3d11DeviceContext->Draw( g_FontVertices.GetSize(), 0 ); - - pd3d11DeviceContext->PSSetShaderResources( 0, 1, &pOldTexture ); - SAFE_RELEASE( pOldTexture ); - - g_FontVertices.Reset(); -} - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialog::DrawText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext, - LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount, bool bCenter ) -{ - //HRESULT hr = S_OK; - - // No need to draw fully transparent layers - if( pElement->FontColor.Current.a == 0 ) - return S_OK; - - RECT rcScreen = *prcDest; - OffsetRect( &rcScreen, m_x, m_y); - - // If caption is enabled, offset the Y position by its height. - if( m_bCaption ) - OffsetRect( &rcScreen, 0, m_nCaptionHeight ); - - float fBBWidth = ( float )m_pManager->m_nBackBufferWidth; - float fBBHeight = ( float )m_pManager->m_nBackBufferHeight; - - if( bShadow ) - { - RECT rcShadow = rcScreen; - OffsetRect( &rcShadow, 1, 1 ); - - D3DXCOLOR vShadowColor( 0,0,0, 1.0f ); - DrawText11DXUT( pd3dDevice, pd3d11DeviceContext, - strText, rcShadow, vShadowColor, - fBBWidth, fBBHeight, bCenter ); - - } - - D3DXCOLOR vFontColor( pElement->FontColor.Current.r, pElement->FontColor.Current.g, pElement->FontColor.Current.b, 1.0f ); - DrawText11DXUT( pd3dDevice, pd3d11DeviceContext, - strText, rcScreen, vFontColor, - fBBWidth, fBBHeight, bCenter ); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::SetBackgroundColors( D3DCOLOR colorTopLeft, D3DCOLOR colorTopRight, D3DCOLOR colorBottomLeft, - D3DCOLOR colorBottomRight ) -{ - m_colorTopLeft = colorTopLeft; - m_colorTopRight = colorTopRight; - m_colorBottomLeft = colorBottomLeft; - m_colorBottomRight = colorBottomRight; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::SetNextDialog( CDXUTDialog* pNextDialog ) -{ - if( pNextDialog == NULL ) - pNextDialog = this; - - m_pNextDialog = pNextDialog; - if( pNextDialog ) - m_pNextDialog->m_pPrevDialog = this; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::ClearFocus() -{ - if( s_pControlFocus ) - { - s_pControlFocus->OnFocusOut(); - s_pControlFocus = NULL; - } - - ReleaseCapture(); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::FocusDefaultControl() -{ - // Check for default control in this dialog - for( int i = 0; i < m_Controls.GetSize(); i++ ) - { - CDXUTControl* pControl = m_Controls.GetAt( i ); - if( pControl->m_bIsDefault ) - { - // Remove focus from the current control - ClearFocus(); - - // Give focus to the default control - s_pControlFocus = pControl; - s_pControlFocus->OnFocusIn(); - return; - } - } -} - - -//-------------------------------------------------------------------------------------- -bool CDXUTDialog::OnCycleFocus( bool bForward ) -{ - CDXUTControl* pControl = NULL; - CDXUTDialog* pDialog = NULL; // pDialog and pLastDialog are used to track wrapping of - CDXUTDialog* pLastDialog; // focus from first control to last or vice versa. - - if( s_pControlFocus == NULL ) - { - // If s_pControlFocus is NULL, we focus the first control of first dialog in - // the case that bForward is true, and focus the last control of last dialog when - // bForward is false. - // - if( bForward ) - { - // Search for the first control from the start of the dialog - // array. - for( int d = 0; d < m_pManager->m_Dialogs.GetSize(); ++d ) - { - pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt( d ); - if( pDialog && pDialog->m_Controls.GetSize() > 0 ) - { - pControl = pDialog->m_Controls.GetAt( 0 ); - break; - } - } - - if( !pDialog || !pControl ) - { - // No dialog has been registered yet or no controls have been - // added to the dialogs. Cannot proceed. - return true; - } - } - else - { - // Search for the first control from the end of the dialog - // array. - for( int d = m_pManager->m_Dialogs.GetSize() - 1; d >= 0; --d ) - { - pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt( d ); - if( pDialog && pDialog->m_Controls.GetSize() > 0 ) - { - pControl = pDialog->m_Controls.GetAt( pDialog->m_Controls.GetSize() - 1 ); - break; - } - } - - if( !pDialog || !pControl ) - { - // No dialog has been registered yet or no controls have been - // added to the dialogs. Cannot proceed. - return true; - } - } - } - else if( s_pControlFocus->m_pDialog != this ) - { - // If a control belonging to another dialog has focus, let that other - // dialog handle this event by returning false. - // - return false; - } - else - { - // Focused control belongs to this dialog. Cycle to the - // next/previous control. - pLastDialog = s_pControlFocus->m_pDialog; - pControl = ( bForward ) ? GetNextControl( s_pControlFocus ) : GetPrevControl( s_pControlFocus ); - pDialog = pControl->m_pDialog; - } - - for( int i = 0; i < 0xffff; i++ ) - { - // If we just wrapped from last control to first or vice versa, - // set the focused control to NULL. This state, where no control - // has focus, allows the camera to work. - int nLastDialogIndex = m_pManager->m_Dialogs.IndexOf( pLastDialog ); - int nDialogIndex = m_pManager->m_Dialogs.IndexOf( pDialog ); - if( ( !bForward && nLastDialogIndex < nDialogIndex ) || - ( bForward && nDialogIndex < nLastDialogIndex ) ) - { - if( s_pControlFocus ) - s_pControlFocus->OnFocusOut(); - s_pControlFocus = NULL; - return true; - } - - // If we've gone in a full circle then focus doesn't change - if( pControl == s_pControlFocus ) - return true; - - // If the dialog accepts keybord input and the control can have focus then - // move focus - if( pControl->m_pDialog->m_bKeyboardInput && pControl->CanHaveFocus() ) - { - if( s_pControlFocus ) - s_pControlFocus->OnFocusOut(); - s_pControlFocus = pControl; - s_pControlFocus->OnFocusIn(); - return true; - } - - pLastDialog = pDialog; - pControl = ( bForward ) ? GetNextControl( pControl ) : GetPrevControl( pControl ); - pDialog = pControl->m_pDialog; - } - - // If we reached this point, the chain of dialogs didn't form a complete loop - DXTRACE_ERR( L"CDXUTDialog: Multiple dialogs are improperly chained together", E_FAIL ); - return false; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialogResourceManager::CreateFont9( UINT iFont ) -{ - HRESULT hr = S_OK; - - DXUTFontNode* pFontNode = m_FontCache.GetAt( iFont ); - - SAFE_RELEASE( pFontNode->pFont9 ); - - V_RETURN( D3DXCreateFont( m_pd3d9Device, pFontNode->nHeight, 0, pFontNode->nWeight, 1, FALSE, DEFAULT_CHARSET, - OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, - pFontNode->strFace, &pFontNode->pFont9 ) ); - - return S_OK; -} - - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialogResourceManager::CreateFont11( UINT iFont ) -{ - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialogResourceManager::CreateTexture9( UINT iTexture ) -{ - HRESULT hr = S_OK; - - DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( iTexture ); - - - D3DXIMAGE_INFO info; - - if( !pTextureNode->bFileSource ) - { - if( pTextureNode->nResourceID == 0xFFFF && pTextureNode->hResourceModule == ( HMODULE )0xFFFF ) - { - hr = DXUTCreateGUITextureFromInternalArray9( m_pd3d9Device, &pTextureNode->pTexture9, &info ); - if( FAILED( hr ) ) - return DXTRACE_ERR( L"D3DXCreateTextureFromFileInMemoryEx", hr ); - } - else - { - LPCWSTR pID = pTextureNode->nResourceID ? ( LPCWSTR )( size_t )pTextureNode->nResourceID : - pTextureNode->strFilename; - - // Create texture from resource - hr = D3DXCreateTextureFromResourceEx( m_pd3d9Device, pTextureNode->hResourceModule, pID, D3DX_DEFAULT, - D3DX_DEFAULT, - 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, - D3DX_DEFAULT, D3DX_DEFAULT, 0, - &info, NULL, &pTextureNode->pTexture9 ); - if( FAILED( hr ) ) - return DXTRACE_ERR( L"D3DXCreateTextureFromResourceEx", hr ); - } - } - else - { - // Make sure there's a texture to create - if( pTextureNode->strFilename[0] == 0 ) - return S_OK; - - // Create texture from file - hr = D3DXCreateTextureFromFileEx( m_pd3d9Device, pTextureNode->strFilename, D3DX_DEFAULT, D3DX_DEFAULT, - 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, - D3DX_DEFAULT, D3DX_DEFAULT, 0, - &info, NULL, &pTextureNode->pTexture9 ); - if( FAILED( hr ) ) - { - return DXTRACE_ERR( L"D3DXCreateTextureFromFileEx", hr ); - } - } - - // Store dimensions - pTextureNode->dwWidth = info.Width; - pTextureNode->dwHeight = info.Height; - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTDialogResourceManager::CreateTexture11( UINT iTexture ) -{ - HRESULT hr = S_OK; - - DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( iTexture ); - - if( !pTextureNode->bFileSource ) - { - if( pTextureNode->nResourceID == 0xFFFF && pTextureNode->hResourceModule == ( HMODULE )0xFFFF ) - { - hr = DXUTCreateGUITextureFromInternalArray11( m_pd3d11Device, &pTextureNode->pTexture11, NULL ); - if( FAILED( hr ) ) - return DXTRACE_ERR( L"D3DX10CreateResourceFromFileInMemory", hr ); - } - //else - //{ - // LPCWSTR pID = pTextureNode->nResourceID ? ( LPCWSTR )( size_t )pTextureNode->nResourceID : - // pTextureNode->strFilename; - - // D3DX10_IMAGE_INFO SrcInfo; - // D3DX10GetImageInfoFromResource( NULL, pID, NULL, &SrcInfo, NULL ); - - // // Create texture from resource - // ID3D10Resource* pRes; - // D3DX10_IMAGE_LOAD_INFO loadInfo; - // loadInfo.Width = D3DX10_DEFAULT; - // loadInfo.Height = D3DX10_DEFAULT; - // loadInfo.Depth = D3DX10_DEFAULT; - // loadInfo.FirstMipLevel = 0; - // loadInfo.MipLevels = 1; - // loadInfo.Usage = D3D10_USAGE_DEFAULT; - // loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE; - // loadInfo.CpuAccessFlags = 0; - // loadInfo.MiscFlags = 0; - // loadInfo.Format = MAKE_TYPELESS( SrcInfo.Format ); - // loadInfo.Filter = D3DX10_FILTER_NONE; - // loadInfo.MipFilter = D3DX10_FILTER_NONE; - // loadInfo.pSrcInfo = &SrcInfo; - - // hr = D3DX10CreateTextureFromResource( m_pd3d10Device, pTextureNode->hResourceModule, pID, &loadInfo, - // NULL, &pRes, NULL ); - // if( FAILED( hr ) ) - // return DXTRACE_ERR( L"D3DX10CreateResourceFromResource", hr ); - // hr = pRes->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&pTextureNode->pTexture10 ); - // SAFE_RELEASE( pRes ); - // if( FAILED( hr ) ) - // return hr; - //} - } - else - { - // - //// Make sure there's a texture to create - //if( pTextureNode->strFilename[0] == 0 ) - // return S_OK; - - //D3DX10_IMAGE_INFO SrcInfo; - //D3DX10GetImageInfoFromFile( pTextureNode->strFilename, NULL, &SrcInfo, NULL ); - - //// Create texture from file - //ID3D10Resource* pRes; - //D3DX10_IMAGE_LOAD_INFO loadInfo; - //loadInfo.Width = D3DX10_DEFAULT; - //loadInfo.Height = D3DX10_DEFAULT; - //loadInfo.Depth = D3DX10_DEFAULT; - //loadInfo.FirstMipLevel = 0; - //loadInfo.MipLevels = 1; - //loadInfo.Usage = D3D10_USAGE_DEFAULT; - //loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE; - //loadInfo.CpuAccessFlags = 0; - //loadInfo.MiscFlags = 0; - //loadInfo.Format = MAKE_TYPELESS( SrcInfo.Format ); - //loadInfo.Filter = D3DX10_FILTER_NONE; - //loadInfo.MipFilter = D3DX10_FILTER_NONE; - //loadInfo.pSrcInfo = &SrcInfo; - //hr = D3DX10CreateTextureFromFile( m_pd3d10Device, pTextureNode->strFilename, &loadInfo, NULL, &pRes, NULL ); - //if( FAILED( hr ) ) - //{ - // return DXTRACE_ERR( L"D3DX10CreateResourceFromFileEx", hr ); - //} - //hr = pRes->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&pTextureNode->pTexture10 ); - //SAFE_RELEASE( pRes ); - //if( FAILED( hr ) ) - // return hr; - // - } - - // Store dimensions - D3D11_TEXTURE2D_DESC desc; - pTextureNode->pTexture11->GetDesc( &desc ); - pTextureNode->dwWidth = desc.Width; - pTextureNode->dwHeight = desc.Height; - - // Create resource view - D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; - SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - SRVDesc.Format = MAKE_SRGB( desc.Format ); - SRVDesc.Texture2D.MipLevels = 1; - SRVDesc.Texture2D.MostDetailedMip = 0; - hr = m_pd3d11Device->CreateShaderResourceView( pTextureNode->pTexture11, &SRVDesc, &pTextureNode->pTexResView11 ); - - return hr; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTDialog::InitDefaultElements() -{ - SetFont( 0, L"Arial", 14, FW_NORMAL ); - - CDXUTElement Element; - RECT rcTexture; - - //------------------------------------- - // Element for the caption - //------------------------------------- - m_CapElement.SetFont( 0 ); - SetRect( &rcTexture, 17, 269, 241, 287 ); - m_CapElement.SetTexture( 0, &rcTexture ); - m_CapElement.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); - m_CapElement.FontColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); - m_CapElement.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER ); - // Pre-blend as we don't need to transition the state - m_CapElement.TextureColor.Blend( DXUT_STATE_NORMAL, 10.0f ); - m_CapElement.FontColor.Blend( DXUT_STATE_NORMAL, 10.0f ); - - //------------------------------------- - // CDXUTStatic - //------------------------------------- - Element.SetFont( 0 ); - Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_STATIC, 0, &Element ); - - - //------------------------------------- - // CDXUTButton - Button - //------------------------------------- - SetRect( &rcTexture, 0, 0, 136, 54 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0 ); - Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); - Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_BUTTON, 0, &Element ); - - - //------------------------------------- - // CDXUTButton - Fill layer - //------------------------------------- - SetRect( &rcTexture, 136, 0, 252, 54 ); - Element.SetTexture( 0, &rcTexture, D3DCOLOR_ARGB( 0, 255, 255, 255 ) ); - Element.TextureColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 160, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 60, 0, 0, 0 ); - Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 30, 255, 255, 255 ); - - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_BUTTON, 1, &Element ); - - - //------------------------------------- - // CDXUTCheckBox - Box - //------------------------------------- - SetRect( &rcTexture, 0, 54, 27, 81 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER ); - Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); - Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_CHECKBOX, 0, &Element ); - - - //------------------------------------- - // CDXUTCheckBox - Check - //------------------------------------- - SetRect( &rcTexture, 27, 54, 54, 81 ); - Element.SetTexture( 0, &rcTexture ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_CHECKBOX, 1, &Element ); - - - //------------------------------------- - // CDXUTRadioButton - Box - //------------------------------------- - SetRect( &rcTexture, 54, 54, 81, 81 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER ); - Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); - Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 255, 255, 255 ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 0, &Element ); - - - //------------------------------------- - // CDXUTRadioButton - Check - //------------------------------------- - SetRect( &rcTexture, 81, 54, 108, 81 ); - Element.SetTexture( 0, &rcTexture ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 1, &Element ); - - - //------------------------------------- - // CDXUTComboBox - Main - //------------------------------------- - SetRect( &rcTexture, 7, 81, 247, 123 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0 ); - Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 200, 200, 200 ); - Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 170, 230, 230, 230 ); - Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 200, 200, 200 ); - Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); - Element.FontColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); - Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 ); - - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_COMBOBOX, 0, &Element ); - - - //------------------------------------- - // CDXUTComboBox - Button - //------------------------------------- - SetRect( &rcTexture, 98, 189, 151, 238 ); - Element.SetTexture( 0, &rcTexture ); - Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 150, 150, 150 ); - Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 255, 255, 255 ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_COMBOBOX, 1, &Element ); - - - //------------------------------------- - // CDXUTComboBox - Dropdown - //------------------------------------- - SetRect( &rcTexture, 13, 123, 241, 160 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_COMBOBOX, 2, &Element ); - - - //------------------------------------- - // CDXUTComboBox - Selection - //------------------------------------- - SetRect( &rcTexture, 12, 163, 239, 183 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_TOP ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_COMBOBOX, 3, &Element ); - - - //------------------------------------- - // CDXUTSlider - Track - //------------------------------------- - SetRect( &rcTexture, 1, 187, 93, 228 ); - Element.SetTexture( 0, &rcTexture ); - Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 ); - Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 255, 255, 255 ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_SLIDER, 0, &Element ); - - //------------------------------------- - // CDXUTSlider - Button - //------------------------------------- - SetRect( &rcTexture, 151, 193, 192, 234 ); - Element.SetTexture( 0, &rcTexture ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_SLIDER, 1, &Element ); - - //------------------------------------- - // CDXUTScrollBar - Track - //------------------------------------- - int nScrollBarStartX = 196; - int nScrollBarStartY = 191; - SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 21, nScrollBarStartX + 22, nScrollBarStartY + 32 ); - Element.SetTexture( 0, &rcTexture ); - Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 0, &Element ); - - //------------------------------------- - // CDXUTScrollBar - Up Arrow - //------------------------------------- - SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 1, nScrollBarStartX + 22, nScrollBarStartY + 21 ); - Element.SetTexture( 0, &rcTexture ); - Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 ); - - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 1, &Element ); - - //------------------------------------- - // CDXUTScrollBar - Down Arrow - //------------------------------------- - SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 32, nScrollBarStartX + 22, nScrollBarStartY + 53 ); - Element.SetTexture( 0, &rcTexture ); - Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 ); - - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 2, &Element ); - - //------------------------------------- - // CDXUTScrollBar - Button - //------------------------------------- - SetRect( &rcTexture, 220, 192, 238, 234 ); - Element.SetTexture( 0, &rcTexture ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 3, &Element ); - - - //------------------------------------- - // CDXUTEditBox - //------------------------------------- - // Element assignment: - // 0 - text area - // 1 - top left border - // 2 - top border - // 3 - top right border - // 4 - left border - // 5 - right border - // 6 - lower left border - // 7 - lower border - // 8 - lower right border - - Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP ); - - // Assign the style - SetRect( &rcTexture, 14, 90, 241, 113 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 0, &Element ); - SetRect( &rcTexture, 8, 82, 14, 90 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 1, &Element ); - SetRect( &rcTexture, 14, 82, 241, 90 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 2, &Element ); - SetRect( &rcTexture, 241, 82, 246, 90 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 3, &Element ); - SetRect( &rcTexture, 8, 90, 14, 113 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 4, &Element ); - SetRect( &rcTexture, 241, 90, 246, 113 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 5, &Element ); - SetRect( &rcTexture, 8, 113, 14, 121 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 6, &Element ); - SetRect( &rcTexture, 14, 113, 241, 121 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 7, &Element ); - SetRect( &rcTexture, 241, 113, 246, 121 ); - Element.SetTexture( 0, &rcTexture ); - SetDefaultElement( DXUT_CONTROL_EDITBOX, 8, &Element ); - - //------------------------------------- - // CDXUTListBox - Main - //------------------------------------- - SetRect( &rcTexture, 13, 123, 241, 160 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_LISTBOX, 0, &Element ); - - //------------------------------------- - // CDXUTListBox - Selection - //------------------------------------- - - SetRect( &rcTexture, 16, 166, 240, 183 ); - Element.SetTexture( 0, &rcTexture ); - Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_TOP ); - - // Assign the Element - SetDefaultElement( DXUT_CONTROL_LISTBOX, 1, &Element ); -} - - - -//-------------------------------------------------------------------------------------- -// CDXUTControl class -//-------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------- -CDXUTControl::CDXUTControl( CDXUTDialog* pDialog ) -{ - m_Type = DXUT_CONTROL_BUTTON; - m_pDialog = pDialog; - m_ID = 0; - m_Index = 0; - m_pUserData = NULL; - - m_bEnabled = true; - m_bVisible = true; - m_bMouseOver = false; - m_bHasFocus = false; - m_bIsDefault = false; - - m_pDialog = NULL; - - m_x = 0; - m_y = 0; - m_width = 0; - m_height = 0; - - ZeroMemory( &m_rcBoundingBox, sizeof( m_rcBoundingBox ) ); -} - - -CDXUTControl::~CDXUTControl() -{ - for( int i = 0; i < m_Elements.GetSize(); ++i ) - { - delete m_Elements[i]; - } - m_Elements.RemoveAll(); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTControl::SetTextColor( D3DCOLOR Color ) -{ - CDXUTElement* pElement = m_Elements.GetAt( 0 ); - - if( pElement ) - pElement->FontColor.States[DXUT_STATE_NORMAL] = Color; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTControl::SetElement( UINT iElement, CDXUTElement* pElement ) -{ - HRESULT hr = S_OK; - - if( pElement == NULL ) - return E_INVALIDARG; - - // Make certain the array is this large - for( UINT i = m_Elements.GetSize(); i <= iElement; i++ ) - { - CDXUTElement* pNewElement = new CDXUTElement(); - if( pNewElement == NULL ) - return E_OUTOFMEMORY; - - hr = m_Elements.Add( pNewElement ); - if( FAILED( hr ) ) - { - SAFE_DELETE( pNewElement ); - return hr; - } - } - - // Update the data - CDXUTElement* pCurElement = m_Elements.GetAt( iElement ); - *pCurElement = *pElement; - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTControl::Refresh() -{ - m_bMouseOver = false; - m_bHasFocus = false; - - for( int i = 0; i < m_Elements.GetSize(); i++ ) - { - CDXUTElement* pElement = m_Elements.GetAt( i ); - pElement->Refresh(); - } -} - - -//-------------------------------------------------------------------------------------- -void CDXUTControl::UpdateRects() -{ - SetRect( &m_rcBoundingBox, m_x, m_y, m_x + m_width, m_y + m_height ); -} - - -//-------------------------------------------------------------------------------------- -// CDXUTStatic class -//-------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------- -CDXUTStatic::CDXUTStatic( CDXUTDialog* pDialog ) -{ - m_Type = DXUT_CONTROL_STATIC; - m_pDialog = pDialog; - - ZeroMemory( &m_strText, sizeof( m_strText ) ); - - for( int i = 0; i < m_Elements.GetSize(); i++ ) - { - CDXUTElement* pElement = m_Elements.GetAt( i ); - SAFE_DELETE( pElement ); - } - - m_Elements.RemoveAll(); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTStatic::Render( float fElapsedTime ) -{ - if( m_bVisible == false ) - return; - - DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL; - - if( m_bEnabled == false ) - iState = DXUT_STATE_DISABLED; - - CDXUTElement* pElement = m_Elements.GetAt( 0 ); - - pElement->FontColor.Blend( iState, fElapsedTime ); - - m_pDialog->DrawText( m_strText, pElement, &m_rcBoundingBox, false, -1, false); -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTStatic::GetTextCopy( __out_ecount(bufferCount) LPWSTR strDest, - UINT bufferCount ) -{ - // Validate incoming parameters - if( strDest == NULL || bufferCount == 0 ) - { - return E_INVALIDARG; - } - - // Copy the window text - wcscpy_s( strDest, bufferCount, m_strText ); - - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CDXUTStatic::SetText( LPCWSTR strText ) -{ - if( strText == NULL ) - { - m_strText[0] = 0; - return S_OK; - } - - wcscpy_s( m_strText, MAX_PATH, strText ); - return S_OK; -} - - -//-------------------------------------------------------------------------------------- -// CDXUTButton class -//-------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------- -CDXUTButton::CDXUTButton( CDXUTDialog* pDialog ) -{ - m_Type = DXUT_CONTROL_BUTTON; - m_pDialog = pDialog; - - m_bPressed = false; - m_nHotkey = 0; -} - -//-------------------------------------------------------------------------------------- -bool CDXUTButton::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->SendEvent( EVENT_BUTTON_CLICKED, true, this ); - } - return true; - } - } - } - return false; -} - - -//-------------------------------------------------------------------------------------- -bool CDXUTButton::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(); - - if( !m_pDialog->m_bKeyboardInput ) - m_pDialog->ClearFocus(); - - // Button click - if( ContainsPoint( pt ) ) - m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this ); - - return true; - } - - break; - } - }; - - return false; -} - -//-------------------------------------------------------------------------------------- -void CDXUTButton::Render( float fElapsedTime ) -{ - if( m_bVisible == false ) - return; - - 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; - } - - // Background fill layer - //TODO: remove magic numbers - CDXUTElement* pElement = m_Elements.GetAt( 0 ); - - float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f; - - RECT rcWindow = m_rcBoundingBox; - OffsetRect( &rcWindow, nOffsetX, nOffsetY ); - - - // Blend current color - pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); - pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate ); - - m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_FAR_BUTTON_DEPTH ); - m_pDialog->DrawText( m_strText, pElement, &rcWindow, false, -1, true ); - - // Main button - pElement = m_Elements.GetAt( 1 ); - - // Blend current color - pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); - pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate ); - - m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_NEAR_BUTTON_DEPTH ); - m_pDialog->DrawText( m_strText, pElement, &rcWindow, false, -1, true ); -} - - - -//-------------------------------------------------------------------------------------- -// 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( float fElapsedTime ) -{ - if( m_bVisible == false ) - return; - 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, DXUT_NEAR_BUTTON_DEPTH ); - m_pDialog->DrawText( m_strText, pElement, &m_rcText, false, -1, false ); - - if( !m_bChecked ) - iState = DXUT_STATE_HIDDEN; - - pElement = m_Elements.GetAt( 1 ); - - pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); - m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_FAR_BUTTON_DEPTH ); -} - - - - -//-------------------------------------------------------------------------------------- -// 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( float fElapsedTime ) -{ - if( m_bVisible == false ) - return; - 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( fElapsedTime ); - - // Blend current color - pElement->TextureColor.Blend( iState, fElapsedTime ); - pElement->FontColor.Blend( iState, fElapsedTime ); - - m_pDialog->DrawSprite( pElement, &m_rcDropdown, DXUT_NEAR_BUTTON_DEPTH ); - - // 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, DXUT_NEAR_BUTTON_DEPTH ); - 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, DXUT_FAR_BUTTON_DEPTH ); - - 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, DXUT_NEAR_BUTTON_DEPTH ); - - 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, false, -1, true ); - - } - } -} - - -//-------------------------------------------------------------------------------------- -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 ) ); - wcscpy_s( 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_UP, 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( float fElapsedTime ) -{ - if( m_bVisible == false ) - return; - - 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, DXUT_FAR_BUTTON_DEPTH ); - - //TODO: remove magic numbers - pElement = m_Elements.GetAt( 1 ); - - // Blend current color - pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); - m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_NEAR_BUTTON_DEPTH ); -} - - -//-------------------------------------------------------------------------------------- -// 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( float fElapsedTime ) -{ - if( m_bVisible == false ) - return; - - // 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, DXUT_FAR_BUTTON_DEPTH ); - - // Up Arrow - pElement = m_Elements.GetAt( 1 ); - - // Blend current color - pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); - m_pDialog->DrawSprite( pElement, &m_rcUpButton, DXUT_NEAR_BUTTON_DEPTH ); - - // Down Arrow - pElement = m_Elements.GetAt( 2 ); - - // Blend current color - pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); - m_pDialog->DrawSprite( pElement, &m_rcDownButton, DXUT_NEAR_BUTTON_DEPTH ); - - // Thumb button - pElement = m_Elements.GetAt( 3 ); - - // Blend current color - pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate ); - m_pDialog->DrawSprite( pElement, &m_rcThumb, DXUT_NEAR_BUTTON_DEPTH ); - -} - - -//-------------------------------------------------------------------------------------- -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; - - wcscpy_s( 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; - - wcscpy_s( 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::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( 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, DXUT_FAR_BUTTON_DEPTH ); - - // 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, DXUT_NEAR_BUTTON_DEPTH ); - 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( 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( __out_ecount(bufferCount) LPWSTR strDest, - UINT bufferCount ) -{ - assert( strDest ); - - wcscpy_s( 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'\0'; // 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: - // Invoke the callback when the user presses Enter. - m_pDialog->SendEvent( EVENT_EDITBOX_STRING, true, this ); - 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: - { - // If there's a selection and the user - // starts to type, the selection should - // be deleted. - if( m_nCaret != m_nSelStart ) - DeleteSelectionText(); - - // If we are in overwrite mode and there is already - // a char at the caret's position, simply replace it. - // Otherwise, we insert the char as normal. - if( !m_bInsertMode && m_nCaret < m_Buffer.GetTextSize() ) - { - m_Buffer[m_nCaret] = ( WCHAR )wParam; - PlaceCaret( m_nCaret + 1 ); - m_nSelStart = m_nCaret; - } - else - { - // Insert the char - if( m_Buffer.InsertChar( m_nCaret, ( WCHAR )wParam ) ) - { - PlaceCaret( m_nCaret + 1 ); - m_nSelStart = m_nCaret; - } - } - ResetCaretBlink(); - m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this ); - } - } - return true; - } - } - return false; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTEditBox::Render( float fElapsedTime ) -{ - if( m_bVisible == false ) - return; - - HRESULT hr; - int nSelStartX = 0, nCaretX = 0; // Left and right X cordinates of the selection region - - CDXUTElement* pElement = GetElement( 0 ); - if( pElement ) - { - m_Buffer.SetFontNode( m_pDialog->GetFont( pElement->iFont ) ); - PlaceCaret( m_nCaret ); // Call PlaceCaret now that we have the font info (node), - // so that scrolling can be handled. - } - - // Render the control graphics - for( int e = 0; e < 9; ++e ) - { - pElement = m_Elements.GetAt( e ); - pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime ); - - m_pDialog->DrawSprite( pElement, &m_rcRender[e], DXUT_FAR_BUTTON_DEPTH ); - } - - // - // Compute the X coordinates of the first visible character. - // - int nXFirst; - m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst ); - - // - // Compute the X coordinates of the selection rectangle - // - hr = m_Buffer.CPtoX( m_nCaret, FALSE, &nCaretX ); - if( m_nCaret != m_nSelStart ) - hr = m_Buffer.CPtoX( m_nSelStart, FALSE, &nSelStartX ); - else - nSelStartX = nCaretX; - - // - // Render the selection rectangle - // - RECT rcSelection; // Make this available for rendering selected text - if( m_nCaret != m_nSelStart ) - { - int nSelLeftX = nCaretX, nSelRightX = nSelStartX; - // Swap if left is bigger than right - if( nSelLeftX > nSelRightX ) - { - int nTemp = nSelLeftX; nSelLeftX = nSelRightX; nSelRightX = nTemp; - } - - SetRect( &rcSelection, nSelLeftX, m_rcText.top, nSelRightX, m_rcText.bottom ); - OffsetRect( &rcSelection, m_rcText.left - nXFirst, 0 ); - IntersectRect( &rcSelection, &m_rcText, &rcSelection ); - - IDirect3DDevice9* pd3dDevice = m_pDialog->GetManager()->GetD3D9Device(); - if( pd3dDevice ) - pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); - m_pDialog->DrawRect( &rcSelection, m_SelBkColor ); - if( pd3dDevice ) - pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); - } - - // - // Render the text - // - // Element 0 for text - m_Elements.GetAt( 0 )->FontColor.Current = m_TextColor; - m_pDialog->DrawText( m_Buffer.GetBuffer() + m_nFirstVisible, m_Elements.GetAt( 0 ), &m_rcText ); - - // Render the selected text - if( m_nCaret != m_nSelStart ) - { - int nFirstToRender = __max( m_nFirstVisible, __min( m_nSelStart, m_nCaret ) ); - int nNumChatToRender = __max( m_nSelStart, m_nCaret ) - nFirstToRender; - m_Elements.GetAt( 0 )->FontColor.Current = m_SelTextColor; - m_pDialog->DrawText( m_Buffer.GetBuffer() + nFirstToRender, - m_Elements.GetAt( 0 ), &rcSelection, false, nNumChatToRender ); - } - - // - // Blink the caret - // - if( DXUTGetGlobalTimer()->GetAbsoluteTime() - m_dfLastBlink >= m_dfBlink ) - { - m_bCaretOn = !m_bCaretOn; - m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime(); - } - - // - // Render the caret if this control has the focus - // - if( m_bHasFocus && m_bCaretOn && !s_bHideCaret ) - { - // Start the rectangle with insert mode caret - RECT rcCaret = - { - m_rcText.left - nXFirst + nCaretX - 1, m_rcText.top, - m_rcText.left - nXFirst + nCaretX + 1, m_rcText.bottom - }; - - // If we are in overwrite mode, adjust the caret rectangle - // to fill the entire character. - if( !m_bInsertMode ) - { - // Obtain the right edge X coord of the current character - int nRightEdgeX; - m_Buffer.CPtoX( m_nCaret, TRUE, &nRightEdgeX ); - rcCaret.right = m_rcText.left - nXFirst + nRightEdgeX; - } - - m_pDialog->DrawRect( &rcCaret, m_CaretColor ); - } -} - - -#define IN_FLOAT_CHARSET( c ) \ - ( (c) == L'-' || (c) == L'.' || ( (c) >= L'0' && (c) <= L'9' ) ) - -void CDXUTEditBox::ParseFloatArray( float* pNumbers, int nCount ) -{ - int nWritten = 0; // Number of floats written - const WCHAR* pToken, *pEnd; - WCHAR wszToken[60]; - - pToken = m_Buffer.GetBuffer(); - while( nWritten < nCount && *pToken != L'\0' ) - { - // Skip leading spaces - while( *pToken == L' ' ) - ++pToken; - - if( *pToken == L'\0' ) - break; - - // Locate the end of number - pEnd = pToken; - while( IN_FLOAT_CHARSET( *pEnd ) ) - ++pEnd; - - // Copy the token to our buffer - int 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 CDXUTEditBox::SetTextFloatArray( const float* pNumbers, int nCount ) -{ - WCHAR wszBuffer[512] = - { - 0 - }; - WCHAR wszTmp[64]; - - if( pNumbers == NULL ) - return; - - for( int i = 0; i < nCount; ++i ) - { - swprintf_s( wszTmp, 64, L"%.4f ", pNumbers[i] ); - wcscat_s( wszBuffer, 512, wszTmp ); - } - - // Don't want the last space - if( nCount > 0 && wcslen( wszBuffer ) > 0 ) - wszBuffer[wcslen( wszBuffer ) - 1] = 0; - - SetText( wszBuffer ); -} - - - - -//-------------------------------------------------------------------------------------- -void CUniBuffer::Initialize() -{ - if( s_hDll ) // Only need to do once - return; - - s_hDll = LoadLibrary( UNISCRIBE_DLLNAME ); - if( s_hDll ) - { - FARPROC Temp; - GETPROCADDRESS( s_hDll, ScriptApplyDigitSubstitution, Temp ); - GETPROCADDRESS( s_hDll, ScriptStringAnalyse, Temp ); - GETPROCADDRESS( s_hDll, ScriptStringCPtoX, Temp ); - GETPROCADDRESS( s_hDll, ScriptStringXtoCP, Temp ); - GETPROCADDRESS( s_hDll, ScriptStringFree, Temp ); - GETPROCADDRESS( s_hDll, ScriptString_pLogAttr, Temp ); - GETPROCADDRESS( s_hDll, ScriptString_pcOutChars, Temp ); - } -} - - -//-------------------------------------------------------------------------------------- -void CUniBuffer::Uninitialize() -{ - if( s_hDll ) - { - PLACEHOLDERPROC( ScriptApplyDigitSubstitution ); - PLACEHOLDERPROC( ScriptStringAnalyse ); - PLACEHOLDERPROC( ScriptStringCPtoX ); - PLACEHOLDERPROC( ScriptStringXtoCP ); - PLACEHOLDERPROC( ScriptStringFree ); - PLACEHOLDERPROC( ScriptString_pLogAttr ); - PLACEHOLDERPROC( ScriptString_pcOutChars ); - - FreeLibrary( s_hDll ); - s_hDll = NULL; - } -} - - -//-------------------------------------------------------------------------------------- -bool CUniBuffer::SetBufferSize( int nNewSize ) -{ - // If the current size is already the maximum allowed, - // we can't possibly allocate more. - if( m_nBufferSize == DXUT_MAX_EDITBOXLENGTH ) - return false; - - int nAllocateSize = ( nNewSize == -1 || nNewSize < m_nBufferSize * 2 ) ? ( m_nBufferSize ? m_nBufferSize * - 2 : 256 ) : nNewSize * 2; - - // Cap the buffer size at the maximum allowed. - if( nAllocateSize > DXUT_MAX_EDITBOXLENGTH ) - nAllocateSize = DXUT_MAX_EDITBOXLENGTH; - - WCHAR* pTempBuffer = new WCHAR[nAllocateSize]; - if( !pTempBuffer ) - return false; - - ZeroMemory( pTempBuffer, sizeof( WCHAR ) * nAllocateSize ); - - if( m_pwszBuffer ) - { - CopyMemory( pTempBuffer, m_pwszBuffer, m_nBufferSize * sizeof( WCHAR ) ); - delete[] m_pwszBuffer; - } - - m_pwszBuffer = pTempBuffer; - m_nBufferSize = nAllocateSize; - return true; -} - - -//-------------------------------------------------------------------------------------- -// Uniscribe -- Analyse() analyses the string in the buffer -//-------------------------------------------------------------------------------------- -HRESULT CUniBuffer::Analyse() -{ - if( m_Analysis ) - _ScriptStringFree( &m_Analysis ); - - SCRIPT_CONTROL ScriptControl; // For uniscribe - SCRIPT_STATE ScriptState; // For uniscribe - ZeroMemory( &ScriptControl, sizeof( ScriptControl ) ); - ZeroMemory( &ScriptState, sizeof( ScriptState ) ); - _ScriptApplyDigitSubstitution( NULL, &ScriptControl, &ScriptState ); - - if( !m_pFontNode ) - return E_FAIL; - - HDC hDC = - ( m_pFontNode->pFont9 ? m_pFontNode->pFont9->GetDC() : NULL ); - HRESULT hr = _ScriptStringAnalyse( hDC, - m_pwszBuffer, - lstrlenW( m_pwszBuffer ) + 1, // NULL is also analyzed. - lstrlenW( m_pwszBuffer ) * 3 / 2 + 16, - -1, - SSA_BREAK | SSA_GLYPHS | SSA_FALLBACK | SSA_LINK, - 0, - &ScriptControl, - &ScriptState, - NULL, - NULL, - NULL, - &m_Analysis ); - if( SUCCEEDED( hr ) ) - m_bAnalyseRequired = false; // Analysis is up-to-date - return hr; -} - - -//-------------------------------------------------------------------------------------- -CUniBuffer::CUniBuffer( int nInitialSize ) -{ - CUniBuffer::Initialize(); // ensure static vars are properly init'ed first - - m_nBufferSize = 0; - m_pwszBuffer = NULL; - m_bAnalyseRequired = true; - m_Analysis = NULL; - m_pFontNode = NULL; - - if( nInitialSize > 0 ) - SetBufferSize( nInitialSize ); -} - - -//-------------------------------------------------------------------------------------- -CUniBuffer::~CUniBuffer() -{ - delete[] m_pwszBuffer; - if( m_Analysis ) - _ScriptStringFree( &m_Analysis ); -} - - -//-------------------------------------------------------------------------------------- -WCHAR& CUniBuffer::operator[]( int n ) // No param checking -{ - // This version of operator[] is called only - // if we are asking for write access, so - // re-analysis is required. - m_bAnalyseRequired = true; - return m_pwszBuffer[n]; -} - - -//-------------------------------------------------------------------------------------- -void CUniBuffer::Clear() -{ - *m_pwszBuffer = L'\0'; - m_bAnalyseRequired = true; -} - - -//-------------------------------------------------------------------------------------- -// Inserts the char at specified index. -// If nIndex == -1, insert to the end. -//-------------------------------------------------------------------------------------- -bool CUniBuffer::InsertChar( int nIndex, WCHAR wChar ) -{ - assert( nIndex >= 0 ); - - if( nIndex < 0 || nIndex > lstrlenW( m_pwszBuffer ) ) - return false; // invalid index - - // Check for maximum length allowed - if( GetTextSize() + 1 >= DXUT_MAX_EDITBOXLENGTH ) - return false; - - if( lstrlenW( m_pwszBuffer ) + 1 >= m_nBufferSize ) - { - if( !SetBufferSize( -1 ) ) - return false; // out of memory - } - - assert( m_nBufferSize >= 2 ); - - // Shift the characters after the index, start by copying the null terminator - WCHAR* dest = m_pwszBuffer + lstrlenW( m_pwszBuffer ) + 1; - WCHAR* stop = m_pwszBuffer + nIndex; - WCHAR* src = dest - 1; - - while( dest > stop ) - { - *dest-- = *src--; - } - - // Set new character - m_pwszBuffer[ nIndex ] = wChar; - m_bAnalyseRequired = true; - - return true; -} - - -//-------------------------------------------------------------------------------------- -// Removes the char at specified index. -// If nIndex == -1, remove the last char. -//-------------------------------------------------------------------------------------- -bool CUniBuffer::RemoveChar( int nIndex ) -{ - if( !lstrlenW( m_pwszBuffer ) || nIndex < 0 || nIndex >= lstrlenW( m_pwszBuffer ) ) - return false; // Invalid index - - MoveMemory( m_pwszBuffer + nIndex, m_pwszBuffer + nIndex + 1, sizeof( WCHAR ) * - ( lstrlenW( m_pwszBuffer ) - nIndex ) ); - m_bAnalyseRequired = true; - return true; -} - - -//-------------------------------------------------------------------------------------- -// Inserts the first nCount characters of the string pStr at specified index. -// If nCount == -1, the entire string is inserted. -// If nIndex == -1, insert to the end. -//-------------------------------------------------------------------------------------- -bool CUniBuffer::InsertString( int nIndex, const WCHAR* pStr, int nCount ) -{ - assert( nIndex >= 0 ); - if( nIndex < 0 ) - return false; - - if( nIndex > lstrlenW( m_pwszBuffer ) ) - return false; // invalid index - - if( -1 == nCount ) - nCount = lstrlenW( pStr ); - - // Check for maximum length allowed - if( GetTextSize() + nCount >= DXUT_MAX_EDITBOXLENGTH ) - return false; - - if( lstrlenW( m_pwszBuffer ) + nCount >= m_nBufferSize ) - { - if( !SetBufferSize( lstrlenW( m_pwszBuffer ) + nCount + 1 ) ) - return false; // out of memory - } - - MoveMemory( m_pwszBuffer + nIndex + nCount, m_pwszBuffer + nIndex, sizeof( WCHAR ) * - ( lstrlenW( m_pwszBuffer ) - nIndex + 1 ) ); - CopyMemory( m_pwszBuffer + nIndex, pStr, nCount * sizeof( WCHAR ) ); - m_bAnalyseRequired = true; - - return true; -} - - -//-------------------------------------------------------------------------------------- -bool CUniBuffer::SetText( LPCWSTR wszText ) -{ - assert( wszText != NULL ); - - int nRequired = int( wcslen( wszText ) + 1 ); - - // Check for maximum length allowed - if( nRequired >= DXUT_MAX_EDITBOXLENGTH ) - return false; - - while( GetBufferSize() < nRequired ) - if( !SetBufferSize( -1 ) ) - break; - // Check again in case out of memory occurred inside while loop. - if( GetBufferSize() >= nRequired ) - { - wcscpy_s( m_pwszBuffer, GetBufferSize(), wszText ); - m_bAnalyseRequired = true; - return true; - } - else - return false; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CUniBuffer::CPtoX( int nCP, BOOL bTrail, int* pX ) -{ - assert( pX ); - *pX = 0; // Default - - HRESULT hr = S_OK; - if( m_bAnalyseRequired ) - hr = Analyse(); - - if( SUCCEEDED( hr ) ) - hr = _ScriptStringCPtoX( m_Analysis, nCP, bTrail, pX ); - - return hr; -} - - -//-------------------------------------------------------------------------------------- -HRESULT CUniBuffer::XtoCP( int nX, int* pCP, int* pnTrail ) -{ - assert( pCP && pnTrail ); - *pCP = 0; *pnTrail = FALSE; // Default - - HRESULT hr = S_OK; - if( m_bAnalyseRequired ) - hr = Analyse(); - - if( SUCCEEDED( hr ) ) - hr = _ScriptStringXtoCP( m_Analysis, nX, pCP, pnTrail ); - - // If the coordinate falls outside the text region, we - // can get character positions that don't exist. We must - // filter them here and convert them to those that do exist. - if( *pCP == -1 && *pnTrail == TRUE ) - { - *pCP = 0; *pnTrail = FALSE; - } - else if( *pCP > lstrlenW( m_pwszBuffer ) && *pnTrail == FALSE ) - { - *pCP = lstrlenW( m_pwszBuffer ); *pnTrail = TRUE; - } - - return hr; -} - - -//-------------------------------------------------------------------------------------- -void CUniBuffer::GetPriorItemPos( int nCP, int* pPrior ) -{ - *pPrior = nCP; // Default is the char itself - - if( m_bAnalyseRequired ) - if( FAILED( Analyse() ) ) - return; - - const SCRIPT_LOGATTR* pLogAttr = _ScriptString_pLogAttr( m_Analysis ); - if( !pLogAttr ) - return; - - if( !_ScriptString_pcOutChars( m_Analysis ) ) - return; - int nInitial = *_ScriptString_pcOutChars( m_Analysis ); - if( nCP - 1 < nInitial ) - nInitial = nCP - 1; - for( int i = nInitial; i > 0; --i ) - if( pLogAttr[i].fWordStop || // Either the fWordStop flag is set - ( !pLogAttr[i].fWhiteSpace && // Or the previous char is whitespace but this isn't. - pLogAttr[i - 1].fWhiteSpace ) ) - { - *pPrior = i; - return; - } - // We have reached index 0. 0 is always a break point, so simply return it. - *pPrior = 0; -} - - -//-------------------------------------------------------------------------------------- -void CUniBuffer::GetNextItemPos( int nCP, int* pPrior ) -{ - *pPrior = nCP; // Default is the char itself - - HRESULT hr = S_OK; - if( m_bAnalyseRequired ) - hr = Analyse(); - if( FAILED( hr ) ) - return; - - const SCRIPT_LOGATTR* pLogAttr = _ScriptString_pLogAttr( m_Analysis ); - if( !pLogAttr ) - return; - - if( !_ScriptString_pcOutChars( m_Analysis ) ) - return; - int nInitial = *_ScriptString_pcOutChars( m_Analysis ); - if( nCP + 1 < nInitial ) - nInitial = nCP + 1; - - int i = nInitial; - int limit = *_ScriptString_pcOutChars( m_Analysis ); - while( limit > 0 && i < limit - 1 ) - { - if( pLogAttr[i].fWordStop ) // Either the fWordStop flag is set - { - *pPrior = i; - return; - } - else if( pLogAttr[i].fWhiteSpace && // Or this whitespace but the next char isn't. - !pLogAttr[i + 1].fWhiteSpace ) - { - *pPrior = i + 1; // The next char is a word stop - return; - } - - ++i; - limit = *_ScriptString_pcOutChars( m_Analysis ); - } - // We have reached the end. It's always a word stop, so simply return it. - *pPrior = *_ScriptString_pcOutChars( m_Analysis ) - 1; -} - - -//-------------------------------------------------------------------------------------- -void CDXUTEditBox::ResetCaretBlink() -{ - m_bCaretOn = true; - m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime(); -} - - -//-------------------------------------------------------------------------------------- -void DXUTBlendColor::Init( D3DCOLOR defaultColor, D3DCOLOR disabledColor, D3DCOLOR hiddenColor ) -{ - for( int i = 0; i < MAX_CONTROL_STATES; i++ ) - { - States[ i ] = defaultColor; - } - - States[ DXUT_STATE_DISABLED ] = disabledColor; - States[ DXUT_STATE_HIDDEN ] = hiddenColor; - Current = hiddenColor; -} - - -//-------------------------------------------------------------------------------------- -void DXUTBlendColor::Blend( UINT iState, float fElapsedTime, float fRate ) -{ - D3DXCOLOR destColor = States[ iState ]; - D3DXColorLerp( &Current, &Current, &destColor, 1.0f - powf( fRate, 30 * fElapsedTime ) ); -} - - - -//-------------------------------------------------------------------------------------- -void CDXUTElement::SetTexture( UINT iTexture, RECT* prcTexture, D3DCOLOR defaultTextureColor ) -{ - this->iTexture = iTexture; - - if( prcTexture ) - rcTexture = *prcTexture; - else - SetRectEmpty( &rcTexture ); - - TextureColor.Init( defaultTextureColor ); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTElement::SetFont( UINT iFont, D3DCOLOR defaultFontColor, DWORD dwTextFormat ) -{ - this->iFont = iFont; - this->dwTextFormat = dwTextFormat; - - FontColor.Init( defaultFontColor ); -} - - -//-------------------------------------------------------------------------------------- -void CDXUTElement::Refresh() -{ - TextureColor.Current = TextureColor.States[ DXUT_STATE_HIDDEN ]; - FontColor.Current = FontColor.States[ DXUT_STATE_HIDDEN ]; -} - - |