1 //--------------------------------------------------------------------------------------
\r
4 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
5 //--------------------------------------------------------------------------------------
\r
8 #include "DXUTsettingsDlg.h"
\r
11 #include "SDKMisc.h"
\r
13 #undef min // use __min instead
\r
14 #undef max // use __max instead
\r
16 #ifndef WM_XBUTTONDOWN
\r
17 #define WM_XBUTTONDOWN 0x020B // (not always defined)
\r
19 #ifndef WM_XBUTTONUP
\r
20 #define WM_XBUTTONUP 0x020C // (not always defined)
\r
22 #ifndef WM_MOUSEWHEEL
\r
23 #define WM_MOUSEWHEEL 0x020A // (not always defined)
\r
26 #define WHEEL_DELTA 120 // (not always defined)
\r
29 // Minimum scroll bar thumb size
\r
30 #define SCROLLBAR_MINTHUMBSIZE 8
\r
32 // Delay and repeat period when clicking on the scroll bar arrows
\r
33 #define SCROLLBAR_ARROWCLICK_DELAY 0.33
\r
34 #define SCROLLBAR_ARROWCLICK_REPEAT 0.05
\r
36 #define DXUT_NEAR_BUTTON_DEPTH 0.6f
\r
37 #define DXUT_FAR_BUTTON_DEPTH 0.8f
\r
39 #define DXUT_MAX_GUI_SPRITES 500
\r
41 D3DCOLORVALUE D3DCOLOR_TO_D3DCOLORVALUE( D3DCOLOR c )
\r
45 ( ( c >> 16 ) & 0xFF ) / 255.0f,
\r
46 ( ( c >> 8 ) & 0xFF ) / 255.0f,
\r
47 ( c & 0xFF ) / 255.0f,
\r
48 ( ( c >> 24 ) & 0xFF ) / 255.0f
\r
53 #define UNISCRIBE_DLLNAME L"usp10.dll"
\r
55 #define GETPROCADDRESS( Module, APIName, Temp ) \
\r
56 Temp = GetProcAddress( Module, #APIName ); \
\r
58 *(FARPROC*)&_##APIName = Temp
\r
60 #define PLACEHOLDERPROC( APIName ) \
\r
61 _##APIName = Dummy_##APIName
\r
63 #define IMM32_DLLNAME L"imm32.dll"
\r
64 #define VER_DLLNAME L"version.dll"
\r
66 CHAR g_strUIEffectFile[] = \
\r
67 "Texture2D g_Texture;"\
\r
69 "SamplerState Sampler"\
\r
71 " Filter = MIN_MAG_MIP_LINEAR;"\
\r
72 " AddressU = Wrap;"\
\r
73 " AddressV = Wrap;"\
\r
76 "BlendState UIBlend"\
\r
78 " AlphaToCoverageEnable = FALSE;"\
\r
79 " BlendEnable[0] = TRUE;"\
\r
80 " SrcBlend = SRC_ALPHA;"\
\r
81 " DestBlend = INV_SRC_ALPHA;"\
\r
83 " SrcBlendAlpha = ONE;"\
\r
84 " DestBlendAlpha = ZERO;"\
\r
85 " BlendOpAlpha = ADD;"\
\r
86 " RenderTargetWriteMask[0] = 0x0F;"\
\r
89 "BlendState NoBlending"\
\r
91 " BlendEnable[0] = FALSE;"\
\r
92 " RenderTargetWriteMask[0] = 0x0F;"\
\r
95 "DepthStencilState DisableDepth"\
\r
97 " DepthEnable = false;"\
\r
99 "DepthStencilState EnableDepth"\
\r
101 " DepthEnable = true;"\
\r
103 "struct VS_OUTPUT"\
\r
105 " float4 Pos : POSITION;"\
\r
106 " float4 Dif : COLOR;"\
\r
107 " float2 Tex : TEXCOORD;"\
\r
110 "VS_OUTPUT VS( float3 vPos : POSITION,"\
\r
111 " float4 Dif : COLOR,"\
\r
112 " float2 vTexCoord0 : TEXCOORD )"\
\r
114 " VS_OUTPUT Output;"\
\r
116 " Output.Pos = float4( vPos, 1.0f );"\
\r
117 " Output.Dif = Dif;"\
\r
118 " Output.Tex = vTexCoord0;"\
\r
123 "float4 PS( VS_OUTPUT In ) : SV_Target"\
\r
125 " return g_Texture.Sample( Sampler, In.Tex ) * In.Dif;"\
\r
128 "float4 PSUntex( VS_OUTPUT In ) : SV_Target"\
\r
133 "technique10 RenderUI"\
\r
137 " SetVertexShader( CompileShader( vs_4_0, VS() ) );"\
\r
138 " SetGeometryShader( NULL );"\
\r
139 " SetPixelShader( CompileShader( ps_4_0, PS() ) );"\
\r
140 " SetDepthStencilState( DisableDepth, 0 );"\
\r
141 " SetBlendState( UIBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\
\r
144 "technique10 RenderUIUntex"\
\r
148 " SetVertexShader( CompileShader( vs_4_0, VS() ) );"\
\r
149 " SetGeometryShader( NULL );"\
\r
150 " SetPixelShader( CompileShader( ps_4_0, PSUntex() ) );"\
\r
151 " SetDepthStencilState( DisableDepth, 0 );"\
\r
152 " SetBlendState( UIBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\
\r
155 "technique10 RestoreState"\
\r
159 " SetDepthStencilState( EnableDepth, 0 );"\
\r
160 " SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );"\
\r
163 const UINT g_uUIEffectFileSize = sizeof( g_strUIEffectFile );
\r
166 // DXUT_MAX_EDITBOXLENGTH is the maximum string length allowed in edit boxes,
\r
167 // including the NULL terminator.
\r
169 // Uniscribe does not support strings having bigger-than-16-bits length.
\r
170 // This means that the string must be less than 65536 characters long,
\r
171 // including the NULL terminator.
\r
172 #define DXUT_MAX_EDITBOXLENGTH 0xFFFF
\r
175 double CDXUTDialog::s_fTimeRefresh = 0.0f;
\r
176 CDXUTControl* CDXUTDialog::s_pControlFocus = NULL; // The control which has focus
\r
177 CDXUTControl* CDXUTDialog::s_pControlPressed = NULL; // The control currently pressed
\r
180 struct DXUT_SCREEN_VERTEX
\r
188 DWORD DXUT_SCREEN_VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
\r
191 struct DXUT_SCREEN_VERTEX_UNTEX
\r
198 DWORD DXUT_SCREEN_VERTEX_UNTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE;
\r
201 struct DXUT_SCREEN_VERTEX_10
\r
204 D3DCOLORVALUE color;
\r
209 inline int RectWidth( RECT& rc )
\r
211 return ( ( rc ).right - ( rc ).left );
\r
213 inline int RectHeight( RECT& rc )
\r
215 return ( ( rc ).bottom - ( rc ).top );
\r
219 HRESULT InitFont11( ID3D11Device* pd3d11Device, ID3D11InputLayout* pInputLayout );
\r
222 //--------------------------------------------------------------------------------------
\r
223 // CDXUTDialog class
\r
224 //--------------------------------------------------------------------------------------
\r
226 //--------------------------------------------------------------------------------------
\r
227 CDXUTDialog::CDXUTDialog()
\r
236 m_bCaption = false;
\r
237 m_bMinimized = false;
\r
239 m_wszCaption[0] = L'\0';
\r
240 m_nCaptionHeight = 18;
\r
242 m_colorTopLeft = 0;
\r
243 m_colorTopRight = 0;
\r
244 m_colorBottomLeft = 0;
\r
245 m_colorBottomRight = 0;
\r
247 m_pCallbackEvent = NULL;
\r
248 m_pCallbackEventUserContext = NULL;
\r
250 m_fTimeLastRefresh = 0;
\r
252 m_pControlMouseOver = NULL;
\r
254 m_pNextDialog = this;
\r
255 m_pPrevDialog = this;
\r
257 m_nDefaultControlID = 0xffff;
\r
258 m_bNonUserEvents = false;
\r
259 m_bKeyboardInput = false;
\r
260 m_bMouseInput = true;
\r
264 //--------------------------------------------------------------------------------------
\r
265 CDXUTDialog::~CDXUTDialog()
\r
269 RemoveAllControls();
\r
271 m_Fonts.RemoveAll();
\r
272 m_Textures.RemoveAll();
\r
274 for( i = 0; i < m_DefaultElements.GetSize(); i++ )
\r
276 DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
\r
277 SAFE_DELETE( pElementHolder );
\r
280 m_DefaultElements.RemoveAll();
\r
284 //--------------------------------------------------------------------------------------
\r
285 void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog )
\r
287 m_pManager = pManager;
\r
288 if( bRegisterDialog )
\r
289 pManager->RegisterDialog( this );
\r
291 SetTexture( 0, MAKEINTRESOURCE( 0xFFFF ), ( HMODULE )0xFFFF );
\r
292 InitDefaultElements();
\r
296 //--------------------------------------------------------------------------------------
\r
297 void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, LPCWSTR pszControlTextureFilename )
\r
299 m_pManager = pManager;
\r
300 if( bRegisterDialog )
\r
301 pManager->RegisterDialog( this );
\r
302 SetTexture( 0, pszControlTextureFilename );
\r
303 InitDefaultElements();
\r
307 //--------------------------------------------------------------------------------------
\r
308 void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog,
\r
309 LPCWSTR szControlTextureResourceName, HMODULE hControlTextureResourceModule )
\r
311 m_pManager = pManager;
\r
312 if( bRegisterDialog )
\r
313 pManager->RegisterDialog( this );
\r
315 SetTexture( 0, szControlTextureResourceName, hControlTextureResourceModule );
\r
316 InitDefaultElements();
\r
320 //--------------------------------------------------------------------------------------
\r
321 void CDXUTDialog::SetCallback( PCALLBACKDXUTGUIEVENT pCallback, void* pUserContext )
\r
323 // If this assert triggers, you need to call CDXUTDialog::Init() first. This change
\r
324 // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
\r
325 // creation and interfacing with CDXUTDialogResourceManager is now the responsibility
\r
326 // of the application if it wishes to use DXUT's GUI.
\r
327 assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first. See comments for details." );
\r
329 m_pCallbackEvent = pCallback;
\r
330 m_pCallbackEventUserContext = pUserContext;
\r
334 //--------------------------------------------------------------------------------------
\r
335 void CDXUTDialog::RemoveControl( int ID )
\r
337 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
339 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
340 if( pControl->GetID() == ID )
\r
342 // Clean focus first
\r
345 // Clear references to this control
\r
346 if( s_pControlFocus == pControl )
\r
347 s_pControlFocus = NULL;
\r
348 if( s_pControlPressed == pControl )
\r
349 s_pControlPressed = NULL;
\r
350 if( m_pControlMouseOver == pControl )
\r
351 m_pControlMouseOver = NULL;
\r
353 SAFE_DELETE( pControl );
\r
354 m_Controls.Remove( i );
\r
362 //--------------------------------------------------------------------------------------
\r
363 void CDXUTDialog::RemoveAllControls()
\r
365 if( s_pControlFocus && s_pControlFocus->m_pDialog == this )
\r
366 s_pControlFocus = NULL;
\r
367 if( s_pControlPressed && s_pControlPressed->m_pDialog == this )
\r
368 s_pControlPressed = NULL;
\r
369 m_pControlMouseOver = NULL;
\r
371 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
373 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
374 SAFE_DELETE( pControl );
\r
377 m_Controls.RemoveAll();
\r
381 //--------------------------------------------------------------------------------------
\r
382 CDXUTDialogResourceManager::CDXUTDialogResourceManager()
\r
384 // Begin D3D9-specific
\r
385 m_pd3d9Device = NULL;
\r
386 m_pStateBlock = NULL;
\r
389 // Begin D3D11-specific
\r
391 m_pVSRenderUI11 = NULL;
\r
392 m_pPSRenderUI11 = NULL;
\r
393 m_pPSRenderUIUntex11 = NULL;
\r
396 m_pDepthStencilStateUI11 = NULL;
\r
397 m_pRasterizerStateUI11 = NULL;
\r
398 m_pBlendStateUI11 = NULL;
\r
399 m_pSamplerStateUI11 = NULL;
\r
400 m_pDepthStencilStateStored11 = NULL;
\r
401 m_pRasterizerStateStored11 = NULL;
\r
402 m_pBlendStateStored11 = NULL;
\r
403 m_pSamplerStateStored11 = NULL;
\r
405 m_pInputLayout11 = NULL;
\r
406 m_pVBScreenQuad11 = NULL;
\r
407 m_pSpriteBuffer11 = NULL;
\r
411 //--------------------------------------------------------------------------------------
\r
412 CDXUTDialogResourceManager::~CDXUTDialogResourceManager()
\r
415 for( i = 0; i < m_FontCache.GetSize(); i++ )
\r
417 DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
\r
418 SAFE_DELETE( pFontNode );
\r
420 m_FontCache.RemoveAll();
\r
422 for( i = 0; i < m_TextureCache.GetSize(); i++ )
\r
424 DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
\r
425 SAFE_DELETE( pTextureNode );
\r
427 m_TextureCache.RemoveAll();
\r
429 CUniBuffer::Uninitialize();
\r
433 //--------------------------------------------------------------------------------------
\r
434 HRESULT CDXUTDialogResourceManager::OnD3D9CreateDevice( LPDIRECT3DDEVICE9 pd3dDevice )
\r
439 m_pd3d9Device = pd3dDevice;
\r
441 for( i = 0; i < m_FontCache.GetSize(); i++ )
\r
443 hr = CreateFont9( i );
\r
448 for( i = 0; i < m_TextureCache.GetSize(); i++ )
\r
450 hr = CreateTexture9( i );
\r
455 hr = D3DXCreateSprite( pd3dDevice, &m_pSprite );
\r
457 return DXUT_ERR( L"D3DXCreateSprite", hr );
\r
463 //--------------------------------------------------------------------------------------
\r
464 HRESULT CDXUTDialogResourceManager::OnD3D9ResetDevice()
\r
468 for( int i = 0; i < m_FontCache.GetSize(); i++ )
\r
470 DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
\r
472 if( pFontNode->pFont9 )
\r
473 pFontNode->pFont9->OnResetDevice();
\r
477 m_pSprite->OnResetDevice();
\r
479 V_RETURN( m_pd3d9Device->CreateStateBlock( D3DSBT_ALL, &m_pStateBlock ) );
\r
484 //--------------------------------------------------------------------------------------
\r
485 bool CDXUTDialogResourceManager::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
491 //--------------------------------------------------------------------------------------
\r
492 void CDXUTDialogResourceManager::OnD3D9LostDevice()
\r
494 for( int i = 0; i < m_FontCache.GetSize(); i++ )
\r
496 DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
\r
498 if( pFontNode->pFont9 )
\r
499 pFontNode->pFont9->OnLostDevice();
\r
503 m_pSprite->OnLostDevice();
\r
505 SAFE_RELEASE( m_pStateBlock );
\r
509 //--------------------------------------------------------------------------------------
\r
510 void CDXUTDialogResourceManager::OnD3D9DestroyDevice()
\r
514 m_pd3d9Device = NULL;
\r
516 // Release the resources but don't clear the cache, as these will need to be
\r
517 // recreated if the device is recreated
\r
518 for( i = 0; i < m_FontCache.GetSize(); i++ )
\r
520 DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
\r
521 SAFE_RELEASE( pFontNode->pFont9 );
\r
524 for( i = 0; i < m_TextureCache.GetSize(); i++ )
\r
526 DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
\r
527 SAFE_RELEASE( pTextureNode->pTexture9 );
\r
530 SAFE_RELEASE( m_pSprite );
\r
535 HRESULT CDXUTDialogResourceManager::OnD3D11CreateDevice( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext )
\r
537 m_pd3d11Device = pd3dDevice;
\r
538 m_pd3d11DeviceContext = pd3d11DeviceContext;
\r
543 ID3DBlob* pVSBlob = NULL;
\r
544 ID3DBlob* pPSBlob = NULL;
\r
545 ID3DBlob* pPSUntexBlob = NULL;
\r
546 V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "VS", "vs_4_0_level_9_1",
\r
547 D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pVSBlob, NULL ) );
\r
548 V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "PS", "ps_4_0_level_9_1",
\r
549 D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pPSBlob, NULL ) );
\r
550 V_RETURN( D3DCompile( g_strUIEffectFile, g_uUIEffectFileSize, "none", NULL, NULL, "PSUntex", "ps_4_0_level_9_1",
\r
551 D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY, 0, &pPSUntexBlob, NULL ) );
\r
552 //D3D10_SHADER_ENABLE_STRICTNESS
\r
555 V_RETURN( pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &m_pVSRenderUI11 ) );
\r
556 V_RETURN( pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &m_pPSRenderUI11 ) );
\r
557 V_RETURN( pd3dDevice->CreatePixelShader( pPSUntexBlob->GetBufferPointer(), pPSUntexBlob->GetBufferSize(), NULL, &m_pPSRenderUIUntex11 ) );
\r
560 D3D11_DEPTH_STENCIL_DESC DSDesc;
\r
561 ZeroMemory( &DSDesc, sizeof( D3D11_DEPTH_STENCIL_DESC ) );
\r
562 DSDesc.DepthEnable = FALSE;
\r
563 DSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
\r
564 DSDesc.DepthFunc = D3D11_COMPARISON_LESS;
\r
565 DSDesc.StencilEnable = FALSE;
\r
566 V_RETURN( pd3dDevice->CreateDepthStencilState( &DSDesc, &m_pDepthStencilStateUI11 ) );
\r
568 D3D11_RASTERIZER_DESC RSDesc;
\r
569 RSDesc.AntialiasedLineEnable = FALSE;
\r
570 RSDesc.CullMode = D3D11_CULL_BACK;
\r
571 RSDesc.DepthBias = 0;
\r
572 RSDesc.DepthBiasClamp = 0.0f;
\r
573 RSDesc.DepthClipEnable = TRUE;
\r
574 RSDesc.FillMode = D3D11_FILL_SOLID;
\r
575 RSDesc.FrontCounterClockwise = FALSE;
\r
576 RSDesc.MultisampleEnable = TRUE;
\r
577 RSDesc.ScissorEnable = FALSE;
\r
578 RSDesc.SlopeScaledDepthBias = 0.0f;
\r
579 V_RETURN( pd3dDevice->CreateRasterizerState( &RSDesc, &m_pRasterizerStateUI11 ) );
\r
581 D3D11_BLEND_DESC BSDesc;
\r
582 ZeroMemory( &BSDesc, sizeof( D3D11_BLEND_DESC ) );
\r
584 BSDesc.RenderTarget[0].BlendEnable = TRUE;
\r
585 BSDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
\r
586 BSDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
\r
587 BSDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
\r
588 BSDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
\r
589 BSDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
\r
590 BSDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
\r
591 BSDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F;
\r
593 V_RETURN( pd3dDevice->CreateBlendState( &BSDesc, &m_pBlendStateUI11 ) );
\r
595 D3D11_SAMPLER_DESC SSDesc;
\r
596 ZeroMemory( &SSDesc, sizeof( D3D11_SAMPLER_DESC ) );
\r
597 SSDesc.Filter = D3D11_FILTER_ANISOTROPIC ;
\r
598 SSDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
\r
599 SSDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
\r
600 SSDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
\r
601 SSDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
\r
602 SSDesc.MaxAnisotropy = 16;
\r
604 SSDesc.MaxLOD = D3D11_FLOAT32_MAX;
\r
605 if ( pd3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3 ) {
\r
606 SSDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
\r
607 SSDesc.MaxAnisotropy = 0;
\r
609 V_RETURN( pd3dDevice->CreateSamplerState( &SSDesc, &m_pSamplerStateUI11 ) );
\r
611 // Create the font and texture objects in the cache arrays.
\r
613 for( i = 0; i < m_FontCache.GetSize(); i++ )
\r
615 hr = CreateFont11( i );
\r
620 for( i = 0; i < m_TextureCache.GetSize(); i++ )
\r
622 hr = CreateTexture11( i );
\r
627 // Create input layout
\r
628 const D3D11_INPUT_ELEMENT_DESC layout[] =
\r
630 { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
\r
631 { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
\r
632 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
\r
635 V_RETURN( pd3dDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &m_pInputLayout11 ) );
\r
637 // Release the blobs
\r
638 SAFE_RELEASE( pVSBlob );
\r
639 SAFE_RELEASE( pPSBlob );
\r
640 SAFE_RELEASE( pPSUntexBlob );
\r
642 // Create a vertex buffer quad for rendering later
\r
643 D3D11_BUFFER_DESC BufDesc;
\r
644 BufDesc.ByteWidth = sizeof( DXUT_SCREEN_VERTEX_10 ) * 4;
\r
645 BufDesc.Usage = D3D11_USAGE_DYNAMIC;
\r
646 BufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
\r
647 BufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
\r
648 BufDesc.MiscFlags = 0;
\r
649 V_RETURN( pd3dDevice->CreateBuffer( &BufDesc, NULL, &m_pVBScreenQuad11 ) );
\r
651 // Init the D3D11 font
\r
652 InitFont11( pd3dDevice, m_pInputLayout11 );
\r
658 //--------------------------------------------------------------------------------------
\r
659 HRESULT CDXUTDialogResourceManager::OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice,
\r
660 const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc )
\r
664 m_nBackBufferWidth = pBackBufferSurfaceDesc->Width;
\r
665 m_nBackBufferHeight = pBackBufferSurfaceDesc->Height;
\r
671 //--------------------------------------------------------------------------------------
\r
672 void CDXUTDialogResourceManager::OnD3D11ReleasingSwapChain()
\r
677 //--------------------------------------------------------------------------------------
\r
678 void CDXUTDialogResourceManager::OnD3D11DestroyDevice()
\r
682 // Release the resources but don't clear the cache, as these will need to be
\r
683 // recreated if the device is recreated
\r
685 for( i = 0; i < m_TextureCache.GetSize(); i++ )
\r
687 DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
\r
688 SAFE_RELEASE( pTextureNode->pTexResView11 );
\r
689 SAFE_RELEASE( pTextureNode->pTexture11 );
\r
693 SAFE_RELEASE( m_pVBScreenQuad11 );
\r
694 SAFE_RELEASE( m_pSpriteBuffer11 );
\r
695 m_SpriteBufferBytes11 = 0;
\r
696 SAFE_RELEASE( m_pInputLayout11 );
\r
699 SAFE_RELEASE( m_pVSRenderUI11 );
\r
700 SAFE_RELEASE( m_pPSRenderUI11 );
\r
701 SAFE_RELEASE( m_pPSRenderUIUntex11 );
\r
704 SAFE_RELEASE( m_pDepthStencilStateUI11 );
\r
705 SAFE_RELEASE( m_pRasterizerStateUI11 );
\r
706 SAFE_RELEASE( m_pBlendStateUI11 );
\r
707 SAFE_RELEASE( m_pSamplerStateUI11 );
\r
709 SAFE_RELEASE( m_pDepthStencilStateStored11 );
\r
710 SAFE_RELEASE( m_pRasterizerStateStored11 );
\r
711 SAFE_RELEASE( m_pBlendStateStored11 );
\r
712 SAFE_RELEASE( m_pSamplerStateStored11 );
\r
717 //--------------------------------------------------------------------------------------
\r
718 void CDXUTDialogResourceManager::StoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext )
\r
720 pd3dImmediateContext->OMGetDepthStencilState( &m_pDepthStencilStateStored11, &m_StencilRefStored11 );
\r
721 pd3dImmediateContext->RSGetState( &m_pRasterizerStateStored11 );
\r
722 pd3dImmediateContext->OMGetBlendState( &m_pBlendStateStored11, m_BlendFactorStored11, &m_SampleMaskStored11 );
\r
723 pd3dImmediateContext->PSGetSamplers( 0, 1, &m_pSamplerStateStored11 );
\r
726 //--------------------------------------------------------------------------------------
\r
727 void CDXUTDialogResourceManager::RestoreD3D11State( ID3D11DeviceContext* pd3dImmediateContext )
\r
729 pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateStored11, m_StencilRefStored11 );
\r
730 pd3dImmediateContext->RSSetState( m_pRasterizerStateStored11 );
\r
731 pd3dImmediateContext->OMSetBlendState( m_pBlendStateStored11, m_BlendFactorStored11, m_SampleMaskStored11 );
\r
732 pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateStored11 );
\r
734 SAFE_RELEASE( m_pDepthStencilStateStored11 );
\r
735 SAFE_RELEASE( m_pRasterizerStateStored11 );
\r
736 SAFE_RELEASE( m_pBlendStateStored11 );
\r
737 SAFE_RELEASE( m_pSamplerStateStored11 );
\r
740 //--------------------------------------------------------------------------------------
\r
741 void CDXUTDialogResourceManager::ApplyRenderUI11( ID3D11DeviceContext* pd3dImmediateContext )
\r
744 pd3dImmediateContext->VSSetShader( m_pVSRenderUI11, NULL, 0 );
\r
745 pd3dImmediateContext->HSSetShader( NULL, NULL, 0 );
\r
746 pd3dImmediateContext->DSSetShader( NULL, NULL, 0 );
\r
747 pd3dImmediateContext->GSSetShader( NULL, NULL, 0 );
\r
748 pd3dImmediateContext->PSSetShader( m_pPSRenderUI11, NULL, 0 );
\r
751 pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateUI11, 0 );
\r
752 pd3dImmediateContext->RSSetState( m_pRasterizerStateUI11 );
\r
753 float BlendFactor[4] = { 0, 0, 0, 0 };
\r
754 pd3dImmediateContext->OMSetBlendState( m_pBlendStateUI11, BlendFactor, 0xFFFFFFFF );
\r
755 pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateUI11 );
\r
758 //--------------------------------------------------------------------------------------
\r
759 void CDXUTDialogResourceManager::ApplyRenderUIUntex11( ID3D11DeviceContext* pd3dImmediateContext )
\r
762 pd3dImmediateContext->VSSetShader( m_pVSRenderUI11, NULL, 0 );
\r
763 pd3dImmediateContext->HSSetShader( NULL, NULL, 0 );
\r
764 pd3dImmediateContext->DSSetShader( NULL, NULL, 0 );
\r
765 pd3dImmediateContext->GSSetShader( NULL, NULL, 0 );
\r
766 pd3dImmediateContext->PSSetShader( m_pPSRenderUIUntex11, NULL, 0 );
\r
769 pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilStateUI11, 0 );
\r
770 pd3dImmediateContext->RSSetState( m_pRasterizerStateUI11 );
\r
771 float BlendFactor[4] = { 0, 0, 0, 0 };
\r
772 pd3dImmediateContext->OMSetBlendState( m_pBlendStateUI11, BlendFactor, 0xFFFFFFFF );
\r
773 pd3dImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerStateUI11 );
\r
776 //--------------------------------------------------------------------------------------
\r
777 void CDXUTDialogResourceManager::BeginSprites11( )
\r
779 m_SpriteVertices.Reset();
\r
782 //--------------------------------------------------------------------------------------
\r
783 void CDXUTDialogResourceManager::EndSprites11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext )
\r
786 // ensure our buffer size can hold our sprites
\r
787 UINT SpriteDataBytes = m_SpriteVertices.GetSize() * sizeof( DXUTSpriteVertex );
\r
788 if( m_SpriteBufferBytes11 < SpriteDataBytes )
\r
790 SAFE_RELEASE( m_pSpriteBuffer11 );
\r
791 m_SpriteBufferBytes11 = SpriteDataBytes;
\r
793 D3D11_BUFFER_DESC BufferDesc;
\r
794 BufferDesc.ByteWidth = m_SpriteBufferBytes11;
\r
795 BufferDesc.Usage = D3D11_USAGE_DYNAMIC;
\r
796 BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
\r
797 BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
\r
798 BufferDesc.MiscFlags = 0;
\r
800 pd3dDevice->CreateBuffer( &BufferDesc, NULL, &m_pSpriteBuffer11 );
\r
803 // Copy the sprites over
\r
804 D3D11_BOX destRegion;
\r
805 destRegion.left = 0;
\r
806 destRegion.right = SpriteDataBytes;
\r
807 destRegion.top = 0;
\r
808 destRegion.bottom = 1;
\r
809 destRegion.front = 0;
\r
810 destRegion.back = 1;
\r
811 D3D11_MAPPED_SUBRESOURCE MappedResource;
\r
812 if ( S_OK == pd3dImmediateContext->Map( m_pSpriteBuffer11, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) {
\r
813 CopyMemory( MappedResource.pData, (void*)m_SpriteVertices.GetData(), SpriteDataBytes );
\r
814 pd3dImmediateContext->Unmap(m_pSpriteBuffer11, 0);
\r
818 UINT Stride = sizeof( DXUTSpriteVertex );
\r
820 pd3dImmediateContext->IASetVertexBuffers( 0, 1, &m_pSpriteBuffer11, &Stride, &Offset );
\r
821 pd3dImmediateContext->IASetInputLayout( m_pInputLayout11 );
\r
822 pd3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
\r
823 pd3dImmediateContext->Draw( m_SpriteVertices.GetSize(), 0 );
\r
825 m_SpriteVertices.Reset();
\r
828 //--------------------------------------------------------------------------------------
\r
829 bool CDXUTDialogResourceManager::RegisterDialog( CDXUTDialog* pDialog )
\r
831 // Check that the dialog isn't already registered.
\r
832 for( int i = 0; i < m_Dialogs.GetSize(); ++i )
\r
833 if( m_Dialogs.GetAt( i ) == pDialog )
\r
836 // Add to the list.
\r
837 if( FAILED( m_Dialogs.Add( pDialog ) ) )
\r
840 // Set up next and prev pointers.
\r
841 if( m_Dialogs.GetSize() > 1 )
\r
842 m_Dialogs[m_Dialogs.GetSize() - 2]->SetNextDialog( pDialog );
\r
843 m_Dialogs[m_Dialogs.GetSize() - 1]->SetNextDialog( m_Dialogs[0] );
\r
849 //--------------------------------------------------------------------------------------
\r
850 void CDXUTDialogResourceManager::UnregisterDialog( CDXUTDialog* pDialog )
\r
852 // Search for the dialog in the list.
\r
853 for( int i = 0; i < m_Dialogs.GetSize(); ++i )
\r
854 if( m_Dialogs.GetAt( i ) == pDialog )
\r
856 m_Dialogs.Remove( i );
\r
857 if( m_Dialogs.GetSize() > 0 )
\r
862 l = m_Dialogs.GetSize() - 1;
\r
866 if( m_Dialogs.GetSize() == i )
\r
871 m_Dialogs[l]->SetNextDialog( m_Dialogs[r] );
\r
878 //--------------------------------------------------------------------------------------
\r
879 void CDXUTDialogResourceManager::EnableKeyboardInputForAllDialogs()
\r
881 // Enable keyboard input for all registered dialogs
\r
882 for( int i = 0; i < m_Dialogs.GetSize(); ++i )
\r
883 m_Dialogs[i]->EnableKeyboardInput( true );
\r
887 //--------------------------------------------------------------------------------------
\r
888 void CDXUTDialog::Refresh()
\r
890 if( s_pControlFocus )
\r
891 s_pControlFocus->OnFocusOut();
\r
893 if( m_pControlMouseOver )
\r
894 m_pControlMouseOver->OnMouseLeave();
\r
896 s_pControlFocus = NULL;
\r
897 s_pControlPressed = NULL;
\r
898 m_pControlMouseOver = NULL;
\r
900 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
902 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
903 pControl->Refresh();
\r
906 if( m_bKeyboardInput )
\r
907 FocusDefaultControl();
\r
911 //--------------------------------------------------------------------------------------
\r
912 HRESULT CDXUTDialog::OnRender( float fElapsedTime )
\r
914 if( m_pManager->GetD3D9Device() )
\r
915 return OnRender9( fElapsedTime );
\r
917 return OnRender11( fElapsedTime );
\r
921 //--------------------------------------------------------------------------------------
\r
922 HRESULT CDXUTDialog::OnRender9( float fElapsedTime )
\r
924 // If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside
\r
925 // the application's device callbacks. See the SDK samples for an example of how to do this.
\r
926 assert( m_pManager->GetD3D9Device() && m_pManager->m_pStateBlock &&
\r
927 L"To fix hook up CDXUTDialogResourceManager to device callbacks. See comments for details" );
\r
929 // See if the dialog needs to be refreshed
\r
930 if( m_fTimeLastRefresh < s_fTimeRefresh )
\r
932 m_fTimeLastRefresh = DXUTGetTime();
\r
936 // For invisible dialog, out now.
\r
938 ( m_bMinimized && !m_bCaption ) )
\r
941 IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device();
\r
943 // Set up a state block here and restore it when finished drawing all the controls
\r
944 m_pManager->m_pStateBlock->Capture();
\r
946 //pd3dDevice->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, TRUE);
\r
947 //pd3dDevice->SetRenderState( D3DRS_SRGBWRITEENABLE, TRUE );
\r
949 pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
\r
950 pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
\r
951 pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
\r
952 pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
\r
953 pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, FALSE );
\r
954 pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
\r
955 pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE |
\r
956 D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED );
\r
957 pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
\r
958 pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
\r
959 pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
\r
960 pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
\r
961 pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
\r
963 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
\r
964 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
\r
965 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
\r
966 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
\r
967 pd3dDevice->SetTextureStageState( 0, D3DTSS_RESULTARG, D3DTA_CURRENT );
\r
968 pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
\r
969 pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
\r
971 BOOL bBackgroundIsVisible = ( m_colorTopLeft | m_colorTopRight | m_colorBottomRight | m_colorBottomLeft ) &
\r
973 if( !m_bMinimized && bBackgroundIsVisible )
\r
975 DXUT_SCREEN_VERTEX_UNTEX vertices[4] =
\r
977 ( float )m_x, ( float )m_y, 0.5f, 1.0f, m_colorTopLeft,
\r
978 ( float )m_x + m_width, ( float )m_y, 0.5f, 1.0f, m_colorTopRight,
\r
979 ( float )m_x + m_width, ( float )m_y + m_height, 0.5f, 1.0f, m_colorBottomRight,
\r
980 ( float )m_x, ( float )m_y + m_height, 0.5f, 1.0f, m_colorBottomLeft,
\r
983 pd3dDevice->SetVertexShader( NULL );
\r
984 pd3dDevice->SetPixelShader( NULL );
\r
986 pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
\r
988 pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX_UNTEX::FVF );
\r
989 pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof( DXUT_SCREEN_VERTEX_UNTEX ) );
\r
992 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
\r
993 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
\r
994 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
\r
996 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
\r
997 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
\r
998 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
\r
1000 pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
\r
1002 DXUTTextureNode* pTextureNode = GetTexture( 0 );
\r
1003 pd3dDevice->SetTexture( 0, pTextureNode->pTexture9 );
\r
1005 m_pManager->m_pSprite->Begin( D3DXSPRITE_DONOTSAVESTATE );
\r
1007 // Render the caption if it's enabled.
\r
1010 // DrawSprite will offset the rect down by
\r
1011 // m_nCaptionHeight, so adjust the rect higher
\r
1012 // here to negate the effect.
\r
1015 0, -m_nCaptionHeight, m_width, 0
\r
1017 DrawSprite9( &m_CapElement, &rc );
\r
1018 rc.left += 5; // Make a left margin
\r
1019 WCHAR wszOutput[256];
\r
1020 wcscpy_s( wszOutput, 256, m_wszCaption );
\r
1021 if( m_bMinimized )
\r
1022 wcscat_s( wszOutput, 256, L" (Minimized)" );
\r
1023 DrawText9( wszOutput, &m_CapElement, &rc, true );
\r
1026 // If the dialog is minimized, skip rendering
\r
1028 if( !m_bMinimized )
\r
1030 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
1032 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
1034 // Focused control is drawn last
\r
1035 if( pControl == s_pControlFocus )
\r
1038 pControl->Render( fElapsedTime );
\r
1041 if( s_pControlFocus != NULL && s_pControlFocus->m_pDialog == this )
\r
1042 s_pControlFocus->Render( fElapsedTime );
\r
1045 m_pManager->m_pSprite->End();
\r
1047 m_pManager->m_pStateBlock->Apply();
\r
1054 //--------------------------------------------------------------------------------------
\r
1055 HRESULT CDXUTDialog::OnRender11( float fElapsedTime )
\r
1057 // If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside
\r
1058 // the application's device callbacks. See the SDK samples for an example of how to do this.
\r
1059 assert( m_pManager->GetD3D11Device() &&
\r
1060 L"To fix hook up CDXUTDialogResourceManager to device callbacks. See comments for details" );
\r
1062 // See if the dialog needs to be refreshed
\r
1063 if( m_fTimeLastRefresh < s_fTimeRefresh )
\r
1065 m_fTimeLastRefresh = DXUTGetTime();
\r
1069 // For invisible dialog, out now.
\r
1070 if( !m_bVisible ||
\r
1071 ( m_bMinimized && !m_bCaption ) )
\r
1074 ID3D11Device* pd3dDevice = m_pManager->GetD3D11Device();
\r
1075 ID3D11DeviceContext* pd3dDeviceContext = m_pManager->GetD3D11DeviceContext();
\r
1077 // Set up a state block here and restore it when finished drawing all the controls
\r
1078 m_pManager->StoreD3D11State( pd3dDeviceContext );
\r
1080 BOOL bBackgroundIsVisible = ( m_colorTopLeft | m_colorTopRight | m_colorBottomRight | m_colorBottomLeft ) &
\r
1082 if( !m_bMinimized && bBackgroundIsVisible )
\r
1084 // Convert the draw rectangle from screen coordinates to clip space coordinates.
\r
1085 float Left, Right, Top, Bottom;
\r
1086 Left = m_x * 2.0f / m_pManager->m_nBackBufferWidth - 1.0f;
\r
1087 Right = ( m_x + m_width ) * 2.0f / m_pManager->m_nBackBufferWidth - 1.0f;
\r
1088 Top = 1.0f - m_y * 2.0f / m_pManager->m_nBackBufferHeight;
\r
1089 Bottom = 1.0f - ( m_y + m_height ) * 2.0f / m_pManager->m_nBackBufferHeight;
\r
1091 DXUT_SCREEN_VERTEX_10 vertices[4] =
\r
1093 Left, Top, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorTopLeft ), 0.0f, 0.0f,
\r
1094 Right, Top, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorTopRight ), 1.0f, 0.0f,
\r
1095 Left, Bottom, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorBottomLeft ), 0.0f, 1.0f,
\r
1096 Right, Bottom, 0.5f, D3DCOLOR_TO_D3DCOLORVALUE( m_colorBottomRight ), 1.0f, 1.0f,
\r
1099 //DXUT_SCREEN_VERTEX_10 *pVB;
\r
1100 D3D11_MAPPED_SUBRESOURCE MappedData;
\r
1101 if( SUCCEEDED( pd3dDeviceContext->Map( m_pManager->m_pVBScreenQuad11, 0, D3D11_MAP_WRITE_DISCARD,
\r
1102 0, &MappedData ) ) )
\r
1104 CopyMemory( MappedData.pData, vertices, sizeof( vertices ) );
\r
1105 pd3dDeviceContext->Unmap( m_pManager->m_pVBScreenQuad11, 0 );
\r
1108 // Set the quad VB as current
\r
1109 UINT stride = sizeof( DXUT_SCREEN_VERTEX_10 );
\r
1111 pd3dDeviceContext->IASetVertexBuffers( 0, 1, &m_pManager->m_pVBScreenQuad11, &stride, &offset );
\r
1112 pd3dDeviceContext->IASetInputLayout( m_pManager->m_pInputLayout11 );
\r
1113 pd3dDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
\r
1115 // Setup for rendering
\r
1116 m_pManager->ApplyRenderUIUntex11( pd3dDeviceContext );
\r
1117 pd3dDeviceContext->Draw( 4, 0 );
\r
1120 DXUTTextureNode* pTextureNode = GetTexture( 0 );
\r
1121 pd3dDeviceContext->PSSetShaderResources( 0, 1, &pTextureNode->pTexResView11 );
\r
1123 // Sort depth back to front
\r
1124 m_pManager->BeginSprites11();
\r
1127 m_pManager->ApplyRenderUI11( pd3dDeviceContext );
\r
1129 // Render the caption if it's enabled.
\r
1132 // DrawSprite will offset the rect down by
\r
1133 // m_nCaptionHeight, so adjust the rect higher
\r
1134 // here to negate the effect.
\r
1135 RECT rc = { 0, -m_nCaptionHeight, m_width, 0 };
\r
1136 DrawSprite11( &m_CapElement, &rc, 0.99f );
\r
1137 rc.left += 5; // Make a left margin
\r
1138 WCHAR wszOutput[256];
\r
1139 wcscpy_s( wszOutput, 256, m_wszCaption );
\r
1140 if( m_bMinimized )
\r
1141 wcscat_s( wszOutput, 256, L" (Minimized)" );
\r
1142 DrawText11( pd3dDevice, pd3dDeviceContext, wszOutput, &m_CapElement, &rc, true );
\r
1145 // If the dialog is minimized, skip rendering
\r
1147 if( !m_bMinimized )
\r
1149 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
1151 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
1153 // Focused control is drawn last
\r
1154 if( pControl == s_pControlFocus )
\r
1157 pControl->Render( fElapsedTime );
\r
1160 if( s_pControlFocus != NULL && s_pControlFocus->m_pDialog == this )
\r
1161 s_pControlFocus->Render( fElapsedTime );
\r
1167 m_pManager->EndSprites11( pd3dDevice, pd3dDeviceContext );
\r
1168 EndText11( pd3dDevice, pd3dDeviceContext );
\r
1170 m_pManager->RestoreD3D11State( pd3dDeviceContext );
\r
1175 //--------------------------------------------------------------------------------------
\r
1176 VOID CDXUTDialog::SendEvent( UINT nEvent, bool bTriggeredByUser, CDXUTControl* pControl )
\r
1178 // If no callback has been registered there's nowhere to send the event to
\r
1179 if( m_pCallbackEvent == NULL )
\r
1182 // Discard events triggered programatically if these types of events haven't been
\r
1184 if( !bTriggeredByUser && !m_bNonUserEvents )
\r
1187 m_pCallbackEvent( nEvent, pControl->GetID(), pControl, m_pCallbackEventUserContext );
\r
1191 //--------------------------------------------------------------------------------------
\r
1192 int CDXUTDialogResourceManager::AddFont( LPCWSTR strFaceName, LONG height, LONG weight )
\r
1194 // See if this font already exists
\r
1195 for( int i = 0; i < m_FontCache.GetSize(); i++ )
\r
1197 DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
\r
1199 nLen = wcsnlen( strFaceName, MAX_PATH);
\r
1200 if( 0 == _wcsnicmp( pFontNode->strFace, strFaceName, nLen ) &&
\r
1201 pFontNode->nHeight == height &&
\r
1202 pFontNode->nWeight == weight )
\r
1208 // Add a new font and try to create it
\r
1209 DXUTFontNode* pNewFontNode = new DXUTFontNode;
\r
1210 if( pNewFontNode == NULL )
\r
1213 ZeroMemory( pNewFontNode, sizeof( DXUTFontNode ) );
\r
1214 wcscpy_s( pNewFontNode->strFace, MAX_PATH, strFaceName );
\r
1215 pNewFontNode->nHeight = height;
\r
1216 pNewFontNode->nWeight = weight;
\r
1217 m_FontCache.Add( pNewFontNode );
\r
1219 int iFont = m_FontCache.GetSize() - 1;
\r
1221 // If a device is available, try to create immediately
\r
1222 if( m_pd3d9Device )
\r
1223 CreateFont9( iFont );
\r
1229 //--------------------------------------------------------------------------------------
\r
1230 HRESULT CDXUTDialog::SetFont( UINT index, LPCWSTR strFaceName, LONG height, LONG weight )
\r
1232 // If this assert triggers, you need to call CDXUTDialog::Init() first. This change
\r
1233 // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
\r
1234 // creation and interfacing with CDXUTDialogResourceManager is now the responsibility
\r
1235 // of the application if it wishes to use DXUT's GUI.
\r
1236 assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first. See comments for details." );
\r
1238 // Make sure the list is at least as large as the index being set
\r
1240 for( i = m_Fonts.GetSize(); i <= index; i++ )
\r
1242 m_Fonts.Add( -1 );
\r
1245 int iFont = m_pManager->AddFont( strFaceName, height, weight );
\r
1246 m_Fonts.SetAt( index, iFont );
\r
1252 //--------------------------------------------------------------------------------------
\r
1253 DXUTFontNode* CDXUTDialog::GetFont( UINT index )
\r
1255 if( NULL == m_pManager )
\r
1257 return m_pManager->GetFontNode( m_Fonts.GetAt( index ) );
\r
1261 //--------------------------------------------------------------------------------------
\r
1262 int CDXUTDialogResourceManager::AddTexture( LPCWSTR strFilename )
\r
1264 // See if this texture already exists
\r
1265 for( int i = 0; i < m_TextureCache.GetSize(); i++ )
\r
1267 DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
\r
1269 nLen = wcsnlen( strFilename, MAX_PATH);
\r
1270 if( pTextureNode->bFileSource && // Sources must match
\r
1271 0 == _wcsnicmp( pTextureNode->strFilename, strFilename, nLen ) )
\r
1277 // Add a new texture and try to create it
\r
1278 DXUTTextureNode* pNewTextureNode = new DXUTTextureNode;
\r
1279 if( pNewTextureNode == NULL )
\r
1282 ZeroMemory( pNewTextureNode, sizeof( DXUTTextureNode ) );
\r
1283 pNewTextureNode->bFileSource = true;
\r
1284 wcscpy_s( pNewTextureNode->strFilename, MAX_PATH, strFilename );
\r
1286 m_TextureCache.Add( pNewTextureNode );
\r
1288 int iTexture = m_TextureCache.GetSize() - 1;
\r
1290 // If a device is available, try to create immediately
\r
1291 if( m_pd3d9Device )
\r
1292 CreateTexture9( iTexture );
\r
1298 //--------------------------------------------------------------------------------------
\r
1299 int CDXUTDialogResourceManager::AddTexture( LPCWSTR strResourceName, HMODULE hResourceModule )
\r
1301 // See if this texture already exists
\r
1302 for( int i = 0; i < m_TextureCache.GetSize(); i++ )
\r
1304 DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
\r
1305 if( !pTextureNode->bFileSource && // Sources must match
\r
1306 pTextureNode->hResourceModule == hResourceModule ) // Module handles must match
\r
1308 if( IS_INTRESOURCE( strResourceName ) )
\r
1310 // Integer-based ID
\r
1311 if( ( INT_PTR )strResourceName == pTextureNode->nResourceID )
\r
1316 // String-based ID
\r
1318 nLen = wcsnlen ( strResourceName, MAX_PATH );
\r
1319 if( 0 == _wcsnicmp( pTextureNode->strFilename, strResourceName, nLen ) )
\r
1325 // Add a new texture and try to create it
\r
1326 DXUTTextureNode* pNewTextureNode = new DXUTTextureNode;
\r
1327 if( pNewTextureNode == NULL )
\r
1330 ZeroMemory( pNewTextureNode, sizeof( DXUTTextureNode ) );
\r
1331 pNewTextureNode->hResourceModule = hResourceModule;
\r
1332 if( IS_INTRESOURCE( strResourceName ) )
\r
1334 pNewTextureNode->nResourceID = ( int )( size_t )strResourceName;
\r
1338 pNewTextureNode->nResourceID = 0;
\r
1339 wcscpy_s( pNewTextureNode->strFilename, MAX_PATH, strResourceName );
\r
1342 m_TextureCache.Add( pNewTextureNode );
\r
1344 int iTexture = m_TextureCache.GetSize() - 1;
\r
1346 // If a device is available, try to create immediately
\r
1347 if( m_pd3d9Device )
\r
1348 CreateTexture9( iTexture );
\r
1354 //--------------------------------------------------------------------------------------
\r
1355 HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strFilename )
\r
1357 // If this assert triggers, you need to call CDXUTDialog::Init() first. This change
\r
1358 // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
\r
1359 // creation and interfacing with CDXUTDialogResourceManager is now the responsibility
\r
1360 // of the application if it wishes to use DXUT's GUI.
\r
1361 assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first. See comments for details." );
\r
1363 // Make sure the list is at least as large as the index being set
\r
1364 for( UINT i = m_Textures.GetSize(); i <= index; i++ )
\r
1366 m_Textures.Add( -1 );
\r
1369 int iTexture = m_pManager->AddTexture( strFilename );
\r
1371 m_Textures.SetAt( index, iTexture );
\r
1376 //--------------------------------------------------------------------------------------
\r
1377 HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strResourceName, HMODULE hResourceModule )
\r
1379 // If this assert triggers, you need to call CDXUTDialog::Init() first. This change
\r
1380 // was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
\r
1381 // creation and interfacing with CDXUTDialogResourceManager is now the responsibility
\r
1382 // of the application if it wishes to use DXUT's GUI.
\r
1383 assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first. See comments for details." );
\r
1385 // Make sure the list is at least as large as the index being set
\r
1386 for( UINT i = m_Textures.GetSize(); i <= index; i++ )
\r
1388 m_Textures.Add( -1 );
\r
1391 int iTexture = m_pManager->AddTexture( strResourceName, hResourceModule );
\r
1393 m_Textures.SetAt( index, iTexture );
\r
1398 //--------------------------------------------------------------------------------------
\r
1399 DXUTTextureNode* CDXUTDialog::GetTexture( UINT index )
\r
1401 if( NULL == m_pManager )
\r
1403 return m_pManager->GetTextureNode( m_Textures.GetAt( index ) );
\r
1408 //--------------------------------------------------------------------------------------
\r
1409 bool CDXUTDialog::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
1411 bool bHandled = false;
\r
1413 // For invisible dialog, do not handle anything.
\r
1417 // If automation command-line switch is on, enable this dialog's keyboard input
\r
1418 // upon any key press or mouse click.
\r
1419 if( DXUTGetAutomation() &&
\r
1420 ( WM_LBUTTONDOWN == uMsg || WM_LBUTTONDBLCLK == uMsg || WM_KEYDOWN == uMsg ) )
\r
1422 m_pManager->EnableKeyboardInputForAllDialogs();
\r
1425 // If caption is enable, check for clicks in the caption area.
\r
1428 if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK )
\r
1430 POINT mousePoint =
\r
1432 short( LOWORD( lParam ) ), short( HIWORD( lParam ) )
\r
1435 if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width &&
\r
1436 mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight )
\r
1439 SetCapture( DXUTGetHWND() );
\r
1443 else if( uMsg == WM_LBUTTONUP && m_bDrag )
\r
1445 POINT mousePoint =
\r
1447 short( LOWORD( lParam ) ), short( HIWORD( lParam ) )
\r
1450 if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width &&
\r
1451 mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight )
\r
1455 m_bMinimized = !m_bMinimized;
\r
1461 // If the dialog is minimized, don't send any messages to controls.
\r
1462 if( m_bMinimized )
\r
1465 // If a control is in focus, it belongs to this dialog, and it's enabled, then give
\r
1466 // it the first chance at handling the message.
\r
1467 if( s_pControlFocus &&
\r
1468 s_pControlFocus->m_pDialog == this &&
\r
1469 s_pControlFocus->GetEnabled() )
\r
1471 // If the control MsgProc handles it, then we don't.
\r
1472 if( s_pControlFocus->MsgProc( uMsg, wParam, lParam ) )
\r
1481 // Handle sizing and moving messages so that in case the mouse cursor is moved out
\r
1482 // of an UI control because of the window adjustment, we can properly
\r
1483 // unhighlight the highlighted control.
\r
1488 OnMouseMove( pt );
\r
1492 case WM_ACTIVATEAPP:
\r
1493 // Call OnFocusIn()/OnFocusOut() of the control that currently has the focus
\r
1494 // as the application is activated/deactivated. This matches the Windows
\r
1496 if( s_pControlFocus &&
\r
1497 s_pControlFocus->m_pDialog == this &&
\r
1498 s_pControlFocus->GetEnabled() )
\r
1501 s_pControlFocus->OnFocusIn();
\r
1503 s_pControlFocus->OnFocusOut();
\r
1507 // Keyboard messages
\r
1509 case WM_SYSKEYDOWN:
\r
1513 // If a control is in focus, it belongs to this dialog, and it's enabled, then give
\r
1514 // it the first chance at handling the message.
\r
1515 if( s_pControlFocus &&
\r
1516 s_pControlFocus->m_pDialog == this &&
\r
1517 s_pControlFocus->GetEnabled() )
\r
1519 if( s_pControlFocus->HandleKeyboard( uMsg, wParam, lParam ) )
\r
1523 // Not yet handled, see if this matches a control's hotkey
\r
1524 // Activate the hotkey if the focus doesn't belong to an
\r
1526 if( uMsg == WM_KEYDOWN && ( !s_pControlFocus ||
\r
1527 ( s_pControlFocus->GetType() != DXUT_CONTROL_EDITBOX
\r
1528 && s_pControlFocus->GetType() != DXUT_CONTROL_IMEEDITBOX ) ) )
\r
1530 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
1532 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
1533 if( pControl->GetHotkey() == wParam )
\r
1535 pControl->OnHotkey();
\r
1541 // Not yet handled, check for focus messages
\r
1542 if( uMsg == WM_KEYDOWN )
\r
1544 // If keyboard input is not enabled, this message should be ignored
\r
1545 if( !m_bKeyboardInput )
\r
1552 if( s_pControlFocus != NULL )
\r
1554 return OnCycleFocus( true );
\r
1560 if( s_pControlFocus != NULL )
\r
1562 return OnCycleFocus( false );
\r
1568 bool bShiftDown = ( ( GetKeyState( VK_SHIFT ) & 0x8000 ) != 0 );
\r
1569 return OnCycleFocus( !bShiftDown );
\r
1579 case WM_MOUSEMOVE:
\r
1580 case WM_LBUTTONDOWN:
\r
1581 case WM_LBUTTONUP:
\r
1582 case WM_MBUTTONDOWN:
\r
1583 case WM_MBUTTONUP:
\r
1584 case WM_RBUTTONDOWN:
\r
1585 case WM_RBUTTONUP:
\r
1586 case WM_XBUTTONDOWN:
\r
1587 case WM_XBUTTONUP:
\r
1588 case WM_LBUTTONDBLCLK:
\r
1589 case WM_MBUTTONDBLCLK:
\r
1590 case WM_RBUTTONDBLCLK:
\r
1591 case WM_XBUTTONDBLCLK:
\r
1592 case WM_MOUSEWHEEL:
\r
1594 // If not accepting mouse input, return false to indicate the message should still
\r
1595 // be handled by the application (usually to move the camera).
\r
1596 if( !m_bMouseInput )
\r
1599 POINT mousePoint =
\r
1601 short( LOWORD( lParam ) ), short( HIWORD( lParam ) )
\r
1603 mousePoint.x -= m_x;
\r
1604 mousePoint.y -= m_y;
\r
1606 // If caption is enabled, offset the Y coordinate by the negative of its height.
\r
1608 mousePoint.y -= m_nCaptionHeight;
\r
1610 // If a control is in focus, it belongs to this dialog, and it's enabled, then give
\r
1611 // it the first chance at handling the message.
\r
1612 if( s_pControlFocus &&
\r
1613 s_pControlFocus->m_pDialog == this &&
\r
1614 s_pControlFocus->GetEnabled() )
\r
1616 if( s_pControlFocus->HandleMouse( uMsg, mousePoint, wParam, lParam ) )
\r
1620 // Not yet handled, see if the mouse is over any controls
\r
1621 CDXUTControl* pControl = GetControlAtPoint( mousePoint );
\r
1622 if( pControl != NULL && pControl->GetEnabled() )
\r
1624 bHandled = pControl->HandleMouse( uMsg, mousePoint, wParam, lParam );
\r
1630 // Mouse not over any controls in this dialog, if there was a control
\r
1631 // which had focus it just lost it
\r
1632 if( uMsg == WM_LBUTTONDOWN &&
\r
1633 s_pControlFocus &&
\r
1634 s_pControlFocus->m_pDialog == this )
\r
1636 s_pControlFocus->OnFocusOut();
\r
1637 s_pControlFocus = NULL;
\r
1641 // Still not handled, hand this off to the dialog. Return false to indicate the
\r
1642 // message should still be handled by the application (usually to move the camera).
\r
1645 case WM_MOUSEMOVE:
\r
1646 OnMouseMove( mousePoint );
\r
1653 case WM_CAPTURECHANGED:
\r
1655 // The application has lost mouse capture.
\r
1656 // The dialog object may not have received
\r
1657 // a WM_MOUSEUP when capture changed. Reset
\r
1658 // m_bDrag so that the dialog does not mistakenly
\r
1659 // think the mouse button is still held down.
\r
1660 if( ( HWND )lParam != hWnd )
\r
1668 //--------------------------------------------------------------------------------------
\r
1669 CDXUTControl* CDXUTDialog::GetControlAtPoint( POINT pt )
\r
1671 // Search through all child controls for the first one which
\r
1672 // contains the mouse point
\r
1673 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
1675 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
1677 if( pControl == NULL )
\r
1682 // We only return the current control if it is visible
\r
1683 // and enabled. Because GetControlAtPoint() is used to do mouse
\r
1684 // hittest, it makes sense to perform this filtering.
\r
1685 if( pControl->ContainsPoint( pt ) && pControl->GetEnabled() && pControl->GetVisible() )
\r
1695 //--------------------------------------------------------------------------------------
\r
1696 bool CDXUTDialog::GetControlEnabled( int ID )
\r
1698 CDXUTControl* pControl = GetControl( ID );
\r
1699 if( pControl == NULL )
\r
1702 return pControl->GetEnabled();
\r
1707 //--------------------------------------------------------------------------------------
\r
1708 void CDXUTDialog::SetControlEnabled( int ID, bool bEnabled )
\r
1710 CDXUTControl* pControl = GetControl( ID );
\r
1711 if( pControl == NULL )
\r
1714 pControl->SetEnabled( bEnabled );
\r
1718 //--------------------------------------------------------------------------------------
\r
1719 void CDXUTDialog::OnMouseUp( POINT pt )
\r
1721 s_pControlPressed = NULL;
\r
1722 m_pControlMouseOver = NULL;
\r
1726 //--------------------------------------------------------------------------------------
\r
1727 void CDXUTDialog::OnMouseMove( POINT pt )
\r
1729 // Figure out which control the mouse is over now
\r
1730 CDXUTControl* pControl = GetControlAtPoint( pt );
\r
1732 // If the mouse is still over the same control, nothing needs to be done
\r
1733 if( pControl == m_pControlMouseOver )
\r
1736 // Handle mouse leaving the old control
\r
1737 if( m_pControlMouseOver )
\r
1738 m_pControlMouseOver->OnMouseLeave();
\r
1740 // Handle mouse entering the new control
\r
1741 m_pControlMouseOver = pControl;
\r
1742 if( pControl != NULL )
\r
1743 m_pControlMouseOver->OnMouseEnter();
\r
1747 //--------------------------------------------------------------------------------------
\r
1748 HRESULT CDXUTDialog::SetDefaultElement( UINT nControlType, UINT iElement, CDXUTElement* pElement )
\r
1750 // If this Element type already exist in the list, simply update the stored Element
\r
1751 for( int i = 0; i < m_DefaultElements.GetSize(); i++ )
\r
1753 DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
\r
1755 if( pElementHolder->nControlType == nControlType &&
\r
1756 pElementHolder->iElement == iElement )
\r
1758 pElementHolder->Element = *pElement;
\r
1763 // Otherwise, add a new entry
\r
1764 DXUTElementHolder* pNewHolder;
\r
1765 pNewHolder = new DXUTElementHolder;
\r
1766 if( pNewHolder == NULL )
\r
1767 return E_OUTOFMEMORY;
\r
1769 pNewHolder->nControlType = nControlType;
\r
1770 pNewHolder->iElement = iElement;
\r
1771 pNewHolder->Element = *pElement;
\r
1773 HRESULT hr = m_DefaultElements.Add( pNewHolder );
\r
1774 if( FAILED( hr ) )
\r
1776 delete pNewHolder;
\r
1782 //--------------------------------------------------------------------------------------
\r
1783 CDXUTElement* CDXUTDialog::GetDefaultElement( UINT nControlType, UINT iElement )
\r
1785 for( int i = 0; i < m_DefaultElements.GetSize(); i++ )
\r
1787 DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
\r
1789 if( pElementHolder->nControlType == nControlType &&
\r
1790 pElementHolder->iElement == iElement )
\r
1792 return &pElementHolder->Element;
\r
1801 //--------------------------------------------------------------------------------------
\r
1802 HRESULT CDXUTDialog::AddStatic( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault,
\r
1803 CDXUTStatic** ppCreated )
\r
1805 HRESULT hr = S_OK;
\r
1807 CDXUTStatic* pStatic = new CDXUTStatic( this );
\r
1809 if( ppCreated != NULL )
\r
1810 *ppCreated = pStatic;
\r
1812 if( pStatic == NULL )
\r
1813 return E_OUTOFMEMORY;
\r
1815 hr = AddControl( pStatic );
\r
1816 if( FAILED( hr ) )
\r
1819 // Set the ID and list index
\r
1820 pStatic->SetID( ID );
\r
1821 pStatic->SetText( strText );
\r
1822 pStatic->SetLocation( x, y );
\r
1823 pStatic->SetSize( width, height );
\r
1824 pStatic->m_bIsDefault = bIsDefault;
\r
1830 //--------------------------------------------------------------------------------------
\r
1831 HRESULT CDXUTDialog::AddButton( int ID, LPCWSTR strText, int x, int y, int width, int height, UINT nHotkey,
\r
1832 bool bIsDefault, CDXUTButton** ppCreated )
\r
1834 HRESULT hr = S_OK;
\r
1836 CDXUTButton* pButton = new CDXUTButton( this );
\r
1838 if( ppCreated != NULL )
\r
1839 *ppCreated = pButton;
\r
1841 if( pButton == NULL )
\r
1842 return E_OUTOFMEMORY;
\r
1844 hr = AddControl( pButton );
\r
1845 if( FAILED( hr ) )
\r
1848 // Set the ID and list index
\r
1849 pButton->SetID( ID );
\r
1850 pButton->SetText( strText );
\r
1851 pButton->SetLocation( x, y );
\r
1852 pButton->SetSize( width, height );
\r
1853 pButton->SetHotkey( nHotkey );
\r
1854 pButton->m_bIsDefault = bIsDefault;
\r
1860 //--------------------------------------------------------------------------------------
\r
1861 HRESULT CDXUTDialog::AddCheckBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bChecked,
\r
1862 UINT nHotkey, bool bIsDefault, CDXUTCheckBox** ppCreated )
\r
1864 HRESULT hr = S_OK;
\r
1866 CDXUTCheckBox* pCheckBox = new CDXUTCheckBox( this );
\r
1868 if( ppCreated != NULL )
\r
1869 *ppCreated = pCheckBox;
\r
1871 if( pCheckBox == NULL )
\r
1872 return E_OUTOFMEMORY;
\r
1874 hr = AddControl( pCheckBox );
\r
1875 if( FAILED( hr ) )
\r
1878 // Set the ID and list index
\r
1879 pCheckBox->SetID( ID );
\r
1880 pCheckBox->SetText( strText );
\r
1881 pCheckBox->SetLocation( x, y );
\r
1882 pCheckBox->SetSize( width, height );
\r
1883 pCheckBox->SetHotkey( nHotkey );
\r
1884 pCheckBox->m_bIsDefault = bIsDefault;
\r
1885 pCheckBox->SetChecked( bChecked );
\r
1892 //--------------------------------------------------------------------------------------
\r
1893 HRESULT CDXUTDialog::AddRadioButton( int ID, UINT nButtonGroup, LPCWSTR strText, int x, int y, int width, int height,
\r
1894 bool bChecked, UINT nHotkey, bool bIsDefault, CDXUTRadioButton** ppCreated )
\r
1896 HRESULT hr = S_OK;
\r
1898 CDXUTRadioButton* pRadioButton = new CDXUTRadioButton( this );
\r
1900 if( ppCreated != NULL )
\r
1901 *ppCreated = pRadioButton;
\r
1903 if( pRadioButton == NULL )
\r
1904 return E_OUTOFMEMORY;
\r
1906 hr = AddControl( pRadioButton );
\r
1907 if( FAILED( hr ) )
\r
1910 // Set the ID and list index
\r
1911 pRadioButton->SetID( ID );
\r
1912 pRadioButton->SetText( strText );
\r
1913 pRadioButton->SetButtonGroup( nButtonGroup );
\r
1914 pRadioButton->SetLocation( x, y );
\r
1915 pRadioButton->SetSize( width, height );
\r
1916 pRadioButton->SetHotkey( nHotkey );
\r
1917 pRadioButton->SetChecked( bChecked );
\r
1918 pRadioButton->m_bIsDefault = bIsDefault;
\r
1919 pRadioButton->SetChecked( bChecked );
\r
1927 //--------------------------------------------------------------------------------------
\r
1928 HRESULT CDXUTDialog::AddComboBox( int ID, int x, int y, int width, int height, UINT nHotkey, bool bIsDefault,
\r
1929 CDXUTComboBox** ppCreated )
\r
1931 HRESULT hr = S_OK;
\r
1933 CDXUTComboBox* pComboBox = new CDXUTComboBox( this );
\r
1935 if( ppCreated != NULL )
\r
1936 *ppCreated = pComboBox;
\r
1938 if( pComboBox == NULL )
\r
1939 return E_OUTOFMEMORY;
\r
1941 hr = AddControl( pComboBox );
\r
1942 if( FAILED( hr ) )
\r
1945 // Set the ID and list index
\r
1946 pComboBox->SetID( ID );
\r
1947 pComboBox->SetLocation( x, y );
\r
1948 pComboBox->SetSize( width, height );
\r
1949 pComboBox->SetHotkey( nHotkey );
\r
1950 pComboBox->m_bIsDefault = bIsDefault;
\r
1957 //--------------------------------------------------------------------------------------
\r
1958 HRESULT CDXUTDialog::AddSlider( int ID, int x, int y, int width, int height, int min, int max, int value,
\r
1959 bool bIsDefault, CDXUTSlider** ppCreated )
\r
1961 HRESULT hr = S_OK;
\r
1963 CDXUTSlider* pSlider = new CDXUTSlider( this );
\r
1965 if( ppCreated != NULL )
\r
1966 *ppCreated = pSlider;
\r
1968 if( pSlider == NULL )
\r
1969 return E_OUTOFMEMORY;
\r
1971 hr = AddControl( pSlider );
\r
1972 if( FAILED( hr ) )
\r
1975 // Set the ID and list index
\r
1976 pSlider->SetID( ID );
\r
1977 pSlider->SetLocation( x, y );
\r
1978 pSlider->SetSize( width, height );
\r
1979 pSlider->m_bIsDefault = bIsDefault;
\r
1980 pSlider->SetRange( min, max );
\r
1981 pSlider->SetValue( value );
\r
1982 pSlider->UpdateRects();
\r
1989 //--------------------------------------------------------------------------------------
\r
1990 HRESULT CDXUTDialog::AddEditBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault,
\r
1991 CDXUTEditBox** ppCreated )
\r
1993 HRESULT hr = S_OK;
\r
1995 CDXUTEditBox* pEditBox = new CDXUTEditBox( this );
\r
1997 if( ppCreated != NULL )
\r
1998 *ppCreated = pEditBox;
\r
2000 if( pEditBox == NULL )
\r
2001 return E_OUTOFMEMORY;
\r
2003 hr = AddControl( pEditBox );
\r
2004 if( FAILED( hr ) )
\r
2007 // Set the ID and position
\r
2008 pEditBox->SetID( ID );
\r
2009 pEditBox->SetLocation( x, y );
\r
2010 pEditBox->SetSize( width, height );
\r
2011 pEditBox->m_bIsDefault = bIsDefault;
\r
2014 pEditBox->SetText( strText );
\r
2020 //--------------------------------------------------------------------------------------
\r
2021 HRESULT CDXUTDialog::AddListBox( int ID, int x, int y, int width, int height, DWORD dwStyle, CDXUTListBox** ppCreated )
\r
2023 HRESULT hr = S_OK;
\r
2024 CDXUTListBox* pListBox = new CDXUTListBox( this );
\r
2026 if( ppCreated != NULL )
\r
2027 *ppCreated = pListBox;
\r
2029 if( pListBox == NULL )
\r
2030 return E_OUTOFMEMORY;
\r
2032 hr = AddControl( pListBox );
\r
2033 if( FAILED( hr ) )
\r
2036 // Set the ID and position
\r
2037 pListBox->SetID( ID );
\r
2038 pListBox->SetLocation( x, y );
\r
2039 pListBox->SetSize( width, height );
\r
2040 pListBox->SetStyle( dwStyle );
\r
2047 //--------------------------------------------------------------------------------------
\r
2048 HRESULT CDXUTDialog::InitControl( CDXUTControl* pControl )
\r
2052 if( pControl == NULL )
\r
2053 return E_INVALIDARG;
\r
2055 pControl->m_Index = m_Controls.GetSize();
\r
2057 // Look for a default Element entries
\r
2058 for( int i = 0; i < m_DefaultElements.GetSize(); i++ )
\r
2060 DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
\r
2061 if( pElementHolder->nControlType == pControl->GetType() )
\r
2062 pControl->SetElement( pElementHolder->iElement, &pElementHolder->Element );
\r
2065 V_RETURN( pControl->OnInit() );
\r
2072 //--------------------------------------------------------------------------------------
\r
2073 HRESULT CDXUTDialog::AddControl( CDXUTControl* pControl )
\r
2075 HRESULT hr = S_OK;
\r
2077 hr = InitControl( pControl );
\r
2078 if( FAILED( hr ) )
\r
2079 return DXTRACE_ERR( L"CDXUTDialog::InitControl", hr );
\r
2081 // Add to the list
\r
2082 hr = m_Controls.Add( pControl );
\r
2083 if( FAILED( hr ) )
\r
2085 return DXTRACE_ERR( L"CGrowableArray::Add", hr );
\r
2092 //--------------------------------------------------------------------------------------
\r
2093 CDXUTControl* CDXUTDialog::GetControl( int ID )
\r
2095 // Try to find the control with the given ID
\r
2096 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
2098 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
2100 if( pControl->GetID() == ID )
\r
2112 //--------------------------------------------------------------------------------------
\r
2113 CDXUTControl* CDXUTDialog::GetControl( int ID, UINT nControlType )
\r
2115 // Try to find the control with the given ID
\r
2116 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
2118 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
2120 if( pControl->GetID() == ID && pControl->GetType() == nControlType )
\r
2132 //--------------------------------------------------------------------------------------
\r
2133 CDXUTControl* CDXUTDialog::GetNextControl( CDXUTControl* pControl )
\r
2135 int index = pControl->m_Index + 1;
\r
2137 CDXUTDialog* pDialog = pControl->m_pDialog;
\r
2139 // Cycle through dialogs in the loop to find the next control. Note
\r
2140 // that if only one control exists in all looped dialogs it will
\r
2141 // be the returned 'next' control.
\r
2142 while( index >= ( int )pDialog->m_Controls.GetSize() )
\r
2144 pDialog = pDialog->m_pNextDialog;
\r
2148 return pDialog->m_Controls.GetAt( index );
\r
2151 //--------------------------------------------------------------------------------------
\r
2152 CDXUTControl* CDXUTDialog::GetPrevControl( CDXUTControl* pControl )
\r
2154 int index = pControl->m_Index - 1;
\r
2156 CDXUTDialog* pDialog = pControl->m_pDialog;
\r
2158 // Cycle through dialogs in the loop to find the next control. Note
\r
2159 // that if only one control exists in all looped dialogs it will
\r
2160 // be the returned 'previous' control.
\r
2161 while( index < 0 )
\r
2163 pDialog = pDialog->m_pPrevDialog;
\r
2164 if( pDialog == NULL )
\r
2165 pDialog = pControl->m_pDialog;
\r
2167 index = pDialog->m_Controls.GetSize() - 1;
\r
2170 return pDialog->m_Controls.GetAt( index );
\r
2174 //--------------------------------------------------------------------------------------
\r
2175 void CDXUTDialog::ClearRadioButtonGroup( UINT nButtonGroup )
\r
2177 // Find all radio buttons with the given group number
\r
2178 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
2180 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
2182 if( pControl->GetType() == DXUT_CONTROL_RADIOBUTTON )
\r
2184 CDXUTRadioButton* pRadioButton = ( CDXUTRadioButton* )pControl;
\r
2186 if( pRadioButton->GetButtonGroup() == nButtonGroup )
\r
2187 pRadioButton->SetChecked( false, false );
\r
2194 //--------------------------------------------------------------------------------------
\r
2195 void CDXUTDialog::ClearComboBox( int ID )
\r
2197 CDXUTComboBox* pComboBox = GetComboBox( ID );
\r
2198 if( pComboBox == NULL )
\r
2201 pComboBox->RemoveAllItems();
\r
2207 //--------------------------------------------------------------------------------------
\r
2208 void CDXUTDialog::RequestFocus( CDXUTControl* pControl )
\r
2210 if( s_pControlFocus == pControl )
\r
2213 if( !pControl->CanHaveFocus() )
\r
2216 if( s_pControlFocus )
\r
2217 s_pControlFocus->OnFocusOut();
\r
2219 pControl->OnFocusIn();
\r
2220 s_pControlFocus = pControl;
\r
2224 //--------------------------------------------------------------------------------------
\r
2225 HRESULT CDXUTDialog::DrawRect( RECT* pRect, D3DCOLOR color )
\r
2227 if( m_pManager->GetD3D9Device() )
\r
2228 return DrawRect9( pRect, color );
\r
2233 //--------------------------------------------------------------------------------------
\r
2234 HRESULT CDXUTDialog::DrawRect9( RECT* pRect, D3DCOLOR color )
\r
2236 RECT rcScreen = *pRect;
\r
2237 OffsetRect( &rcScreen, m_x, m_y );
\r
2239 // If caption is enabled, offset the Y position by its height.
\r
2241 OffsetRect( &rcScreen, 0, m_nCaptionHeight );
\r
2243 DXUT_SCREEN_VERTEX vertices[4] =
\r
2245 ( float )rcScreen.left - 0.5f, ( float )rcScreen.top - 0.5f, 0.5f, 1.0f, color, 0, 0,
\r
2246 ( float )rcScreen.right - 0.5f, ( float )rcScreen.top - 0.5f, 0.5f, 1.0f, color, 0, 0,
\r
2247 ( float )rcScreen.right - 0.5f, ( float )rcScreen.bottom - 0.5f, 0.5f, 1.0f, color, 0, 0,
\r
2248 ( float )rcScreen.left - 0.5f, ( float )rcScreen.bottom - 0.5f, 0.5f, 1.0f, color, 0, 0,
\r
2251 IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device();
\r
2253 // Since we're doing our own drawing here we need to flush the sprites
\r
2254 m_pManager->m_pSprite->Flush();
\r
2255 IDirect3DVertexDeclaration9* pDecl = NULL;
\r
2256 pd3dDevice->GetVertexDeclaration( &pDecl ); // Preserve the sprite's current vertex decl
\r
2257 pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF );
\r
2259 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
\r
2260 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
\r
2262 pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof( DXUT_SCREEN_VERTEX ) );
\r
2264 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
\r
2265 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
\r
2267 // Restore the vertex decl
\r
2268 pd3dDevice->SetVertexDeclaration( pDecl );
\r
2275 //--------------------------------------------------------------------------------------
\r
2276 HRESULT CDXUTDialog::DrawPolyLine( POINT* apPoints, UINT nNumPoints, D3DCOLOR color )
\r
2278 DXUT_SCREEN_VERTEX* vertices = new DXUT_SCREEN_VERTEX[ nNumPoints ];
\r
2279 if( vertices == NULL )
\r
2280 return E_OUTOFMEMORY;
\r
2282 DXUT_SCREEN_VERTEX* pVertex = vertices;
\r
2283 POINT* pt = apPoints;
\r
2284 for( UINT i = 0; i < nNumPoints; i++ )
\r
2286 pVertex->x = m_x + ( float )pt->x;
\r
2287 pVertex->y = m_y + ( float )pt->y;
\r
2288 pVertex->z = 0.5f;
\r
2289 pVertex->h = 1.0f;
\r
2290 pVertex->color = color;
\r
2291 pVertex->tu = 0.0f;
\r
2292 pVertex->tv = 0.0f;
\r
2298 IDirect3DDevice9* pd3dDevice = m_pManager->GetD3D9Device();
\r
2300 // Since we're doing our own drawing here we need to flush the sprites
\r
2301 m_pManager->m_pSprite->Flush();
\r
2302 IDirect3DVertexDeclaration9* pDecl = NULL;
\r
2303 pd3dDevice->GetVertexDeclaration( &pDecl ); // Preserve the sprite's current vertex decl
\r
2304 pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF );
\r
2306 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
\r
2307 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
\r
2309 pd3dDevice->DrawPrimitiveUP( D3DPT_LINESTRIP, nNumPoints - 1, vertices, sizeof( DXUT_SCREEN_VERTEX ) );
\r
2311 pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
\r
2312 pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
\r
2314 // Restore the vertex decl
\r
2315 pd3dDevice->SetVertexDeclaration( pDecl );
\r
2318 SAFE_DELETE_ARRAY( vertices );
\r
2323 //--------------------------------------------------------------------------------------
\r
2324 HRESULT CDXUTDialog::DrawSprite( CDXUTElement* pElement, RECT* prcDest, float fDepth )
\r
2326 if( m_pManager->GetD3D9Device() )
\r
2327 return DrawSprite9( pElement, prcDest );
\r
2329 return DrawSprite11( pElement, prcDest, fDepth );
\r
2333 //--------------------------------------------------------------------------------------
\r
2334 HRESULT CDXUTDialog::DrawSprite9( CDXUTElement* pElement, RECT* prcDest )
\r
2336 // No need to draw fully transparent layers
\r
2337 if( pElement->TextureColor.Current.a == 0 )
\r
2340 RECT rcTexture = pElement->rcTexture;
\r
2342 RECT rcScreen = *prcDest;
\r
2343 OffsetRect( &rcScreen, m_x, m_y );
\r
2345 // If caption is enabled, offset the Y position by its height.
\r
2347 OffsetRect( &rcScreen, 0, m_nCaptionHeight );
\r
2349 DXUTTextureNode* pTextureNode = GetTexture( pElement->iTexture );
\r
2350 if( pTextureNode == NULL )
\r
2353 float fScaleX = ( float )RectWidth( rcScreen ) / RectWidth( rcTexture );
\r
2354 float fScaleY = ( float )RectHeight( rcScreen ) / RectHeight( rcTexture );
\r
2356 D3DXMATRIXA16 matTransform;
\r
2357 D3DXMatrixScaling( &matTransform, fScaleX, fScaleY, 1.0f );
\r
2359 m_pManager->m_pSprite->SetTransform( &matTransform );
\r
2361 D3DXVECTOR3 vPos( ( float )rcScreen.left, ( float )rcScreen.top, 0.0f );
\r
2363 vPos.x /= fScaleX;
\r
2364 vPos.y /= fScaleY;
\r
2366 return m_pManager->m_pSprite->Draw( pTextureNode->pTexture9, &rcTexture, NULL, &vPos,
\r
2367 pElement->TextureColor.Current );
\r
2370 //--------------------------------------------------------------------------------------
\r
2371 HRESULT CDXUTDialog::DrawSprite11( CDXUTElement* pElement, RECT* prcDest, float fDepth )
\r
2373 // No need to draw fully transparent layers
\r
2374 if( pElement->TextureColor.Current.a == 0 )
\r
2377 RECT rcTexture = pElement->rcTexture;
\r
2379 RECT rcScreen = *prcDest;
\r
2380 OffsetRect( &rcScreen, m_x, m_y );
\r
2382 // If caption is enabled, offset the Y position by its height.
\r
2384 OffsetRect( &rcScreen, 0, m_nCaptionHeight );
\r
2386 DXUTTextureNode* pTextureNode = GetTexture( pElement->iTexture );
\r
2387 if( pTextureNode == NULL )
\r
2390 float fBBWidth = ( float )m_pManager->m_nBackBufferWidth;
\r
2391 float fBBHeight = ( float )m_pManager->m_nBackBufferHeight;
\r
2392 float fTexWidth = ( float )pTextureNode->dwWidth;
\r
2393 float fTexHeight = ( float )pTextureNode->dwHeight;
\r
2395 float fRectLeft = rcScreen.left / fBBWidth;
\r
2396 float fRectTop = 1.0f - rcScreen.top / fBBHeight;
\r
2397 float fRectRight = rcScreen.right / fBBWidth;
\r
2398 float fRectBottom = 1.0f - rcScreen.bottom / fBBHeight;
\r
2400 fRectLeft = fRectLeft * 2.0f - 1.0f;
\r
2401 fRectTop = fRectTop * 2.0f - 1.0f;
\r
2402 fRectRight = fRectRight * 2.0f - 1.0f;
\r
2403 fRectBottom = fRectBottom * 2.0f - 1.0f;
\r
2405 float fTexLeft = rcTexture.left / fTexWidth;
\r
2406 float fTexTop = rcTexture.top / fTexHeight;
\r
2407 float fTexRight = rcTexture.right / fTexWidth;
\r
2408 float fTexBottom = rcTexture.bottom / fTexHeight;
\r
2410 // Add 6 sprite vertices
\r
2411 DXUTSpriteVertex SpriteVertex;
\r
2414 SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectTop, fDepth );
\r
2415 SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexTop );
\r
2416 SpriteVertex.vColor = pElement->TextureColor.Current;
\r
2417 m_pManager->m_SpriteVertices.Add( SpriteVertex );
\r
2419 SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth );
\r
2420 SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop );
\r
2421 SpriteVertex.vColor = pElement->TextureColor.Current;
\r
2422 m_pManager->m_SpriteVertices.Add( SpriteVertex );
\r
2424 SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth );
\r
2425 SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom );
\r
2426 SpriteVertex.vColor = pElement->TextureColor.Current;
\r
2427 m_pManager->m_SpriteVertices.Add( SpriteVertex );
\r
2430 SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth );
\r
2431 SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop );
\r
2432 SpriteVertex.vColor = pElement->TextureColor.Current;
\r
2433 m_pManager->m_SpriteVertices.Add( SpriteVertex );
\r
2435 SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectBottom, fDepth );
\r
2436 SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexBottom );
\r
2437 SpriteVertex.vColor = pElement->TextureColor.Current;
\r
2438 m_pManager->m_SpriteVertices.Add( SpriteVertex );
\r
2440 SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth );
\r
2441 SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom );
\r
2442 SpriteVertex.vColor = pElement->TextureColor.Current;
\r
2443 m_pManager->m_SpriteVertices.Add( SpriteVertex );
\r
2445 // 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
\r
2446 // draw a sprite every time to keep the order correct between sprites and text.
\r
2447 m_pManager->EndSprites11( DXUTGetD3D11Device(), DXUTGetD3D11DeviceContext() );
\r
2453 //--------------------------------------------------------------------------------------
\r
2454 HRESULT CDXUTDialog::CalcTextRect( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, int nCount )
\r
2456 HRESULT hr = S_OK;
\r
2458 DXUTFontNode* pFontNode = GetFont( pElement->iFont );
\r
2459 if( pFontNode == NULL )
\r
2462 DWORD dwTextFormat = pElement->dwTextFormat | DT_CALCRECT;
\r
2463 // Since we are only computing the rectangle, we don't need a sprite.
\r
2464 if( pFontNode->pFont9 )
\r
2466 hr = pFontNode->pFont9->DrawText( NULL, strText, nCount, prcDest, dwTextFormat, pElement->FontColor.Current );
\r
2467 if( FAILED( hr ) )
\r
2475 //--------------------------------------------------------------------------------------
\r
2476 HRESULT CDXUTDialog::DrawText( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount, bool bCenter )
\r
2478 if( m_pManager->GetD3D9Device() )
\r
2479 return DrawText9( strText, pElement, prcDest, bShadow, nCount );
\r
2481 return DrawText11( m_pManager->GetD3D11Device(), m_pManager->GetD3D11DeviceContext(), strText, pElement, prcDest, bShadow, nCount, bCenter );
\r
2485 //--------------------------------------------------------------------------------------
\r
2486 HRESULT CDXUTDialog::DrawText9( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount )
\r
2488 HRESULT hr = S_OK;
\r
2490 // No need to draw fully transparent layers
\r
2491 if( pElement->FontColor.Current.a == 0 )
\r
2494 RECT rcScreen = *prcDest;
\r
2495 OffsetRect( &rcScreen, m_x, m_y );
\r
2497 // If caption is enabled, offset the Y position by its height.
\r
2499 OffsetRect( &rcScreen, 0, m_nCaptionHeight );
\r
2501 D3DXMATRIX matTransform;
\r
2502 D3DXMatrixIdentity( &matTransform );
\r
2503 m_pManager->m_pSprite->SetTransform( &matTransform );
\r
2505 DXUTFontNode* pFontNode = GetFont( pElement->iFont );
\r
2509 RECT rcShadow = rcScreen;
\r
2510 OffsetRect( &rcShadow, 1, 1 );
\r
2511 hr = pFontNode->pFont9->DrawText( m_pManager->m_pSprite, strText, nCount, &rcShadow, pElement->dwTextFormat,
\r
2512 D3DCOLOR_ARGB( DWORD( pElement->FontColor.Current.a * 255 ), 0, 0, 0 ) );
\r
2513 if( FAILED( hr ) )
\r
2517 hr = pFontNode->pFont9->DrawText( m_pManager->m_pSprite, strText, nCount, &rcScreen, pElement->dwTextFormat,
\r
2518 pElement->FontColor.Current );
\r
2519 if( FAILED( hr ) )
\r
2525 ID3D11Buffer* g_pFontBuffer11 = NULL;
\r
2526 UINT g_FontBufferBytes11 = 0;
\r
2527 CGrowableArray<DXUTSpriteVertex> g_FontVertices;
\r
2528 ID3D11ShaderResourceView* g_pFont11 = NULL;
\r
2529 ID3D11InputLayout* g_pInputLayout11 = NULL;
\r
2530 HRESULT InitFont11( ID3D11Device* pd3d11Device, ID3D11InputLayout* pInputLayout )
\r
2532 HRESULT hr = S_OK;
\r
2533 WCHAR str[MAX_PATH];
\r
2534 V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"UI\\Font.dds" ) );
\r
2536 if (pd3d11Device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0 ) {
\r
2538 D3DX11_IMAGE_INFO dii;
\r
2539 D3DX11GetImageInfoFromFile( str, NULL, &dii, NULL );
\r
2541 D3DX11_IMAGE_LOAD_INFO dili;
\r
2542 dili.BindFlags = D3DX11_DEFAULT;
\r
2543 dili.CpuAccessFlags = D3DX11_DEFAULT;
\r
2544 dili.Depth = D3DX11_DEFAULT;
\r
2545 dili.Filter = D3DX11_DEFAULT;
\r
2546 dili.FirstMipLevel = 0;
\r
2547 dili.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
\r
2548 dili.Height = D3DX11_DEFAULT;
\r
2549 dili.MipFilter = D3DX11_DEFAULT;
\r
2550 dili.MipLevels = 1;
\r
2551 dili.MiscFlags = D3DX11_DEFAULT;
\r
2552 dili.pSrcInfo = &dii;
\r
2553 dili.Usage = D3D11_USAGE_DEFAULT ;
\r
2554 dili.Width = D3DX11_DEFAULT;
\r
2556 V_RETURN( D3DX11CreateShaderResourceViewFromFile( pd3d11Device, str, &dili, NULL, &g_pFont11, &hr) );
\r
2558 V_RETURN( D3DX11CreateShaderResourceViewFromFile( pd3d11Device, str, NULL, NULL, &g_pFont11, &hr) );
\r
2563 g_pInputLayout11 = pInputLayout;
\r
2569 SAFE_RELEASE( g_pFontBuffer11 );
\r
2570 g_FontBufferBytes11 = 0;
\r
2571 SAFE_RELEASE( g_pFont11 );
\r
2574 void BeginText11()
\r
2576 g_FontVertices.Reset();
\r
2579 void DrawText11DXUT( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext,
\r
2580 LPCWSTR strText, RECT rcScreen, D3DXCOLOR vFontColor,
\r
2581 float fBBWidth, float fBBHeight, bool bCenter )
\r
2583 float fCharTexSizeX = 0.010526315f;
\r
2584 //float fGlyphSizeX = 14.0f / fBBWidth;
\r
2585 //float fGlyphSizeY = 32.0f / fBBHeight;
\r
2586 float fGlyphSizeX = 15.0f / fBBWidth;
\r
2587 float fGlyphSizeY = 42.0f / fBBHeight;
\r
2590 float fRectLeft = rcScreen.left / fBBWidth;
\r
2591 float fRectTop = 1.0f - rcScreen.top / fBBHeight;
\r
2593 fRectLeft = fRectLeft * 2.0f - 1.0f;
\r
2594 fRectTop = fRectTop * 2.0f - 1.0f;
\r
2596 int NumChars = (int)wcslen( strText );
\r
2598 float fRectRight = rcScreen.right / fBBWidth;
\r
2599 fRectRight = fRectRight * 2.0f - 1.0f;
\r
2600 float fRectBottom = 1.0f - rcScreen.bottom / fBBHeight;
\r
2601 fRectBottom = fRectBottom * 2.0f - 1.0f;
\r
2602 float fcenterx = ((fRectRight - fRectLeft) - (float)NumChars*fGlyphSizeX) *0.5f;
\r
2603 float fcentery = ((fRectTop - fRectBottom) - (float)1*fGlyphSizeY) *0.5f;
\r
2604 fRectLeft += fcenterx ;
\r
2605 fRectTop -= fcentery;
\r
2607 float fOriginalLeft = fRectLeft;
\r
2608 float fTexTop = 0.0f;
\r
2609 float fTexBottom = 1.0f;
\r
2611 float fDepth = 0.5f;
\r
2612 for( int i=0; i<NumChars; i++ )
\r
2614 if( strText[i] == '\n' )
\r
2616 fRectLeft = fOriginalLeft;
\r
2617 fRectTop -= fGlyphSizeY;
\r
2621 else if( strText[i] < 32 || strText[i] > 126 )
\r
2626 // Add 6 sprite vertices
\r
2627 DXUTSpriteVertex SpriteVertex;
\r
2628 float fRectRight = fRectLeft + fGlyphSizeX;
\r
2629 float fRectBottom = fRectTop - fGlyphSizeY;
\r
2630 float fTexLeft = ( strText[i] - 32 ) * fCharTexSizeX;
\r
2631 float fTexRight = fTexLeft + fCharTexSizeX;
\r
2634 SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectTop, fDepth );
\r
2635 SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexTop );
\r
2636 SpriteVertex.vColor = vFontColor;
\r
2637 g_FontVertices.Add( SpriteVertex );
\r
2639 SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth );
\r
2640 SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop );
\r
2641 SpriteVertex.vColor = vFontColor;
\r
2642 g_FontVertices.Add( SpriteVertex );
\r
2644 SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth );
\r
2645 SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom );
\r
2646 SpriteVertex.vColor = vFontColor;
\r
2647 g_FontVertices.Add( SpriteVertex );
\r
2650 SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth );
\r
2651 SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop );
\r
2652 SpriteVertex.vColor = vFontColor;
\r
2653 g_FontVertices.Add( SpriteVertex );
\r
2655 SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectBottom, fDepth );
\r
2656 SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexBottom );
\r
2657 SpriteVertex.vColor = vFontColor;
\r
2658 g_FontVertices.Add( SpriteVertex );
\r
2660 SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth );
\r
2661 SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom );
\r
2662 SpriteVertex.vColor = vFontColor;
\r
2663 g_FontVertices.Add( SpriteVertex );
\r
2665 fRectLeft += fGlyphSizeX;
\r
2669 // TODO: We have to end text after every line so that rendering order between sprites and fonts is preserved
\r
2670 EndText11( pd3dDevice, pd3d11DeviceContext );
\r
2673 void EndText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext )
\r
2676 // ensure our buffer size can hold our sprites
\r
2677 UINT FontDataBytes = g_FontVertices.GetSize() * sizeof( DXUTSpriteVertex );
\r
2678 if( g_FontBufferBytes11 < FontDataBytes )
\r
2680 SAFE_RELEASE( g_pFontBuffer11 );
\r
2681 g_FontBufferBytes11 = FontDataBytes;
\r
2683 D3D11_BUFFER_DESC BufferDesc;
\r
2684 BufferDesc.ByteWidth = g_FontBufferBytes11;
\r
2685 BufferDesc.Usage = D3D11_USAGE_DYNAMIC;
\r
2686 BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
\r
2687 BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
\r
2688 BufferDesc.MiscFlags = 0;
\r
2690 pd3dDevice->CreateBuffer( &BufferDesc, NULL, &g_pFontBuffer11 );
\r
2693 // Copy the sprites over
\r
2694 D3D11_BOX destRegion;
\r
2695 destRegion.left = 0;
\r
2696 destRegion.right = FontDataBytes;
\r
2697 destRegion.top = 0;
\r
2698 destRegion.bottom = 1;
\r
2699 destRegion.front = 0;
\r
2700 destRegion.back = 1;
\r
2701 D3D11_MAPPED_SUBRESOURCE MappedResource;
\r
2702 if ( S_OK == pd3d11DeviceContext->Map( g_pFontBuffer11, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) {
\r
2703 CopyMemory( MappedResource.pData, (void*)g_FontVertices.GetData(), FontDataBytes );
\r
2704 pd3d11DeviceContext->Unmap(g_pFontBuffer11, 0);
\r
2707 ID3D11ShaderResourceView* pOldTexture = NULL;
\r
2708 pd3d11DeviceContext->PSGetShaderResources( 0, 1, &pOldTexture );
\r
2709 pd3d11DeviceContext->PSSetShaderResources( 0, 1, &g_pFont11 );
\r
2712 UINT Stride = sizeof( DXUTSpriteVertex );
\r
2714 pd3d11DeviceContext->IASetVertexBuffers( 0, 1, &g_pFontBuffer11, &Stride, &Offset );
\r
2715 pd3d11DeviceContext->IASetInputLayout( g_pInputLayout11 );
\r
2716 pd3d11DeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
\r
2717 pd3d11DeviceContext->Draw( g_FontVertices.GetSize(), 0 );
\r
2719 pd3d11DeviceContext->PSSetShaderResources( 0, 1, &pOldTexture );
\r
2720 SAFE_RELEASE( pOldTexture );
\r
2722 g_FontVertices.Reset();
\r
2725 //--------------------------------------------------------------------------------------
\r
2726 HRESULT CDXUTDialog::DrawText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext,
\r
2727 LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount, bool bCenter )
\r
2729 //HRESULT hr = S_OK;
\r
2731 // No need to draw fully transparent layers
\r
2732 if( pElement->FontColor.Current.a == 0 )
\r
2735 RECT rcScreen = *prcDest;
\r
2736 OffsetRect( &rcScreen, m_x, m_y);
\r
2738 // If caption is enabled, offset the Y position by its height.
\r
2740 OffsetRect( &rcScreen, 0, m_nCaptionHeight );
\r
2742 float fBBWidth = ( float )m_pManager->m_nBackBufferWidth;
\r
2743 float fBBHeight = ( float )m_pManager->m_nBackBufferHeight;
\r
2747 RECT rcShadow = rcScreen;
\r
2748 OffsetRect( &rcShadow, 1, 1 );
\r
2750 D3DXCOLOR vShadowColor( 0,0,0, 1.0f );
\r
2751 DrawText11DXUT( pd3dDevice, pd3d11DeviceContext,
\r
2752 strText, rcShadow, vShadowColor,
\r
2753 fBBWidth, fBBHeight, bCenter );
\r
2757 D3DXCOLOR vFontColor( pElement->FontColor.Current.r, pElement->FontColor.Current.g, pElement->FontColor.Current.b, 1.0f );
\r
2758 DrawText11DXUT( pd3dDevice, pd3d11DeviceContext,
\r
2759 strText, rcScreen, vFontColor,
\r
2760 fBBWidth, fBBHeight, bCenter );
\r
2766 //--------------------------------------------------------------------------------------
\r
2767 void CDXUTDialog::SetBackgroundColors( D3DCOLOR colorTopLeft, D3DCOLOR colorTopRight, D3DCOLOR colorBottomLeft,
\r
2768 D3DCOLOR colorBottomRight )
\r
2770 m_colorTopLeft = colorTopLeft;
\r
2771 m_colorTopRight = colorTopRight;
\r
2772 m_colorBottomLeft = colorBottomLeft;
\r
2773 m_colorBottomRight = colorBottomRight;
\r
2777 //--------------------------------------------------------------------------------------
\r
2778 void CDXUTDialog::SetNextDialog( CDXUTDialog* pNextDialog )
\r
2780 if( pNextDialog == NULL )
\r
2781 pNextDialog = this;
\r
2783 m_pNextDialog = pNextDialog;
\r
2785 m_pNextDialog->m_pPrevDialog = this;
\r
2789 //--------------------------------------------------------------------------------------
\r
2790 void CDXUTDialog::ClearFocus()
\r
2792 if( s_pControlFocus )
\r
2794 s_pControlFocus->OnFocusOut();
\r
2795 s_pControlFocus = NULL;
\r
2802 //--------------------------------------------------------------------------------------
\r
2803 void CDXUTDialog::FocusDefaultControl()
\r
2805 // Check for default control in this dialog
\r
2806 for( int i = 0; i < m_Controls.GetSize(); i++ )
\r
2808 CDXUTControl* pControl = m_Controls.GetAt( i );
\r
2809 if( pControl->m_bIsDefault )
\r
2811 // Remove focus from the current control
\r
2814 // Give focus to the default control
\r
2815 s_pControlFocus = pControl;
\r
2816 s_pControlFocus->OnFocusIn();
\r
2823 //--------------------------------------------------------------------------------------
\r
2824 bool CDXUTDialog::OnCycleFocus( bool bForward )
\r
2826 CDXUTControl* pControl = NULL;
\r
2827 CDXUTDialog* pDialog = NULL; // pDialog and pLastDialog are used to track wrapping of
\r
2828 CDXUTDialog* pLastDialog; // focus from first control to last or vice versa.
\r
2830 if( s_pControlFocus == NULL )
\r
2832 // If s_pControlFocus is NULL, we focus the first control of first dialog in
\r
2833 // the case that bForward is true, and focus the last control of last dialog when
\r
2834 // bForward is false.
\r
2838 // Search for the first control from the start of the dialog
\r
2840 for( int d = 0; d < m_pManager->m_Dialogs.GetSize(); ++d )
\r
2842 pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt( d );
\r
2843 if( pDialog && pDialog->m_Controls.GetSize() > 0 )
\r
2845 pControl = pDialog->m_Controls.GetAt( 0 );
\r
2850 if( !pDialog || !pControl )
\r
2852 // No dialog has been registered yet or no controls have been
\r
2853 // added to the dialogs. Cannot proceed.
\r
2859 // Search for the first control from the end of the dialog
\r
2861 for( int d = m_pManager->m_Dialogs.GetSize() - 1; d >= 0; --d )
\r
2863 pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt( d );
\r
2864 if( pDialog && pDialog->m_Controls.GetSize() > 0 )
\r
2866 pControl = pDialog->m_Controls.GetAt( pDialog->m_Controls.GetSize() - 1 );
\r
2871 if( !pDialog || !pControl )
\r
2873 // No dialog has been registered yet or no controls have been
\r
2874 // added to the dialogs. Cannot proceed.
\r
2879 else if( s_pControlFocus->m_pDialog != this )
\r
2881 // If a control belonging to another dialog has focus, let that other
\r
2882 // dialog handle this event by returning false.
\r
2888 // Focused control belongs to this dialog. Cycle to the
\r
2889 // next/previous control.
\r
2890 pLastDialog = s_pControlFocus->m_pDialog;
\r
2891 pControl = ( bForward ) ? GetNextControl( s_pControlFocus ) : GetPrevControl( s_pControlFocus );
\r
2892 pDialog = pControl->m_pDialog;
\r
2895 for( int i = 0; i < 0xffff; i++ )
\r
2897 // If we just wrapped from last control to first or vice versa,
\r
2898 // set the focused control to NULL. This state, where no control
\r
2899 // has focus, allows the camera to work.
\r
2900 int nLastDialogIndex = m_pManager->m_Dialogs.IndexOf( pLastDialog );
\r
2901 int nDialogIndex = m_pManager->m_Dialogs.IndexOf( pDialog );
\r
2902 if( ( !bForward && nLastDialogIndex < nDialogIndex ) ||
\r
2903 ( bForward && nDialogIndex < nLastDialogIndex ) )
\r
2905 if( s_pControlFocus )
\r
2906 s_pControlFocus->OnFocusOut();
\r
2907 s_pControlFocus = NULL;
\r
2911 // If we've gone in a full circle then focus doesn't change
\r
2912 if( pControl == s_pControlFocus )
\r
2915 // If the dialog accepts keybord input and the control can have focus then
\r
2917 if( pControl->m_pDialog->m_bKeyboardInput && pControl->CanHaveFocus() )
\r
2919 if( s_pControlFocus )
\r
2920 s_pControlFocus->OnFocusOut();
\r
2921 s_pControlFocus = pControl;
\r
2922 s_pControlFocus->OnFocusIn();
\r
2926 pLastDialog = pDialog;
\r
2927 pControl = ( bForward ) ? GetNextControl( pControl ) : GetPrevControl( pControl );
\r
2928 pDialog = pControl->m_pDialog;
\r
2931 // If we reached this point, the chain of dialogs didn't form a complete loop
\r
2932 DXTRACE_ERR( L"CDXUTDialog: Multiple dialogs are improperly chained together", E_FAIL );
\r
2937 //--------------------------------------------------------------------------------------
\r
2938 HRESULT CDXUTDialogResourceManager::CreateFont9( UINT iFont )
\r
2940 HRESULT hr = S_OK;
\r
2942 DXUTFontNode* pFontNode = m_FontCache.GetAt( iFont );
\r
2944 SAFE_RELEASE( pFontNode->pFont9 );
\r
2946 V_RETURN( D3DXCreateFont( m_pd3d9Device, pFontNode->nHeight, 0, pFontNode->nWeight, 1, FALSE, DEFAULT_CHARSET,
\r
2947 OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
\r
2948 pFontNode->strFace, &pFontNode->pFont9 ) );
\r
2955 //--------------------------------------------------------------------------------------
\r
2956 HRESULT CDXUTDialogResourceManager::CreateFont11( UINT iFont )
\r
2962 //--------------------------------------------------------------------------------------
\r
2963 HRESULT CDXUTDialogResourceManager::CreateTexture9( UINT iTexture )
\r
2965 HRESULT hr = S_OK;
\r
2967 DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( iTexture );
\r
2970 D3DXIMAGE_INFO info;
\r
2972 if( !pTextureNode->bFileSource )
\r
2974 if( pTextureNode->nResourceID == 0xFFFF && pTextureNode->hResourceModule == ( HMODULE )0xFFFF )
\r
2976 hr = DXUTCreateGUITextureFromInternalArray9( m_pd3d9Device, &pTextureNode->pTexture9, &info );
\r
2977 if( FAILED( hr ) )
\r
2978 return DXTRACE_ERR( L"D3DXCreateTextureFromFileInMemoryEx", hr );
\r
2982 LPCWSTR pID = pTextureNode->nResourceID ? ( LPCWSTR )( size_t )pTextureNode->nResourceID :
\r
2983 pTextureNode->strFilename;
\r
2985 // Create texture from resource
\r
2986 hr = D3DXCreateTextureFromResourceEx( m_pd3d9Device, pTextureNode->hResourceModule, pID, D3DX_DEFAULT,
\r
2988 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
\r
2989 D3DX_DEFAULT, D3DX_DEFAULT, 0,
\r
2990 &info, NULL, &pTextureNode->pTexture9 );
\r
2991 if( FAILED( hr ) )
\r
2992 return DXTRACE_ERR( L"D3DXCreateTextureFromResourceEx", hr );
\r
2997 // Make sure there's a texture to create
\r
2998 if( pTextureNode->strFilename[0] == 0 )
\r
3001 // Create texture from file
\r
3002 hr = D3DXCreateTextureFromFileEx( m_pd3d9Device, pTextureNode->strFilename, D3DX_DEFAULT, D3DX_DEFAULT,
\r
3003 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
\r
3004 D3DX_DEFAULT, D3DX_DEFAULT, 0,
\r
3005 &info, NULL, &pTextureNode->pTexture9 );
\r
3006 if( FAILED( hr ) )
\r
3008 return DXTRACE_ERR( L"D3DXCreateTextureFromFileEx", hr );
\r
3012 // Store dimensions
\r
3013 pTextureNode->dwWidth = info.Width;
\r
3014 pTextureNode->dwHeight = info.Height;
\r
3020 //--------------------------------------------------------------------------------------
\r
3021 HRESULT CDXUTDialogResourceManager::CreateTexture11( UINT iTexture )
\r
3023 HRESULT hr = S_OK;
\r
3025 DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( iTexture );
\r
3027 if( !pTextureNode->bFileSource )
\r
3029 if( pTextureNode->nResourceID == 0xFFFF && pTextureNode->hResourceModule == ( HMODULE )0xFFFF )
\r
3031 hr = DXUTCreateGUITextureFromInternalArray11( m_pd3d11Device, &pTextureNode->pTexture11, NULL );
\r
3032 if( FAILED( hr ) )
\r
3033 return DXTRACE_ERR( L"D3DX10CreateResourceFromFileInMemory", hr );
\r
3037 // LPCWSTR pID = pTextureNode->nResourceID ? ( LPCWSTR )( size_t )pTextureNode->nResourceID :
\r
3038 // pTextureNode->strFilename;
\r
3040 // D3DX10_IMAGE_INFO SrcInfo;
\r
3041 // D3DX10GetImageInfoFromResource( NULL, pID, NULL, &SrcInfo, NULL );
\r
3043 // // Create texture from resource
\r
3044 // ID3D10Resource* pRes;
\r
3045 // D3DX10_IMAGE_LOAD_INFO loadInfo;
\r
3046 // loadInfo.Width = D3DX10_DEFAULT;
\r
3047 // loadInfo.Height = D3DX10_DEFAULT;
\r
3048 // loadInfo.Depth = D3DX10_DEFAULT;
\r
3049 // loadInfo.FirstMipLevel = 0;
\r
3050 // loadInfo.MipLevels = 1;
\r
3051 // loadInfo.Usage = D3D10_USAGE_DEFAULT;
\r
3052 // loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE;
\r
3053 // loadInfo.CpuAccessFlags = 0;
\r
3054 // loadInfo.MiscFlags = 0;
\r
3055 // loadInfo.Format = MAKE_TYPELESS( SrcInfo.Format );
\r
3056 // loadInfo.Filter = D3DX10_FILTER_NONE;
\r
3057 // loadInfo.MipFilter = D3DX10_FILTER_NONE;
\r
3058 // loadInfo.pSrcInfo = &SrcInfo;
\r
3060 // hr = D3DX10CreateTextureFromResource( m_pd3d10Device, pTextureNode->hResourceModule, pID, &loadInfo,
\r
3061 // NULL, &pRes, NULL );
\r
3062 // if( FAILED( hr ) )
\r
3063 // return DXTRACE_ERR( L"D3DX10CreateResourceFromResource", hr );
\r
3064 // hr = pRes->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&pTextureNode->pTexture10 );
\r
3065 // SAFE_RELEASE( pRes );
\r
3066 // if( FAILED( hr ) )
\r
3073 //// Make sure there's a texture to create
\r
3074 //if( pTextureNode->strFilename[0] == 0 )
\r
3077 //D3DX10_IMAGE_INFO SrcInfo;
\r
3078 //D3DX10GetImageInfoFromFile( pTextureNode->strFilename, NULL, &SrcInfo, NULL );
\r
3080 //// Create texture from file
\r
3081 //ID3D10Resource* pRes;
\r
3082 //D3DX10_IMAGE_LOAD_INFO loadInfo;
\r
3083 //loadInfo.Width = D3DX10_DEFAULT;
\r
3084 //loadInfo.Height = D3DX10_DEFAULT;
\r
3085 //loadInfo.Depth = D3DX10_DEFAULT;
\r
3086 //loadInfo.FirstMipLevel = 0;
\r
3087 //loadInfo.MipLevels = 1;
\r
3088 //loadInfo.Usage = D3D10_USAGE_DEFAULT;
\r
3089 //loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE;
\r
3090 //loadInfo.CpuAccessFlags = 0;
\r
3091 //loadInfo.MiscFlags = 0;
\r
3092 //loadInfo.Format = MAKE_TYPELESS( SrcInfo.Format );
\r
3093 //loadInfo.Filter = D3DX10_FILTER_NONE;
\r
3094 //loadInfo.MipFilter = D3DX10_FILTER_NONE;
\r
3095 //loadInfo.pSrcInfo = &SrcInfo;
\r
3096 //hr = D3DX10CreateTextureFromFile( m_pd3d10Device, pTextureNode->strFilename, &loadInfo, NULL, &pRes, NULL );
\r
3097 //if( FAILED( hr ) )
\r
3099 // return DXTRACE_ERR( L"D3DX10CreateResourceFromFileEx", hr );
\r
3101 //hr = pRes->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&pTextureNode->pTexture10 );
\r
3102 //SAFE_RELEASE( pRes );
\r
3103 //if( FAILED( hr ) )
\r
3108 // Store dimensions
\r
3109 D3D11_TEXTURE2D_DESC desc;
\r
3110 pTextureNode->pTexture11->GetDesc( &desc );
\r
3111 pTextureNode->dwWidth = desc.Width;
\r
3112 pTextureNode->dwHeight = desc.Height;
\r
3114 // Create resource view
\r
3115 D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
\r
3116 SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
\r
3117 SRVDesc.Format = MAKE_SRGB( desc.Format );
\r
3118 SRVDesc.Texture2D.MipLevels = 1;
\r
3119 SRVDesc.Texture2D.MostDetailedMip = 0;
\r
3120 hr = m_pd3d11Device->CreateShaderResourceView( pTextureNode->pTexture11, &SRVDesc, &pTextureNode->pTexResView11 );
\r
3126 //--------------------------------------------------------------------------------------
\r
3127 void CDXUTDialog::InitDefaultElements()
\r
3129 SetFont( 0, L"Arial", 14, FW_NORMAL );
\r
3131 CDXUTElement Element;
\r
3134 //-------------------------------------
\r
3135 // Element for the caption
\r
3136 //-------------------------------------
\r
3137 m_CapElement.SetFont( 0 );
\r
3138 SetRect( &rcTexture, 17, 269, 241, 287 );
\r
3139 m_CapElement.SetTexture( 0, &rcTexture );
\r
3140 m_CapElement.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 255, 255, 255, 255 );
\r
3141 m_CapElement.FontColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 255, 255, 255, 255 );
\r
3142 m_CapElement.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER );
\r
3143 // Pre-blend as we don't need to transition the state
\r
3144 m_CapElement.TextureColor.Blend( DXUT_STATE_NORMAL, 10.0f );
\r
3145 m_CapElement.FontColor.Blend( DXUT_STATE_NORMAL, 10.0f );
\r
3147 //-------------------------------------
\r
3149 //-------------------------------------
\r
3150 Element.SetFont( 0 );
\r
3151 Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 );
\r
3153 // Assign the Element
\r
3154 SetDefaultElement( DXUT_CONTROL_STATIC, 0, &Element );
\r
3157 //-------------------------------------
\r
3158 // CDXUTButton - Button
\r
3159 //-------------------------------------
\r
3160 SetRect( &rcTexture, 0, 0, 136, 54 );
\r
3161 Element.SetTexture( 0, &rcTexture );
\r
3162 Element.SetFont( 0 );
\r
3163 Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 );
\r
3164 Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 200, 255, 255, 255 );
\r
3165 Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 255, 0, 0, 0 );
\r
3167 // Assign the Element
\r
3168 SetDefaultElement( DXUT_CONTROL_BUTTON, 0, &Element );
\r
3171 //-------------------------------------
\r
3172 // CDXUTButton - Fill layer
\r
3173 //-------------------------------------
\r
3174 SetRect( &rcTexture, 136, 0, 252, 54 );
\r
3175 Element.SetTexture( 0, &rcTexture, D3DCOLOR_ARGB( 0, 255, 255, 255 ) );
\r
3176 Element.TextureColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 160, 255, 255, 255 );
\r
3177 Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 60, 0, 0, 0 );
\r
3178 Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 30, 255, 255, 255 );
\r
3181 // Assign the Element
\r
3182 SetDefaultElement( DXUT_CONTROL_BUTTON, 1, &Element );
\r
3185 //-------------------------------------
\r
3186 // CDXUTCheckBox - Box
\r
3187 //-------------------------------------
\r
3188 SetRect( &rcTexture, 0, 54, 27, 81 );
\r
3189 Element.SetTexture( 0, &rcTexture );
\r
3190 Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER );
\r
3191 Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 );
\r
3192 Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 );
\r
3193 Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 );
\r
3194 Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 255, 255, 255 );
\r
3196 // Assign the Element
\r
3197 SetDefaultElement( DXUT_CONTROL_CHECKBOX, 0, &Element );
\r
3200 //-------------------------------------
\r
3201 // CDXUTCheckBox - Check
\r
3202 //-------------------------------------
\r
3203 SetRect( &rcTexture, 27, 54, 54, 81 );
\r
3204 Element.SetTexture( 0, &rcTexture );
\r
3206 // Assign the Element
\r
3207 SetDefaultElement( DXUT_CONTROL_CHECKBOX, 1, &Element );
\r
3210 //-------------------------------------
\r
3211 // CDXUTRadioButton - Box
\r
3212 //-------------------------------------
\r
3213 SetRect( &rcTexture, 54, 54, 81, 81 );
\r
3214 Element.SetTexture( 0, &rcTexture );
\r
3215 Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_VCENTER );
\r
3216 Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 );
\r
3217 Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 );
\r
3218 Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 );
\r
3219 Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 255, 255, 255 );
\r
3221 // Assign the Element
\r
3222 SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 0, &Element );
\r
3225 //-------------------------------------
\r
3226 // CDXUTRadioButton - Check
\r
3227 //-------------------------------------
\r
3228 SetRect( &rcTexture, 81, 54, 108, 81 );
\r
3229 Element.SetTexture( 0, &rcTexture );
\r
3231 // Assign the Element
\r
3232 SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 1, &Element );
\r
3235 //-------------------------------------
\r
3236 // CDXUTComboBox - Main
\r
3237 //-------------------------------------
\r
3238 SetRect( &rcTexture, 7, 81, 247, 123 );
\r
3239 Element.SetTexture( 0, &rcTexture );
\r
3240 Element.SetFont( 0 );
\r
3241 Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 200, 200, 200 );
\r
3242 Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 170, 230, 230, 230 );
\r
3243 Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 200, 200, 200 );
\r
3244 Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 255, 0, 0, 0 );
\r
3245 Element.FontColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 0, 0, 0 );
\r
3246 Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 );
\r
3249 // Assign the Element
\r
3250 SetDefaultElement( DXUT_CONTROL_COMBOBOX, 0, &Element );
\r
3253 //-------------------------------------
\r
3254 // CDXUTComboBox - Button
\r
3255 //-------------------------------------
\r
3256 SetRect( &rcTexture, 98, 189, 151, 238 );
\r
3257 Element.SetTexture( 0, &rcTexture );
\r
3258 Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 );
\r
3259 Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 255, 150, 150, 150 );
\r
3260 Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 );
\r
3261 Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 255, 255, 255 );
\r
3263 // Assign the Element
\r
3264 SetDefaultElement( DXUT_CONTROL_COMBOBOX, 1, &Element );
\r
3267 //-------------------------------------
\r
3268 // CDXUTComboBox - Dropdown
\r
3269 //-------------------------------------
\r
3270 SetRect( &rcTexture, 13, 123, 241, 160 );
\r
3271 Element.SetTexture( 0, &rcTexture );
\r
3272 Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP );
\r
3274 // Assign the Element
\r
3275 SetDefaultElement( DXUT_CONTROL_COMBOBOX, 2, &Element );
\r
3278 //-------------------------------------
\r
3279 // CDXUTComboBox - Selection
\r
3280 //-------------------------------------
\r
3281 SetRect( &rcTexture, 12, 163, 239, 183 );
\r
3282 Element.SetTexture( 0, &rcTexture );
\r
3283 Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_TOP );
\r
3285 // Assign the Element
\r
3286 SetDefaultElement( DXUT_CONTROL_COMBOBOX, 3, &Element );
\r
3289 //-------------------------------------
\r
3290 // CDXUTSlider - Track
\r
3291 //-------------------------------------
\r
3292 SetRect( &rcTexture, 1, 187, 93, 228 );
\r
3293 Element.SetTexture( 0, &rcTexture );
\r
3294 Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 );
\r
3295 Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 200, 255, 255, 255 );
\r
3296 Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 70, 255, 255, 255 );
\r
3298 // Assign the Element
\r
3299 SetDefaultElement( DXUT_CONTROL_SLIDER, 0, &Element );
\r
3301 //-------------------------------------
\r
3302 // CDXUTSlider - Button
\r
3303 //-------------------------------------
\r
3304 SetRect( &rcTexture, 151, 193, 192, 234 );
\r
3305 Element.SetTexture( 0, &rcTexture );
\r
3307 // Assign the Element
\r
3308 SetDefaultElement( DXUT_CONTROL_SLIDER, 1, &Element );
\r
3310 //-------------------------------------
\r
3311 // CDXUTScrollBar - Track
\r
3312 //-------------------------------------
\r
3313 int nScrollBarStartX = 196;
\r
3314 int nScrollBarStartY = 191;
\r
3315 SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 21, nScrollBarStartX + 22, nScrollBarStartY + 32 );
\r
3316 Element.SetTexture( 0, &rcTexture );
\r
3317 Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 );
\r
3319 // Assign the Element
\r
3320 SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 0, &Element );
\r
3322 //-------------------------------------
\r
3323 // CDXUTScrollBar - Up Arrow
\r
3324 //-------------------------------------
\r
3325 SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 1, nScrollBarStartX + 22, nScrollBarStartY + 21 );
\r
3326 Element.SetTexture( 0, &rcTexture );
\r
3327 Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 );
\r
3330 // Assign the Element
\r
3331 SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 1, &Element );
\r
3333 //-------------------------------------
\r
3334 // CDXUTScrollBar - Down Arrow
\r
3335 //-------------------------------------
\r
3336 SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 32, nScrollBarStartX + 22, nScrollBarStartY + 53 );
\r
3337 Element.SetTexture( 0, &rcTexture );
\r
3338 Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 255, 200, 200, 200 );
\r
3341 // Assign the Element
\r
3342 SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 2, &Element );
\r
3344 //-------------------------------------
\r
3345 // CDXUTScrollBar - Button
\r
3346 //-------------------------------------
\r
3347 SetRect( &rcTexture, 220, 192, 238, 234 );
\r
3348 Element.SetTexture( 0, &rcTexture );
\r
3350 // Assign the Element
\r
3351 SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 3, &Element );
\r
3354 //-------------------------------------
\r
3356 //-------------------------------------
\r
3357 // Element assignment:
\r
3359 // 1 - top left border
\r
3361 // 3 - top right border
\r
3362 // 4 - left border
\r
3363 // 5 - right border
\r
3364 // 6 - lower left border
\r
3365 // 7 - lower border
\r
3366 // 8 - lower right border
\r
3368 Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP );
\r
3370 // Assign the style
\r
3371 SetRect( &rcTexture, 14, 90, 241, 113 );
\r
3372 Element.SetTexture( 0, &rcTexture );
\r
3373 SetDefaultElement( DXUT_CONTROL_EDITBOX, 0, &Element );
\r
3374 SetRect( &rcTexture, 8, 82, 14, 90 );
\r
3375 Element.SetTexture( 0, &rcTexture );
\r
3376 SetDefaultElement( DXUT_CONTROL_EDITBOX, 1, &Element );
\r
3377 SetRect( &rcTexture, 14, 82, 241, 90 );
\r
3378 Element.SetTexture( 0, &rcTexture );
\r
3379 SetDefaultElement( DXUT_CONTROL_EDITBOX, 2, &Element );
\r
3380 SetRect( &rcTexture, 241, 82, 246, 90 );
\r
3381 Element.SetTexture( 0, &rcTexture );
\r
3382 SetDefaultElement( DXUT_CONTROL_EDITBOX, 3, &Element );
\r
3383 SetRect( &rcTexture, 8, 90, 14, 113 );
\r
3384 Element.SetTexture( 0, &rcTexture );
\r
3385 SetDefaultElement( DXUT_CONTROL_EDITBOX, 4, &Element );
\r
3386 SetRect( &rcTexture, 241, 90, 246, 113 );
\r
3387 Element.SetTexture( 0, &rcTexture );
\r
3388 SetDefaultElement( DXUT_CONTROL_EDITBOX, 5, &Element );
\r
3389 SetRect( &rcTexture, 8, 113, 14, 121 );
\r
3390 Element.SetTexture( 0, &rcTexture );
\r
3391 SetDefaultElement( DXUT_CONTROL_EDITBOX, 6, &Element );
\r
3392 SetRect( &rcTexture, 14, 113, 241, 121 );
\r
3393 Element.SetTexture( 0, &rcTexture );
\r
3394 SetDefaultElement( DXUT_CONTROL_EDITBOX, 7, &Element );
\r
3395 SetRect( &rcTexture, 241, 113, 246, 121 );
\r
3396 Element.SetTexture( 0, &rcTexture );
\r
3397 SetDefaultElement( DXUT_CONTROL_EDITBOX, 8, &Element );
\r
3399 //-------------------------------------
\r
3400 // CDXUTListBox - Main
\r
3401 //-------------------------------------
\r
3402 SetRect( &rcTexture, 13, 123, 241, 160 );
\r
3403 Element.SetTexture( 0, &rcTexture );
\r
3404 Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP );
\r
3406 // Assign the Element
\r
3407 SetDefaultElement( DXUT_CONTROL_LISTBOX, 0, &Element );
\r
3409 //-------------------------------------
\r
3410 // CDXUTListBox - Selection
\r
3411 //-------------------------------------
\r
3413 SetRect( &rcTexture, 16, 166, 240, 183 );
\r
3414 Element.SetTexture( 0, &rcTexture );
\r
3415 Element.SetFont( 0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), DT_LEFT | DT_TOP );
\r
3417 // Assign the Element
\r
3418 SetDefaultElement( DXUT_CONTROL_LISTBOX, 1, &Element );
\r
3423 //--------------------------------------------------------------------------------------
\r
3424 // CDXUTControl class
\r
3425 //--------------------------------------------------------------------------------------
\r
3427 //--------------------------------------------------------------------------------------
\r
3428 CDXUTControl::CDXUTControl( CDXUTDialog* pDialog )
\r
3430 m_Type = DXUT_CONTROL_BUTTON;
\r
3431 m_pDialog = pDialog;
\r
3434 m_pUserData = NULL;
\r
3436 m_bEnabled = true;
\r
3437 m_bVisible = true;
\r
3438 m_bMouseOver = false;
\r
3439 m_bHasFocus = false;
\r
3440 m_bIsDefault = false;
\r
3449 ZeroMemory( &m_rcBoundingBox, sizeof( m_rcBoundingBox ) );
\r
3453 CDXUTControl::~CDXUTControl()
\r
3455 for( int i = 0; i < m_Elements.GetSize(); ++i )
\r
3457 delete m_Elements[i];
\r
3459 m_Elements.RemoveAll();
\r
3463 //--------------------------------------------------------------------------------------
\r
3464 void CDXUTControl::SetTextColor( D3DCOLOR Color )
\r
3466 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
3469 pElement->FontColor.States[DXUT_STATE_NORMAL] = Color;
\r
3473 //--------------------------------------------------------------------------------------
\r
3474 HRESULT CDXUTControl::SetElement( UINT iElement, CDXUTElement* pElement )
\r
3476 HRESULT hr = S_OK;
\r
3478 if( pElement == NULL )
\r
3479 return E_INVALIDARG;
\r
3481 // Make certain the array is this large
\r
3482 for( UINT i = m_Elements.GetSize(); i <= iElement; i++ )
\r
3484 CDXUTElement* pNewElement = new CDXUTElement();
\r
3485 if( pNewElement == NULL )
\r
3486 return E_OUTOFMEMORY;
\r
3488 hr = m_Elements.Add( pNewElement );
\r
3489 if( FAILED( hr ) )
\r
3491 SAFE_DELETE( pNewElement );
\r
3496 // Update the data
\r
3497 CDXUTElement* pCurElement = m_Elements.GetAt( iElement );
\r
3498 *pCurElement = *pElement;
\r
3504 //--------------------------------------------------------------------------------------
\r
3505 void CDXUTControl::Refresh()
\r
3507 m_bMouseOver = false;
\r
3508 m_bHasFocus = false;
\r
3510 for( int i = 0; i < m_Elements.GetSize(); i++ )
\r
3512 CDXUTElement* pElement = m_Elements.GetAt( i );
\r
3513 pElement->Refresh();
\r
3518 //--------------------------------------------------------------------------------------
\r
3519 void CDXUTControl::UpdateRects()
\r
3521 SetRect( &m_rcBoundingBox, m_x, m_y, m_x + m_width, m_y + m_height );
\r
3525 //--------------------------------------------------------------------------------------
\r
3526 // CDXUTStatic class
\r
3527 //--------------------------------------------------------------------------------------
\r
3529 //--------------------------------------------------------------------------------------
\r
3530 CDXUTStatic::CDXUTStatic( CDXUTDialog* pDialog )
\r
3532 m_Type = DXUT_CONTROL_STATIC;
\r
3533 m_pDialog = pDialog;
\r
3535 ZeroMemory( &m_strText, sizeof( m_strText ) );
\r
3537 for( int i = 0; i < m_Elements.GetSize(); i++ )
\r
3539 CDXUTElement* pElement = m_Elements.GetAt( i );
\r
3540 SAFE_DELETE( pElement );
\r
3543 m_Elements.RemoveAll();
\r
3547 //--------------------------------------------------------------------------------------
\r
3548 void CDXUTStatic::Render( float fElapsedTime )
\r
3550 if( m_bVisible == false )
\r
3553 DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
\r
3555 if( m_bEnabled == false )
\r
3556 iState = DXUT_STATE_DISABLED;
\r
3558 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
3560 pElement->FontColor.Blend( iState, fElapsedTime );
\r
3562 m_pDialog->DrawText( m_strText, pElement, &m_rcBoundingBox, false, -1, false);
\r
3566 //--------------------------------------------------------------------------------------
\r
3567 HRESULT CDXUTStatic::GetTextCopy( __out_ecount(bufferCount) LPWSTR strDest,
\r
3568 UINT bufferCount )
\r
3570 // Validate incoming parameters
\r
3571 if( strDest == NULL || bufferCount == 0 )
\r
3573 return E_INVALIDARG;
\r
3576 // Copy the window text
\r
3577 wcscpy_s( strDest, bufferCount, m_strText );
\r
3583 //--------------------------------------------------------------------------------------
\r
3584 HRESULT CDXUTStatic::SetText( LPCWSTR strText )
\r
3586 if( strText == NULL )
\r
3592 wcscpy_s( m_strText, MAX_PATH, strText );
\r
3597 //--------------------------------------------------------------------------------------
\r
3598 // CDXUTButton class
\r
3599 //--------------------------------------------------------------------------------------
\r
3601 //--------------------------------------------------------------------------------------
\r
3602 CDXUTButton::CDXUTButton( CDXUTDialog* pDialog )
\r
3604 m_Type = DXUT_CONTROL_BUTTON;
\r
3605 m_pDialog = pDialog;
\r
3607 m_bPressed = false;
\r
3611 //--------------------------------------------------------------------------------------
\r
3612 bool CDXUTButton::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
3614 if( !m_bEnabled || !m_bVisible )
\r
3624 m_bPressed = true;
\r
3634 if( m_bPressed == true )
\r
3636 m_bPressed = false;
\r
3637 m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this );
\r
3647 //--------------------------------------------------------------------------------------
\r
3648 bool CDXUTButton::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
3650 if( !m_bEnabled || !m_bVisible )
\r
3655 case WM_LBUTTONDOWN:
\r
3656 case WM_LBUTTONDBLCLK:
\r
3658 if( ContainsPoint( pt ) )
\r
3660 // Pressed while inside the control
\r
3661 m_bPressed = true;
\r
3662 SetCapture( DXUTGetHWND() );
\r
3664 if( !m_bHasFocus )
\r
3665 m_pDialog->RequestFocus( this );
\r
3673 case WM_LBUTTONUP:
\r
3677 m_bPressed = false;
\r
3680 if( !m_pDialog->m_bKeyboardInput )
\r
3681 m_pDialog->ClearFocus();
\r
3684 if( ContainsPoint( pt ) )
\r
3685 m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this );
\r
3697 //--------------------------------------------------------------------------------------
\r
3698 void CDXUTButton::Render( float fElapsedTime )
\r
3700 if( m_bVisible == false )
\r
3706 DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
\r
3708 if( m_bVisible == false )
\r
3710 iState = DXUT_STATE_HIDDEN;
\r
3712 else if( m_bEnabled == false )
\r
3714 iState = DXUT_STATE_DISABLED;
\r
3716 else if( m_bPressed )
\r
3718 iState = DXUT_STATE_PRESSED;
\r
3723 else if( m_bMouseOver )
\r
3725 iState = DXUT_STATE_MOUSEOVER;
\r
3730 else if( m_bHasFocus )
\r
3732 iState = DXUT_STATE_FOCUS;
\r
3735 // Background fill layer
\r
3736 //TODO: remove magic numbers
\r
3737 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
3739 float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
\r
3741 RECT rcWindow = m_rcBoundingBox;
\r
3742 OffsetRect( &rcWindow, nOffsetX, nOffsetY );
\r
3745 // Blend current color
\r
3746 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
3747 pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
\r
3749 m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_FAR_BUTTON_DEPTH );
\r
3750 m_pDialog->DrawText( m_strText, pElement, &rcWindow, false, -1, true );
\r
3753 pElement = m_Elements.GetAt( 1 );
\r
3755 // Blend current color
\r
3756 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
3757 pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
\r
3759 m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_NEAR_BUTTON_DEPTH );
\r
3760 m_pDialog->DrawText( m_strText, pElement, &rcWindow, false, -1, true );
\r
3765 //--------------------------------------------------------------------------------------
\r
3766 // CDXUTCheckBox class
\r
3767 //--------------------------------------------------------------------------------------
\r
3769 //--------------------------------------------------------------------------------------
\r
3770 CDXUTCheckBox::CDXUTCheckBox( CDXUTDialog* pDialog )
\r
3772 m_Type = DXUT_CONTROL_CHECKBOX;
\r
3773 m_pDialog = pDialog;
\r
3775 m_bChecked = false;
\r
3779 //--------------------------------------------------------------------------------------
\r
3780 bool CDXUTCheckBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
3782 if( !m_bEnabled || !m_bVisible )
\r
3792 m_bPressed = true;
\r
3802 if( m_bPressed == true )
\r
3804 m_bPressed = false;
\r
3805 SetCheckedInternal( !m_bChecked, true );
\r
3815 //--------------------------------------------------------------------------------------
\r
3816 bool CDXUTCheckBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
3818 if( !m_bEnabled || !m_bVisible )
\r
3823 case WM_LBUTTONDOWN:
\r
3824 case WM_LBUTTONDBLCLK:
\r
3826 if( ContainsPoint( pt ) )
\r
3828 // Pressed while inside the control
\r
3829 m_bPressed = true;
\r
3830 SetCapture( DXUTGetHWND() );
\r
3832 if( !m_bHasFocus )
\r
3833 m_pDialog->RequestFocus( this );
\r
3841 case WM_LBUTTONUP:
\r
3845 m_bPressed = false;
\r
3849 if( ContainsPoint( pt ) )
\r
3850 SetCheckedInternal( !m_bChecked, true );
\r
3863 //--------------------------------------------------------------------------------------
\r
3864 void CDXUTCheckBox::SetCheckedInternal( bool bChecked, bool bFromInput )
\r
3866 m_bChecked = bChecked;
\r
3868 m_pDialog->SendEvent( EVENT_CHECKBOX_CHANGED, bFromInput, this );
\r
3872 //--------------------------------------------------------------------------------------
\r
3873 BOOL CDXUTCheckBox::ContainsPoint( POINT pt )
\r
3875 return ( PtInRect( &m_rcBoundingBox, pt ) ||
\r
3876 PtInRect( &m_rcButton, pt ) );
\r
3881 //--------------------------------------------------------------------------------------
\r
3882 void CDXUTCheckBox::UpdateRects()
\r
3884 CDXUTButton::UpdateRects();
\r
3886 m_rcButton = m_rcBoundingBox;
\r
3887 m_rcButton.right = m_rcButton.left + RectHeight( m_rcButton );
\r
3889 m_rcText = m_rcBoundingBox;
\r
3890 m_rcText.left += ( int )( 1.25f * RectWidth( m_rcButton ) );
\r
3895 //--------------------------------------------------------------------------------------
\r
3896 void CDXUTCheckBox::Render( float fElapsedTime )
\r
3898 if( m_bVisible == false )
\r
3900 DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
\r
3902 if( m_bVisible == false )
\r
3903 iState = DXUT_STATE_HIDDEN;
\r
3904 else if( m_bEnabled == false )
\r
3905 iState = DXUT_STATE_DISABLED;
\r
3906 else if( m_bPressed )
\r
3907 iState = DXUT_STATE_PRESSED;
\r
3908 else if( m_bMouseOver )
\r
3909 iState = DXUT_STATE_MOUSEOVER;
\r
3910 else if( m_bHasFocus )
\r
3911 iState = DXUT_STATE_FOCUS;
\r
3913 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
3915 float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
\r
3917 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
3918 pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
\r
3920 m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_NEAR_BUTTON_DEPTH );
\r
3921 m_pDialog->DrawText( m_strText, pElement, &m_rcText, false, -1, false );
\r
3924 iState = DXUT_STATE_HIDDEN;
\r
3926 pElement = m_Elements.GetAt( 1 );
\r
3928 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
3929 m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_FAR_BUTTON_DEPTH );
\r
3935 //--------------------------------------------------------------------------------------
\r
3936 // CDXUTRadioButton class
\r
3937 //--------------------------------------------------------------------------------------
\r
3939 //--------------------------------------------------------------------------------------
\r
3940 CDXUTRadioButton::CDXUTRadioButton( CDXUTDialog* pDialog )
\r
3942 m_Type = DXUT_CONTROL_RADIOBUTTON;
\r
3943 m_pDialog = pDialog;
\r
3948 //--------------------------------------------------------------------------------------
\r
3949 bool CDXUTRadioButton::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
3951 if( !m_bEnabled || !m_bVisible )
\r
3961 m_bPressed = true;
\r
3971 if( m_bPressed == true )
\r
3973 m_bPressed = false;
\r
3975 m_pDialog->ClearRadioButtonGroup( m_nButtonGroup );
\r
3976 m_bChecked = !m_bChecked;
\r
3978 m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, true, this );
\r
3988 //--------------------------------------------------------------------------------------
\r
3989 bool CDXUTRadioButton::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
3991 if( !m_bEnabled || !m_bVisible )
\r
3996 case WM_LBUTTONDOWN:
\r
3997 case WM_LBUTTONDBLCLK:
\r
3999 if( ContainsPoint( pt ) )
\r
4001 // Pressed while inside the control
\r
4002 m_bPressed = true;
\r
4003 SetCapture( DXUTGetHWND() );
\r
4005 if( !m_bHasFocus )
\r
4006 m_pDialog->RequestFocus( this );
\r
4014 case WM_LBUTTONUP:
\r
4018 m_bPressed = false;
\r
4022 if( ContainsPoint( pt ) )
\r
4024 m_pDialog->ClearRadioButtonGroup( m_nButtonGroup );
\r
4025 m_bChecked = !m_bChecked;
\r
4027 m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, true, this );
\r
4040 //--------------------------------------------------------------------------------------
\r
4041 void CDXUTRadioButton::SetCheckedInternal( bool bChecked, bool bClearGroup, bool bFromInput )
\r
4043 if( bChecked && bClearGroup )
\r
4044 m_pDialog->ClearRadioButtonGroup( m_nButtonGroup );
\r
4046 m_bChecked = bChecked;
\r
4047 m_pDialog->SendEvent( EVENT_RADIOBUTTON_CHANGED, bFromInput, this );
\r
4053 //--------------------------------------------------------------------------------------
\r
4054 // CDXUTComboBox class
\r
4055 //--------------------------------------------------------------------------------------
\r
4057 //--------------------------------------------------------------------------------------
\r
4058 CDXUTComboBox::CDXUTComboBox( CDXUTDialog* pDialog ) : m_ScrollBar( pDialog )
\r
4060 m_Type = DXUT_CONTROL_COMBOBOX;
\r
4061 m_pDialog = pDialog;
\r
4063 m_nDropHeight = 100;
\r
4066 m_bOpened = false;
\r
4072 //--------------------------------------------------------------------------------------
\r
4073 CDXUTComboBox::~CDXUTComboBox()
\r
4079 //--------------------------------------------------------------------------------------
\r
4080 void CDXUTComboBox::SetTextColor( D3DCOLOR Color )
\r
4082 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
4085 pElement->FontColor.States[DXUT_STATE_NORMAL] = Color;
\r
4087 pElement = m_Elements.GetAt( 2 );
\r
4090 pElement->FontColor.States[DXUT_STATE_NORMAL] = Color;
\r
4094 //--------------------------------------------------------------------------------------
\r
4095 void CDXUTComboBox::UpdateRects()
\r
4098 CDXUTButton::UpdateRects();
\r
4100 m_rcButton = m_rcBoundingBox;
\r
4101 m_rcButton.left = m_rcButton.right - RectHeight( m_rcButton );
\r
4103 m_rcText = m_rcBoundingBox;
\r
4104 m_rcText.right = m_rcButton.left;
\r
4106 m_rcDropdown = m_rcText;
\r
4107 OffsetRect( &m_rcDropdown, 0, ( int )( 0.90f * RectHeight( m_rcText ) ) );
\r
4108 m_rcDropdown.bottom += m_nDropHeight;
\r
4109 m_rcDropdown.right -= m_nSBWidth;
\r
4111 m_rcDropdownText = m_rcDropdown;
\r
4112 m_rcDropdownText.left += ( int )( 0.1f * RectWidth( m_rcDropdown ) );
\r
4113 m_rcDropdownText.right -= ( int )( 0.1f * RectWidth( m_rcDropdown ) );
\r
4114 m_rcDropdownText.top += ( int )( 0.1f * RectHeight( m_rcDropdown ) );
\r
4115 m_rcDropdownText.bottom -= ( int )( 0.1f * RectHeight( m_rcDropdown ) );
\r
4117 // Update the scrollbar's rects
\r
4118 m_ScrollBar.SetLocation( m_rcDropdown.right, m_rcDropdown.top + 2 );
\r
4119 m_ScrollBar.SetSize( m_nSBWidth, RectHeight( m_rcDropdown ) - 2 );
\r
4120 DXUTFontNode* pFontNode = m_pDialog->GetManager()->GetFontNode( m_Elements.GetAt( 2 )->iFont );
\r
4121 if( pFontNode && pFontNode->nHeight )
\r
4123 m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) / pFontNode->nHeight );
\r
4125 // The selected item may have been scrolled off the page.
\r
4126 // Ensure that it is in page again.
\r
4127 m_ScrollBar.ShowItem( m_iSelected );
\r
4132 //--------------------------------------------------------------------------------------
\r
4133 void CDXUTComboBox::OnFocusOut()
\r
4135 CDXUTButton::OnFocusOut();
\r
4137 m_bOpened = false;
\r
4141 //--------------------------------------------------------------------------------------
\r
4142 bool CDXUTComboBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
4144 const DWORD REPEAT_MASK = ( 0x40000000 );
\r
4146 if( !m_bEnabled || !m_bVisible )
\r
4149 // Let the scroll bar have a chance to handle it first
\r
4150 if( m_ScrollBar.HandleKeyboard( uMsg, wParam, lParam ) )
\r
4162 if( m_iSelected != m_iFocused )
\r
4164 m_iSelected = m_iFocused;
\r
4165 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4167 m_bOpened = false;
\r
4169 if( !m_pDialog->m_bKeyboardInput )
\r
4170 m_pDialog->ClearFocus();
\r
4177 // Filter out auto-repeats
\r
4178 if( lParam & REPEAT_MASK )
\r
4181 m_bOpened = !m_bOpened;
\r
4185 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4187 if( !m_pDialog->m_bKeyboardInput )
\r
4188 m_pDialog->ClearFocus();
\r
4195 if( m_iFocused > 0 )
\r
4198 m_iSelected = m_iFocused;
\r
4201 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4208 if( m_iFocused + 1 < ( int )GetNumItems() )
\r
4211 m_iSelected = m_iFocused;
\r
4214 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4227 //--------------------------------------------------------------------------------------
\r
4228 bool CDXUTComboBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
4230 if( !m_bEnabled || !m_bVisible )
\r
4233 // Let the scroll bar handle it first.
\r
4234 if( m_ScrollBar.HandleMouse( uMsg, pt, wParam, lParam ) )
\r
4239 case WM_MOUSEMOVE:
\r
4241 if( m_bOpened && PtInRect( &m_rcDropdown, pt ) )
\r
4243 // Determine which item has been selected
\r
4244 for( int i = 0; i < m_Items.GetSize(); i++ )
\r
4246 DXUTComboBoxItem* pItem = m_Items.GetAt( i );
\r
4247 if( pItem->bVisible &&
\r
4248 PtInRect( &pItem->rcActive, pt ) )
\r
4258 case WM_LBUTTONDOWN:
\r
4259 case WM_LBUTTONDBLCLK:
\r
4261 if( ContainsPoint( pt ) )
\r
4263 // Pressed while inside the control
\r
4264 m_bPressed = true;
\r
4265 SetCapture( DXUTGetHWND() );
\r
4267 if( !m_bHasFocus )
\r
4268 m_pDialog->RequestFocus( this );
\r
4270 // Toggle dropdown
\r
4273 m_bOpened = !m_bOpened;
\r
4277 if( !m_pDialog->m_bKeyboardInput )
\r
4278 m_pDialog->ClearFocus();
\r
4285 // Perhaps this click is within the dropdown
\r
4286 if( m_bOpened && PtInRect( &m_rcDropdown, pt ) )
\r
4288 // Determine which item has been selected
\r
4289 for( int i = m_ScrollBar.GetTrackPos(); i < m_Items.GetSize(); i++ )
\r
4291 DXUTComboBoxItem* pItem = m_Items.GetAt( i );
\r
4292 if( pItem->bVisible &&
\r
4293 PtInRect( &pItem->rcActive, pt ) )
\r
4295 m_iFocused = m_iSelected = i;
\r
4296 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4297 m_bOpened = false;
\r
4299 if( !m_pDialog->m_bKeyboardInput )
\r
4300 m_pDialog->ClearFocus();
\r
4309 // Mouse click not on main control or in dropdown, fire an event if needed
\r
4312 m_iFocused = m_iSelected;
\r
4314 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4315 m_bOpened = false;
\r
4318 // Make sure the control is no longer in a pressed state
\r
4319 m_bPressed = false;
\r
4321 // Release focus if appropriate
\r
4322 if( !m_pDialog->m_bKeyboardInput )
\r
4324 m_pDialog->ClearFocus();
\r
4330 case WM_LBUTTONUP:
\r
4332 if( m_bPressed && ContainsPoint( pt ) )
\r
4335 m_bPressed = false;
\r
4343 case WM_MOUSEWHEEL:
\r
4345 int zDelta = ( short )HIWORD( wParam ) / WHEEL_DELTA;
\r
4349 SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &uLines, 0 );
\r
4350 m_ScrollBar.Scroll( -zDelta * uLines );
\r
4356 if( m_iFocused > 0 )
\r
4359 m_iSelected = m_iFocused;
\r
4362 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4367 if( m_iFocused + 1 < ( int )GetNumItems() )
\r
4370 m_iSelected = m_iFocused;
\r
4373 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4385 //--------------------------------------------------------------------------------------
\r
4386 void CDXUTComboBox::OnHotkey()
\r
4391 if( m_iSelected == -1 )
\r
4394 if( m_pDialog->IsKeyboardInputEnabled() )
\r
4395 m_pDialog->RequestFocus( this );
\r
4399 if( m_iSelected >= ( int )m_Items.GetSize() )
\r
4402 m_iFocused = m_iSelected;
\r
4403 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, true, this );
\r
4407 //--------------------------------------------------------------------------------------
\r
4408 void CDXUTComboBox::Render( float fElapsedTime )
\r
4410 if( m_bVisible == false )
\r
4412 DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
\r
4415 iState = DXUT_STATE_HIDDEN;
\r
4418 CDXUTElement* pElement = m_Elements.GetAt( 2 );
\r
4420 // If we have not initialized the scroll bar page size,
\r
4422 static bool bSBInit;
\r
4425 // Update the page size of the scroll bar
\r
4426 if( m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight )
\r
4427 m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) /
\r
4428 m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight );
\r
4430 m_ScrollBar.SetPageSize( RectHeight( m_rcDropdownText ) );
\r
4436 m_ScrollBar.Render( fElapsedTime );
\r
4438 // Blend current color
\r
4439 pElement->TextureColor.Blend( iState, fElapsedTime );
\r
4440 pElement->FontColor.Blend( iState, fElapsedTime );
\r
4442 m_pDialog->DrawSprite( pElement, &m_rcDropdown, DXUT_NEAR_BUTTON_DEPTH );
\r
4444 // Selection outline
\r
4445 CDXUTElement* pSelectionElement = m_Elements.GetAt( 3 );
\r
4446 pSelectionElement->TextureColor.Current = pElement->TextureColor.Current;
\r
4447 pSelectionElement->FontColor.Current = pSelectionElement->FontColor.States[ DXUT_STATE_NORMAL ];
\r
4449 DXUTFontNode* pFont = m_pDialog->GetFont( pElement->iFont );
\r
4452 int curY = m_rcDropdownText.top;
\r
4453 int nRemainingHeight = RectHeight( m_rcDropdownText );
\r
4454 //WCHAR strDropdown[4096] = {0};
\r
4456 for( int i = m_ScrollBar.GetTrackPos(); i < m_Items.GetSize(); i++ )
\r
4458 DXUTComboBoxItem* pItem = m_Items.GetAt( i );
\r
4460 // Make sure there's room left in the dropdown
\r
4461 nRemainingHeight -= pFont->nHeight;
\r
4462 if( nRemainingHeight < 0 )
\r
4464 pItem->bVisible = false;
\r
4468 SetRect( &pItem->rcActive, m_rcDropdownText.left, curY, m_rcDropdownText.right, curY + pFont->nHeight );
\r
4469 curY += pFont->nHeight;
\r
4472 //int blue = 50 * i;
\r
4473 //m_pDialog->DrawRect( &pItem->rcActive, 0xFFFF0000 | blue );
\r
4475 pItem->bVisible = true;
\r
4479 if( ( int )i == m_iFocused )
\r
4482 SetRect( &rc, m_rcDropdown.left, pItem->rcActive.top - 2, m_rcDropdown.right,
\r
4483 pItem->rcActive.bottom + 2 );
\r
4484 m_pDialog->DrawSprite( pSelectionElement, &rc, DXUT_NEAR_BUTTON_DEPTH );
\r
4485 m_pDialog->DrawText( pItem->strText, pSelectionElement, &pItem->rcActive );
\r
4489 m_pDialog->DrawText( pItem->strText, pElement, &pItem->rcActive );
\r
4498 iState = DXUT_STATE_NORMAL;
\r
4500 if( m_bVisible == false )
\r
4501 iState = DXUT_STATE_HIDDEN;
\r
4502 else if( m_bEnabled == false )
\r
4503 iState = DXUT_STATE_DISABLED;
\r
4504 else if( m_bPressed )
\r
4506 iState = DXUT_STATE_PRESSED;
\r
4511 else if( m_bMouseOver )
\r
4513 iState = DXUT_STATE_MOUSEOVER;
\r
4518 else if( m_bHasFocus )
\r
4519 iState = DXUT_STATE_FOCUS;
\r
4521 float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
\r
4524 pElement = m_Elements.GetAt( 1 );
\r
4526 // Blend current color
\r
4527 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
4529 RECT rcWindow = m_rcButton;
\r
4530 OffsetRect( &rcWindow, nOffsetX, nOffsetY );
\r
4531 m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_FAR_BUTTON_DEPTH );
\r
4534 iState = DXUT_STATE_PRESSED;
\r
4537 //TODO: remove magic numbers
\r
4538 pElement = m_Elements.GetAt( 0 );
\r
4540 // Blend current color
\r
4541 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
4542 pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
\r
4544 m_pDialog->DrawSprite( pElement, &m_rcText, DXUT_NEAR_BUTTON_DEPTH );
\r
4546 if( m_iSelected >= 0 && m_iSelected < ( int )m_Items.GetSize() )
\r
4548 DXUTComboBoxItem* pItem = m_Items.GetAt( m_iSelected );
\r
4549 if( pItem != NULL )
\r
4551 m_pDialog->DrawText( pItem->strText, pElement, &m_rcText, false, -1, true );
\r
4558 //--------------------------------------------------------------------------------------
\r
4559 HRESULT CDXUTComboBox::AddItem( const WCHAR* strText, void* pData )
\r
4561 // Validate parameters
\r
4562 if( strText == NULL )
\r
4564 return E_INVALIDARG;
\r
4567 // Create a new item and set the data
\r
4568 DXUTComboBoxItem* pItem = new DXUTComboBoxItem;
\r
4569 if( pItem == NULL )
\r
4571 return DXTRACE_ERR_MSGBOX( L"new", E_OUTOFMEMORY );
\r
4574 ZeroMemory( pItem, sizeof( DXUTComboBoxItem ) );
\r
4575 wcscpy_s( pItem->strText, 256, strText );
\r
4576 pItem->pData = pData;
\r
4578 m_Items.Add( pItem );
\r
4580 // Update the scroll bar with new range
\r
4581 m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
\r
4583 // If this is the only item in the list, it's selected
\r
4584 if( GetNumItems() == 1 )
\r
4588 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
\r
4595 //--------------------------------------------------------------------------------------
\r
4596 void CDXUTComboBox::RemoveItem( UINT index )
\r
4598 DXUTComboBoxItem* pItem = m_Items.GetAt( index );
\r
4599 SAFE_DELETE( pItem );
\r
4600 m_Items.Remove( index );
\r
4601 m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
\r
4602 if( m_iSelected >= m_Items.GetSize() )
\r
4603 m_iSelected = m_Items.GetSize() - 1;
\r
4607 //--------------------------------------------------------------------------------------
\r
4608 void CDXUTComboBox::RemoveAllItems()
\r
4610 for( int i = 0; i < m_Items.GetSize(); i++ )
\r
4612 DXUTComboBoxItem* pItem = m_Items.GetAt( i );
\r
4613 SAFE_DELETE( pItem );
\r
4616 m_Items.RemoveAll();
\r
4617 m_ScrollBar.SetTrackRange( 0, 1 );
\r
4618 m_iFocused = m_iSelected = -1;
\r
4623 //--------------------------------------------------------------------------------------
\r
4624 bool CDXUTComboBox::ContainsItem( const WCHAR* strText, UINT iStart )
\r
4626 return ( -1 != FindItem( strText, iStart ) );
\r
4630 //--------------------------------------------------------------------------------------
\r
4631 int CDXUTComboBox::FindItem( const WCHAR* strText, UINT iStart )
\r
4633 if( strText == NULL )
\r
4636 for( int i = iStart; i < m_Items.GetSize(); i++ )
\r
4638 DXUTComboBoxItem* pItem = m_Items.GetAt( i );
\r
4640 if( 0 == wcscmp( pItem->strText, strText ) )
\r
4650 //--------------------------------------------------------------------------------------
\r
4651 void* CDXUTComboBox::GetSelectedData()
\r
4653 if( m_iSelected < 0 )
\r
4656 DXUTComboBoxItem* pItem = m_Items.GetAt( m_iSelected );
\r
4657 return pItem->pData;
\r
4661 //--------------------------------------------------------------------------------------
\r
4662 DXUTComboBoxItem* CDXUTComboBox::GetSelectedItem()
\r
4664 if( m_iSelected < 0 )
\r
4667 return m_Items.GetAt( m_iSelected );
\r
4671 //--------------------------------------------------------------------------------------
\r
4672 void* CDXUTComboBox::GetItemData( const WCHAR* strText )
\r
4674 int index = FindItem( strText );
\r
4680 DXUTComboBoxItem* pItem = m_Items.GetAt( index );
\r
4681 if( pItem == NULL )
\r
4683 DXTRACE_ERR( L"CGrowableArray::GetAt", E_FAIL );
\r
4687 return pItem->pData;
\r
4691 //--------------------------------------------------------------------------------------
\r
4692 void* CDXUTComboBox::GetItemData( int nIndex )
\r
4694 if( nIndex < 0 || nIndex >= m_Items.GetSize() )
\r
4697 return m_Items.GetAt( nIndex )->pData;
\r
4701 //--------------------------------------------------------------------------------------
\r
4702 HRESULT CDXUTComboBox::SetSelectedByIndex( UINT index )
\r
4704 if( index >= GetNumItems() )
\r
4705 return E_INVALIDARG;
\r
4707 m_iFocused = m_iSelected = index;
\r
4708 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
\r
4715 //--------------------------------------------------------------------------------------
\r
4716 HRESULT CDXUTComboBox::SetSelectedByText( const WCHAR* strText )
\r
4718 if( strText == NULL )
\r
4719 return E_INVALIDARG;
\r
4721 int index = FindItem( strText );
\r
4725 m_iFocused = m_iSelected = index;
\r
4726 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
\r
4733 //--------------------------------------------------------------------------------------
\r
4734 HRESULT CDXUTComboBox::SetSelectedByData( void* pData )
\r
4736 for( int i = 0; i < m_Items.GetSize(); i++ )
\r
4738 DXUTComboBoxItem* pItem = m_Items.GetAt( i );
\r
4740 if( pItem->pData == pData )
\r
4742 m_iFocused = m_iSelected = i;
\r
4743 m_pDialog->SendEvent( EVENT_COMBOBOX_SELECTION_CHANGED, false, this );
\r
4753 //--------------------------------------------------------------------------------------
\r
4754 CDXUTSlider::CDXUTSlider( CDXUTDialog* pDialog )
\r
4756 m_Type = DXUT_CONTROL_SLIDER;
\r
4757 m_pDialog = pDialog;
\r
4763 m_bPressed = false;
\r
4767 //--------------------------------------------------------------------------------------
\r
4768 BOOL CDXUTSlider::ContainsPoint( POINT pt )
\r
4770 return ( PtInRect( &m_rcBoundingBox, pt ) ||
\r
4771 PtInRect( &m_rcButton, pt ) );
\r
4775 //--------------------------------------------------------------------------------------
\r
4776 void CDXUTSlider::UpdateRects()
\r
4778 CDXUTControl::UpdateRects();
\r
4780 m_rcButton = m_rcBoundingBox;
\r
4781 m_rcButton.right = m_rcButton.left + RectHeight( m_rcButton );
\r
4782 OffsetRect( &m_rcButton, -RectWidth( m_rcButton ) / 2, 0 );
\r
4784 m_nButtonX = ( int )( ( m_nValue - m_nMin ) * ( float )RectWidth( m_rcBoundingBox ) / ( m_nMax - m_nMin ) );
\r
4785 OffsetRect( &m_rcButton, m_nButtonX, 0 );
\r
4788 int CDXUTSlider::ValueFromPos( int x )
\r
4790 float fValuePerPixel = ( float )( m_nMax - m_nMin ) / RectWidth( m_rcBoundingBox );
\r
4791 return ( int )( 0.5f + m_nMin + fValuePerPixel * ( x - m_rcBoundingBox.left ) );
\r
4794 //--------------------------------------------------------------------------------------
\r
4795 bool CDXUTSlider::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
4797 if( !m_bEnabled || !m_bVisible )
\r
4807 SetValueInternal( m_nMin, true );
\r
4811 SetValueInternal( m_nMax, true );
\r
4816 SetValueInternal( m_nValue - 1, true );
\r
4821 SetValueInternal( m_nValue + 1, true );
\r
4825 SetValueInternal( m_nValue - ( 10 > ( m_nMax - m_nMin ) / 10 ? 10 : ( m_nMax - m_nMin ) / 10 ),
\r
4830 SetValueInternal( m_nValue + ( 10 > ( m_nMax - m_nMin ) / 10 ? 10 : ( m_nMax - m_nMin ) / 10 ),
\r
4843 //--------------------------------------------------------------------------------------
\r
4844 bool CDXUTSlider::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
4846 if( !m_bEnabled || !m_bVisible )
\r
4851 case WM_LBUTTONDOWN:
\r
4852 case WM_LBUTTONDBLCLK:
\r
4854 if( PtInRect( &m_rcButton, pt ) )
\r
4856 // Pressed while inside the control
\r
4857 m_bPressed = true;
\r
4858 SetCapture( DXUTGetHWND() );
\r
4861 //m_nDragY = pt.y;
\r
4862 m_nDragOffset = m_nButtonX - m_nDragX;
\r
4864 //m_nDragValue = m_nValue;
\r
4866 if( !m_bHasFocus )
\r
4867 m_pDialog->RequestFocus( this );
\r
4872 if( PtInRect( &m_rcBoundingBox, pt ) )
\r
4875 m_nDragOffset = 0;
\r
4876 m_bPressed = true;
\r
4878 if( !m_bHasFocus )
\r
4879 m_pDialog->RequestFocus( this );
\r
4881 if( pt.x > m_nButtonX + m_x )
\r
4883 SetValueInternal( m_nValue + 1, true );
\r
4887 if( pt.x < m_nButtonX + m_x )
\r
4889 SetValueInternal( m_nValue - 1, true );
\r
4897 case WM_LBUTTONUP:
\r
4901 m_bPressed = false;
\r
4903 m_pDialog->SendEvent( EVENT_SLIDER_VALUE_CHANGED_UP, true, this );
\r
4911 case WM_MOUSEMOVE:
\r
4915 SetValueInternal( ValueFromPos( m_x + pt.x + m_nDragOffset ), true );
\r
4922 case WM_MOUSEWHEEL:
\r
4924 int nScrollAmount = int( ( short )HIWORD( wParam ) ) / WHEEL_DELTA;
\r
4925 SetValueInternal( m_nValue - nScrollAmount, true );
\r
4934 //--------------------------------------------------------------------------------------
\r
4935 void CDXUTSlider::SetRange( int nMin, int nMax )
\r
4940 SetValueInternal( m_nValue, false );
\r
4944 //--------------------------------------------------------------------------------------
\r
4945 void CDXUTSlider::SetValueInternal( int nValue, bool bFromInput )
\r
4948 nValue = __max( m_nMin, nValue );
\r
4949 nValue = __min( m_nMax, nValue );
\r
4951 if( nValue == m_nValue )
\r
4954 m_nValue = nValue;
\r
4957 m_pDialog->SendEvent( EVENT_SLIDER_VALUE_CHANGED, bFromInput, this );
\r
4961 //--------------------------------------------------------------------------------------
\r
4962 void CDXUTSlider::Render( float fElapsedTime )
\r
4964 if( m_bVisible == false )
\r
4970 DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
\r
4972 if( m_bVisible == false )
\r
4974 iState = DXUT_STATE_HIDDEN;
\r
4976 else if( m_bEnabled == false )
\r
4978 iState = DXUT_STATE_DISABLED;
\r
4980 else if( m_bPressed )
\r
4982 iState = DXUT_STATE_PRESSED;
\r
4987 else if( m_bMouseOver )
\r
4989 iState = DXUT_STATE_MOUSEOVER;
\r
4994 else if( m_bHasFocus )
\r
4996 iState = DXUT_STATE_FOCUS;
\r
4999 float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
\r
5001 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
5003 // Blend current color
\r
5004 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
5005 m_pDialog->DrawSprite( pElement, &m_rcBoundingBox, DXUT_FAR_BUTTON_DEPTH );
\r
5007 //TODO: remove magic numbers
\r
5008 pElement = m_Elements.GetAt( 1 );
\r
5010 // Blend current color
\r
5011 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
5012 m_pDialog->DrawSprite( pElement, &m_rcButton, DXUT_NEAR_BUTTON_DEPTH );
\r
5016 //--------------------------------------------------------------------------------------
\r
5017 // CDXUTScrollBar class
\r
5018 //--------------------------------------------------------------------------------------
\r
5020 //--------------------------------------------------------------------------------------
\r
5021 CDXUTScrollBar::CDXUTScrollBar( CDXUTDialog* pDialog )
\r
5023 m_Type = DXUT_CONTROL_SCROLLBAR;
\r
5024 m_pDialog = pDialog;
\r
5026 m_bShowThumb = true;
\r
5029 SetRect( &m_rcUpButton, 0, 0, 0, 0 );
\r
5030 SetRect( &m_rcDownButton, 0, 0, 0, 0 );
\r
5031 SetRect( &m_rcTrack, 0, 0, 0, 0 );
\r
5032 SetRect( &m_rcThumb, 0, 0, 0, 0 );
\r
5042 //--------------------------------------------------------------------------------------
\r
5043 CDXUTScrollBar::~CDXUTScrollBar()
\r
5048 //--------------------------------------------------------------------------------------
\r
5049 void CDXUTScrollBar::UpdateRects()
\r
5051 CDXUTControl::UpdateRects();
\r
5053 // Make the buttons square
\r
5055 SetRect( &m_rcUpButton, m_rcBoundingBox.left, m_rcBoundingBox.top,
\r
5056 m_rcBoundingBox.right, m_rcBoundingBox.top + RectWidth( m_rcBoundingBox ) );
\r
5057 SetRect( &m_rcDownButton, m_rcBoundingBox.left, m_rcBoundingBox.bottom - RectWidth( m_rcBoundingBox ),
\r
5058 m_rcBoundingBox.right, m_rcBoundingBox.bottom );
\r
5059 SetRect( &m_rcTrack, m_rcUpButton.left, m_rcUpButton.bottom,
\r
5060 m_rcDownButton.right, m_rcDownButton.top );
\r
5061 m_rcThumb.left = m_rcUpButton.left;
\r
5062 m_rcThumb.right = m_rcUpButton.right;
\r
5064 UpdateThumbRect();
\r
5068 //--------------------------------------------------------------------------------------
\r
5069 // Compute the dimension of the scroll thumb
\r
5070 void CDXUTScrollBar::UpdateThumbRect()
\r
5072 if( m_nEnd - m_nStart > m_nPageSize )
\r
5074 int nThumbHeight = __max( RectHeight( m_rcTrack ) * m_nPageSize / ( m_nEnd - m_nStart ),
\r
5075 SCROLLBAR_MINTHUMBSIZE );
\r
5076 int nMaxPosition = m_nEnd - m_nStart - m_nPageSize;
\r
5077 m_rcThumb.top = m_rcTrack.top + ( m_nPosition - m_nStart ) * ( RectHeight( m_rcTrack ) - nThumbHeight )
\r
5079 m_rcThumb.bottom = m_rcThumb.top + nThumbHeight;
\r
5080 m_bShowThumb = true;
\r
5085 // No content to scroll
\r
5086 m_rcThumb.bottom = m_rcThumb.top;
\r
5087 m_bShowThumb = false;
\r
5092 //--------------------------------------------------------------------------------------
\r
5093 // Scroll() scrolls by nDelta items. A positive value scrolls down, while a negative
\r
5094 // value scrolls up.
\r
5095 void CDXUTScrollBar::Scroll( int nDelta )
\r
5098 m_nPosition += nDelta;
\r
5103 // Update thumb position
\r
5104 UpdateThumbRect();
\r
5108 //--------------------------------------------------------------------------------------
\r
5109 void CDXUTScrollBar::ShowItem( int nIndex )
\r
5116 if( nIndex >= m_nEnd )
\r
5117 nIndex = m_nEnd - 1;
\r
5119 // Adjust position
\r
5121 if( m_nPosition > nIndex )
\r
5122 m_nPosition = nIndex;
\r
5123 else if( m_nPosition + m_nPageSize <= nIndex )
\r
5124 m_nPosition = nIndex - m_nPageSize + 1;
\r
5126 UpdateThumbRect();
\r
5130 //--------------------------------------------------------------------------------------
\r
5131 bool CDXUTScrollBar::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
5137 //--------------------------------------------------------------------------------------
\r
5138 bool CDXUTScrollBar::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
5140 static int ThumbOffsetY;
\r
5145 case WM_LBUTTONDOWN:
\r
5146 case WM_LBUTTONDBLCLK:
\r
5148 // Check for click on up button
\r
5150 if( PtInRect( &m_rcUpButton, pt ) )
\r
5152 SetCapture( DXUTGetHWND() );
\r
5153 if( m_nPosition > m_nStart )
\r
5155 UpdateThumbRect();
\r
5156 m_Arrow = CLICKED_UP;
\r
5157 m_dArrowTS = DXUTGetTime();
\r
5161 // Check for click on down button
\r
5163 if( PtInRect( &m_rcDownButton, pt ) )
\r
5165 SetCapture( DXUTGetHWND() );
\r
5166 if( m_nPosition + m_nPageSize < m_nEnd )
\r
5168 UpdateThumbRect();
\r
5169 m_Arrow = CLICKED_DOWN;
\r
5170 m_dArrowTS = DXUTGetTime();
\r
5174 // Check for click on thumb
\r
5176 if( PtInRect( &m_rcThumb, pt ) )
\r
5178 SetCapture( DXUTGetHWND() );
\r
5180 ThumbOffsetY = pt.y - m_rcThumb.top;
\r
5184 // Check for click on track
\r
5186 if( m_rcThumb.left <= pt.x &&
\r
5187 m_rcThumb.right > pt.x )
\r
5189 SetCapture( DXUTGetHWND() );
\r
5190 if( m_rcThumb.top > pt.y &&
\r
5191 m_rcTrack.top <= pt.y )
\r
5193 Scroll( -( m_nPageSize - 1 ) );
\r
5196 else if( m_rcThumb.bottom <= pt.y &&
\r
5197 m_rcTrack.bottom > pt.y )
\r
5199 Scroll( m_nPageSize - 1 );
\r
5207 case WM_LBUTTONUP:
\r
5211 UpdateThumbRect();
\r
5216 case WM_MOUSEMOVE:
\r
5220 m_rcThumb.bottom += pt.y - ThumbOffsetY - m_rcThumb.top;
\r
5221 m_rcThumb.top = pt.y - ThumbOffsetY;
\r
5222 if( m_rcThumb.top < m_rcTrack.top )
\r
5223 OffsetRect( &m_rcThumb, 0, m_rcTrack.top - m_rcThumb.top );
\r
5224 else if( m_rcThumb.bottom > m_rcTrack.bottom )
\r
5225 OffsetRect( &m_rcThumb, 0, m_rcTrack.bottom - m_rcThumb.bottom );
\r
5227 // Compute first item index based on thumb position
\r
5229 int nMaxFirstItem = m_nEnd - m_nStart - m_nPageSize; // Largest possible index for first item
\r
5230 int nMaxThumb = RectHeight( m_rcTrack ) - RectHeight( m_rcThumb ); // Largest possible thumb position from the top
\r
5232 m_nPosition = m_nStart +
\r
5233 ( m_rcThumb.top - m_rcTrack.top +
\r
5234 nMaxThumb / ( nMaxFirstItem * 2 ) ) * // Shift by half a row to avoid last row covered by only one pixel
\r
5235 nMaxFirstItem / nMaxThumb;
\r
5248 //--------------------------------------------------------------------------------------
\r
5249 bool CDXUTScrollBar::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
5251 if( WM_CAPTURECHANGED == uMsg )
\r
5253 // The application just lost mouse capture. We may not have gotten
\r
5254 // the WM_MOUSEUP message, so reset m_bDrag here.
\r
5255 if( ( HWND )lParam != DXUTGetHWND() )
\r
5263 //--------------------------------------------------------------------------------------
\r
5264 void CDXUTScrollBar::Render( float fElapsedTime )
\r
5266 if( m_bVisible == false )
\r
5269 // Check if the arrow button has been held for a while.
\r
5270 // If so, update the thumb position to simulate repeated
\r
5272 if( m_Arrow != CLEAR )
\r
5274 double dCurrTime = DXUTGetTime();
\r
5275 if( PtInRect( &m_rcUpButton, m_LastMouse ) )
\r
5280 if( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS )
\r
5283 m_Arrow = HELD_UP;
\r
5284 m_dArrowTS = dCurrTime;
\r
5288 if( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS )
\r
5291 m_dArrowTS = dCurrTime;
\r
5296 else if( PtInRect( &m_rcDownButton, m_LastMouse ) )
\r
5300 case CLICKED_DOWN:
\r
5301 if( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS )
\r
5304 m_Arrow = HELD_DOWN;
\r
5305 m_dArrowTS = dCurrTime;
\r
5309 if( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS )
\r
5312 m_dArrowTS = dCurrTime;
\r
5319 DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
\r
5321 if( m_bVisible == false )
\r
5322 iState = DXUT_STATE_HIDDEN;
\r
5323 else if( m_bEnabled == false || m_bShowThumb == false )
\r
5324 iState = DXUT_STATE_DISABLED;
\r
5325 else if( m_bMouseOver )
\r
5326 iState = DXUT_STATE_MOUSEOVER;
\r
5327 else if( m_bHasFocus )
\r
5328 iState = DXUT_STATE_FOCUS;
\r
5331 float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
\r
5333 // Background track layer
\r
5334 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
5336 // Blend current color
\r
5337 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
5338 m_pDialog->DrawSprite( pElement, &m_rcTrack, DXUT_FAR_BUTTON_DEPTH );
\r
5341 pElement = m_Elements.GetAt( 1 );
\r
5343 // Blend current color
\r
5344 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
5345 m_pDialog->DrawSprite( pElement, &m_rcUpButton, DXUT_NEAR_BUTTON_DEPTH );
\r
5348 pElement = m_Elements.GetAt( 2 );
\r
5350 // Blend current color
\r
5351 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
5352 m_pDialog->DrawSprite( pElement, &m_rcDownButton, DXUT_NEAR_BUTTON_DEPTH );
\r
5355 pElement = m_Elements.GetAt( 3 );
\r
5357 // Blend current color
\r
5358 pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
\r
5359 m_pDialog->DrawSprite( pElement, &m_rcThumb, DXUT_NEAR_BUTTON_DEPTH );
\r
5364 //--------------------------------------------------------------------------------------
\r
5365 void CDXUTScrollBar::SetTrackRange( int nStart, int nEnd )
\r
5367 m_nStart = nStart; m_nEnd = nEnd;
\r
5369 UpdateThumbRect();
\r
5373 //--------------------------------------------------------------------------------------
\r
5374 void CDXUTScrollBar::Cap() // Clips position at boundaries. Ensures it stays within legal range.
\r
5376 if( m_nPosition < m_nStart ||
\r
5377 m_nEnd - m_nStart <= m_nPageSize )
\r
5379 m_nPosition = m_nStart;
\r
5381 else if( m_nPosition + m_nPageSize > m_nEnd )
\r
5382 m_nPosition = m_nEnd - m_nPageSize;
\r
5385 //--------------------------------------------------------------------------------------
\r
5386 // CDXUTListBox class
\r
5387 //--------------------------------------------------------------------------------------
\r
5389 //--------------------------------------------------------------------------------------
\r
5390 CDXUTListBox::CDXUTListBox( CDXUTDialog* pDialog ) : m_ScrollBar( pDialog )
\r
5392 m_Type = DXUT_CONTROL_LISTBOX;
\r
5393 m_pDialog = pDialog;
\r
5402 m_nTextHeight = 0;
\r
5406 //--------------------------------------------------------------------------------------
\r
5407 CDXUTListBox::~CDXUTListBox()
\r
5413 //--------------------------------------------------------------------------------------
\r
5414 void CDXUTListBox::UpdateRects()
\r
5416 CDXUTControl::UpdateRects();
\r
5418 m_rcSelection = m_rcBoundingBox;
\r
5419 m_rcSelection.right -= m_nSBWidth;
\r
5420 InflateRect( &m_rcSelection, -m_nBorder, -m_nBorder );
\r
5421 m_rcText = m_rcSelection;
\r
5422 InflateRect( &m_rcText, -m_nMargin, 0 );
\r
5424 // Update the scrollbar's rects
\r
5425 m_ScrollBar.SetLocation( m_rcBoundingBox.right - m_nSBWidth, m_rcBoundingBox.top );
\r
5426 m_ScrollBar.SetSize( m_nSBWidth, m_height );
\r
5427 DXUTFontNode* pFontNode = m_pDialog->GetManager()->GetFontNode( m_Elements.GetAt( 0 )->iFont );
\r
5428 if( pFontNode && pFontNode->nHeight )
\r
5430 m_ScrollBar.SetPageSize( RectHeight( m_rcText ) / pFontNode->nHeight );
\r
5432 // The selected item may have been scrolled off the page.
\r
5433 // Ensure that it is in page again.
\r
5434 m_ScrollBar.ShowItem( m_nSelected );
\r
5439 //--------------------------------------------------------------------------------------
\r
5440 HRESULT CDXUTListBox::AddItem( const WCHAR* wszText, void* pData )
\r
5442 DXUTListBoxItem* pNewItem = new DXUTListBoxItem;
\r
5444 return E_OUTOFMEMORY;
\r
5446 wcscpy_s( pNewItem->strText, 256, wszText );
\r
5447 pNewItem->pData = pData;
\r
5448 SetRect( &pNewItem->rcActive, 0, 0, 0, 0 );
\r
5449 pNewItem->bSelected = false;
\r
5451 HRESULT hr = m_Items.Add( pNewItem );
\r
5452 if( FAILED( hr ) )
\r
5454 SAFE_DELETE( pNewItem );
\r
5458 m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
\r
5465 //--------------------------------------------------------------------------------------
\r
5466 HRESULT CDXUTListBox::InsertItem( int nIndex, const WCHAR* wszText, void* pData )
\r
5468 DXUTListBoxItem* pNewItem = new DXUTListBoxItem;
\r
5470 return E_OUTOFMEMORY;
\r
5472 wcscpy_s( pNewItem->strText, 256, wszText );
\r
5473 pNewItem->pData = pData;
\r
5474 SetRect( &pNewItem->rcActive, 0, 0, 0, 0 );
\r
5475 pNewItem->bSelected = false;
\r
5477 HRESULT hr = m_Items.Insert( nIndex, pNewItem );
\r
5478 if( SUCCEEDED( hr ) )
\r
5479 m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
\r
5481 SAFE_DELETE( pNewItem );
\r
5487 //--------------------------------------------------------------------------------------
\r
5488 void CDXUTListBox::RemoveItem( int nIndex )
\r
5490 if( nIndex < 0 || nIndex >= ( int )m_Items.GetSize() )
\r
5493 DXUTListBoxItem* pItem = m_Items.GetAt( nIndex );
\r
5496 m_Items.Remove( nIndex );
\r
5497 m_ScrollBar.SetTrackRange( 0, m_Items.GetSize() );
\r
5498 if( m_nSelected >= ( int )m_Items.GetSize() )
\r
5499 m_nSelected = m_Items.GetSize() - 1;
\r
5501 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5508 //--------------------------------------------------------------------------------------
\r
5509 void CDXUTListBox::RemoveAllItems()
\r
5511 for( int i = 0; i < m_Items.GetSize(); ++i )
\r
5513 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5517 m_Items.RemoveAll();
\r
5518 m_ScrollBar.SetTrackRange( 0, 1 );
\r
5522 //--------------------------------------------------------------------------------------
\r
5523 DXUTListBoxItem* CDXUTListBox::GetItem( int nIndex )
\r
5525 if( nIndex < 0 || nIndex >= ( int )m_Items.GetSize() )
\r
5528 return m_Items[nIndex];
\r
5532 //--------------------------------------------------------------------------------------
\r
5533 // For single-selection listbox, returns the index of the selected item.
\r
5534 // For multi-selection, returns the first selected item after the nPreviousSelected position.
\r
5535 // To search for the first selected item, the app passes -1 for nPreviousSelected. For
\r
5536 // subsequent searches, the app passes the returned index back to GetSelectedIndex as.
\r
5537 // nPreviousSelected.
\r
5538 // Returns -1 on error or if no item is selected.
\r
5539 int CDXUTListBox::GetSelectedIndex( int nPreviousSelected )
\r
5541 if( nPreviousSelected < -1 )
\r
5544 if( m_dwStyle & MULTISELECTION )
\r
5546 // Multiple selection enabled. Search for the next item with the selected flag.
\r
5547 for( int i = nPreviousSelected + 1; i < ( int )m_Items.GetSize(); ++i )
\r
5549 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5551 if( pItem->bSelected )
\r
5559 // Single selection
\r
5560 return m_nSelected;
\r
5565 //--------------------------------------------------------------------------------------
\r
5566 void CDXUTListBox::SelectItem( int nNewIndex )
\r
5568 // If no item exists, do nothing.
\r
5569 if( m_Items.GetSize() == 0 )
\r
5572 int nOldSelected = m_nSelected;
\r
5574 // Adjust m_nSelected
\r
5575 m_nSelected = nNewIndex;
\r
5577 // Perform capping
\r
5578 if( m_nSelected < 0 )
\r
5580 if( m_nSelected >= ( int )m_Items.GetSize() )
\r
5581 m_nSelected = m_Items.GetSize() - 1;
\r
5583 if( nOldSelected != m_nSelected )
\r
5585 if( m_dwStyle & MULTISELECTION )
\r
5587 m_Items[m_nSelected]->bSelected = true;
\r
5590 // Update selection start
\r
5591 m_nSelStart = m_nSelected;
\r
5593 // Adjust scroll bar
\r
5594 m_ScrollBar.ShowItem( m_nSelected );
\r
5597 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5601 //--------------------------------------------------------------------------------------
\r
5602 bool CDXUTListBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
5604 if( !m_bEnabled || !m_bVisible )
\r
5607 // Let the scroll bar have a chance to handle it first
\r
5608 if( m_ScrollBar.HandleKeyboard( uMsg, wParam, lParam ) )
\r
5623 // If no item exists, do nothing.
\r
5624 if( m_Items.GetSize() == 0 )
\r
5627 int nOldSelected = m_nSelected;
\r
5629 // Adjust m_nSelected
\r
5633 --m_nSelected; break;
\r
5635 ++m_nSelected; break;
\r
5637 m_nSelected += m_ScrollBar.GetPageSize() - 1; break;
\r
5639 m_nSelected -= m_ScrollBar.GetPageSize() - 1; break;
\r
5641 m_nSelected = 0; break;
\r
5643 m_nSelected = m_Items.GetSize() - 1; break;
\r
5646 // Perform capping
\r
5647 if( m_nSelected < 0 )
\r
5649 if( m_nSelected >= ( int )m_Items.GetSize() )
\r
5650 m_nSelected = m_Items.GetSize() - 1;
\r
5652 if( nOldSelected != m_nSelected )
\r
5654 if( m_dwStyle & MULTISELECTION )
\r
5656 // Multiple selection
\r
5658 // Clear all selection
\r
5659 for( int i = 0; i < ( int )m_Items.GetSize(); ++i )
\r
5661 DXUTListBoxItem* pItem = m_Items[i];
\r
5662 pItem->bSelected = false;
\r
5665 if( GetKeyState( VK_SHIFT ) < 0 )
\r
5667 // Select all items from m_nSelStart to
\r
5669 int nEnd = __max( m_nSelStart, m_nSelected );
\r
5671 for( int n = __min( m_nSelStart, m_nSelected ); n <= nEnd; ++n )
\r
5672 m_Items[n]->bSelected = true;
\r
5676 m_Items[m_nSelected]->bSelected = true;
\r
5678 // Update selection start
\r
5679 m_nSelStart = m_nSelected;
\r
5683 m_nSelStart = m_nSelected;
\r
5685 // Adjust scroll bar
\r
5687 m_ScrollBar.ShowItem( m_nSelected );
\r
5689 // Send notification
\r
5691 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5696 // Space is the hotkey for double-clicking an item.
\r
5699 m_pDialog->SendEvent( EVENT_LISTBOX_ITEM_DBLCLK, true, this );
\r
5709 //--------------------------------------------------------------------------------------
\r
5710 bool CDXUTListBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
5712 if( !m_bEnabled || !m_bVisible )
\r
5715 // First acquire focus
\r
5716 if( WM_LBUTTONDOWN == uMsg )
\r
5717 if( !m_bHasFocus )
\r
5718 m_pDialog->RequestFocus( this );
\r
5720 // Let the scroll bar handle it first.
\r
5721 if( m_ScrollBar.HandleMouse( uMsg, pt, wParam, lParam ) )
\r
5726 case WM_LBUTTONDOWN:
\r
5727 case WM_LBUTTONDBLCLK:
\r
5728 // Check for clicks in the text area
\r
5729 if( m_Items.GetSize() > 0 && PtInRect( &m_rcSelection, pt ) )
\r
5731 // Compute the index of the clicked item
\r
5734 if( m_nTextHeight )
\r
5735 nClicked = m_ScrollBar.GetTrackPos() + ( pt.y - m_rcText.top ) / m_nTextHeight;
\r
5739 // Only proceed if the click falls on top of an item.
\r
5741 if( nClicked >= m_ScrollBar.GetTrackPos() &&
\r
5742 nClicked < ( int )m_Items.GetSize() &&
\r
5743 nClicked < m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() )
\r
5745 SetCapture( DXUTGetHWND() );
\r
5748 // If this is a double click, fire off an event and exit
\r
5749 // since the first click would have taken care of the selection
\r
5751 if( uMsg == WM_LBUTTONDBLCLK )
\r
5753 m_pDialog->SendEvent( EVENT_LISTBOX_ITEM_DBLCLK, true, this );
\r
5757 m_nSelected = nClicked;
\r
5758 if( !( wParam & MK_SHIFT ) )
\r
5759 m_nSelStart = m_nSelected;
\r
5761 // If this is a multi-selection listbox, update per-item
\r
5762 // selection data.
\r
5764 if( m_dwStyle & MULTISELECTION )
\r
5766 // Determine behavior based on the state of Shift and Ctrl
\r
5768 DXUTListBoxItem* pSelItem = m_Items.GetAt( m_nSelected );
\r
5769 if( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) == MK_CONTROL )
\r
5771 // Control click. Reverse the selection of this item.
\r
5773 pSelItem->bSelected = !pSelItem->bSelected;
\r
5775 else if( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) == MK_SHIFT )
\r
5777 // Shift click. Set the selection for all items
\r
5778 // from last selected item to the current item.
\r
5779 // Clear everything else.
\r
5781 int nBegin = __min( m_nSelStart, m_nSelected );
\r
5782 int nEnd = __max( m_nSelStart, m_nSelected );
\r
5784 for( int i = 0; i < nBegin; ++i )
\r
5786 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5787 pItem->bSelected = false;
\r
5790 for( int i = nEnd + 1; i < ( int )m_Items.GetSize(); ++i )
\r
5792 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5793 pItem->bSelected = false;
\r
5796 for( int i = nBegin; i <= nEnd; ++i )
\r
5798 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5799 pItem->bSelected = true;
\r
5802 else if( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) == ( MK_SHIFT | MK_CONTROL ) )
\r
5804 // Control-Shift-click.
\r
5806 // The behavior is:
\r
5807 // Set all items from m_nSelStart to m_nSelected to
\r
5808 // the same state as m_nSelStart, not including m_nSelected.
\r
5809 // Set m_nSelected to selected.
\r
5811 int nBegin = __min( m_nSelStart, m_nSelected );
\r
5812 int nEnd = __max( m_nSelStart, m_nSelected );
\r
5814 // The two ends do not need to be set here.
\r
5816 bool bLastSelected = m_Items.GetAt( m_nSelStart )->bSelected;
\r
5817 for( int i = nBegin + 1; i < nEnd; ++i )
\r
5819 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5820 pItem->bSelected = bLastSelected;
\r
5823 pSelItem->bSelected = true;
\r
5825 // Restore m_nSelected to the previous value
\r
5826 // This matches the Windows behavior
\r
5828 m_nSelected = m_nSelStart;
\r
5832 // Simple click. Clear all items and select the clicked
\r
5836 for( int i = 0; i < ( int )m_Items.GetSize(); ++i )
\r
5838 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5839 pItem->bSelected = false;
\r
5842 pSelItem->bSelected = true;
\r
5844 } // End of multi-selection case
\r
5846 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5853 case WM_LBUTTONUP:
\r
5858 if( m_nSelected != -1 )
\r
5860 // Set all items between m_nSelStart and m_nSelected to
\r
5861 // the same state as m_nSelStart
\r
5862 int nEnd = __max( m_nSelStart, m_nSelected );
\r
5864 for( int n = __min( m_nSelStart, m_nSelected ) + 1; n < nEnd; ++n )
\r
5865 m_Items[n]->bSelected = m_Items[m_nSelStart]->bSelected;
\r
5866 m_Items[m_nSelected]->bSelected = m_Items[m_nSelStart]->bSelected;
\r
5868 // If m_nSelStart and m_nSelected are not the same,
\r
5869 // the user has dragged the mouse to make a selection.
\r
5870 // Notify the application of this.
\r
5871 if( m_nSelStart != m_nSelected )
\r
5872 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5874 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION_END, true, this );
\r
5879 case WM_MOUSEMOVE:
\r
5882 // Compute the index of the item below cursor
\r
5885 if( m_nTextHeight )
\r
5886 nItem = m_ScrollBar.GetTrackPos() + ( pt.y - m_rcText.top ) / m_nTextHeight;
\r
5890 // Only proceed if the cursor is on top of an item.
\r
5892 if( nItem >= ( int )m_ScrollBar.GetTrackPos() &&
\r
5893 nItem < ( int )m_Items.GetSize() &&
\r
5894 nItem < m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() )
\r
5896 m_nSelected = nItem;
\r
5897 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5899 else if( nItem < ( int )m_ScrollBar.GetTrackPos() )
\r
5901 // User drags the mouse above window top
\r
5902 m_ScrollBar.Scroll( -1 );
\r
5903 m_nSelected = m_ScrollBar.GetTrackPos();
\r
5904 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5906 else if( nItem >= m_ScrollBar.GetTrackPos() + m_ScrollBar.GetPageSize() )
\r
5908 // User drags the mouse below window bottom
\r
5909 m_ScrollBar.Scroll( 1 );
\r
5910 m_nSelected = __min( ( int )m_Items.GetSize(), m_ScrollBar.GetTrackPos() +
\r
5911 m_ScrollBar.GetPageSize() ) - 1;
\r
5912 m_pDialog->SendEvent( EVENT_LISTBOX_SELECTION, true, this );
\r
5917 case WM_MOUSEWHEEL:
\r
5920 SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &uLines, 0 );
\r
5921 int nScrollAmount = int( ( short )HIWORD( wParam ) ) / WHEEL_DELTA * uLines;
\r
5922 m_ScrollBar.Scroll( -nScrollAmount );
\r
5931 //--------------------------------------------------------------------------------------
\r
5932 bool CDXUTListBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
5934 if( WM_CAPTURECHANGED == uMsg )
\r
5936 // The application just lost mouse capture. We may not have gotten
\r
5937 // the WM_MOUSEUP message, so reset m_bDrag here.
\r
5938 if( ( HWND )lParam != DXUTGetHWND() )
\r
5946 //--------------------------------------------------------------------------------------
\r
5947 void CDXUTListBox::Render( float fElapsedTime )
\r
5949 if( m_bVisible == false )
\r
5952 CDXUTElement* pElement = m_Elements.GetAt( 0 );
\r
5953 pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
\r
5954 pElement->FontColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
\r
5956 CDXUTElement* pSelElement = m_Elements.GetAt( 1 );
\r
5957 pSelElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
\r
5958 pSelElement->FontColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
\r
5960 m_pDialog->DrawSprite( pElement, &m_rcBoundingBox, DXUT_FAR_BUTTON_DEPTH );
\r
5962 // Render the text
\r
5963 if( m_Items.GetSize() > 0 )
\r
5965 // Find out the height of a single line of text
\r
5966 RECT rc = m_rcText;
\r
5967 RECT rcSel = m_rcSelection;
\r
5968 rc.bottom = rc.top + m_pDialog->GetManager()->GetFontNode( pElement->iFont )->nHeight;
\r
5970 // Update the line height formation
\r
5971 m_nTextHeight = rc.bottom - rc.top;
\r
5973 static bool bSBInit;
\r
5976 // Update the page size of the scroll bar
\r
5977 if( m_nTextHeight )
\r
5978 m_ScrollBar.SetPageSize( RectHeight( m_rcText ) / m_nTextHeight );
\r
5980 m_ScrollBar.SetPageSize( RectHeight( m_rcText ) );
\r
5984 rc.right = m_rcText.right;
\r
5985 for( int i = m_ScrollBar.GetTrackPos(); i < ( int )m_Items.GetSize(); ++i )
\r
5987 if( rc.bottom > m_rcText.bottom )
\r
5990 DXUTListBoxItem* pItem = m_Items.GetAt( i );
\r
5992 // Determine if we need to render this item with the
\r
5993 // selected element.
\r
5994 bool bSelectedStyle = false;
\r
5996 if( !( m_dwStyle & MULTISELECTION ) && i == m_nSelected )
\r
5997 bSelectedStyle = true;
\r
5998 else if( m_dwStyle & MULTISELECTION )
\r
6001 ( ( i >= m_nSelected && i < m_nSelStart ) ||
\r
6002 ( i <= m_nSelected && i > m_nSelStart ) ) )
\r
6003 bSelectedStyle = m_Items[m_nSelStart]->bSelected;
\r
6004 else if( pItem->bSelected )
\r
6005 bSelectedStyle = true;
\r
6008 if( bSelectedStyle )
\r
6010 rcSel.top = rc.top; rcSel.bottom = rc.bottom;
\r
6011 m_pDialog->DrawSprite( pSelElement, &rcSel, DXUT_NEAR_BUTTON_DEPTH );
\r
6012 m_pDialog->DrawText( pItem->strText, pSelElement, &rc );
\r
6015 m_pDialog->DrawText( pItem->strText, pElement, &rc );
\r
6017 OffsetRect( &rc, 0, m_nTextHeight );
\r
6021 // Render the scroll bar
\r
6023 m_ScrollBar.Render( fElapsedTime );
\r
6027 // Static member initialization
\r
6028 HINSTANCE CUniBuffer::s_hDll = NULL;
\r
6029 HRESULT ( WINAPI*CUniBuffer::_ScriptApplyDigitSubstitution )( const SCRIPT_DIGITSUBSTITUTE*, SCRIPT_CONTROL*,
\r
6030 SCRIPT_STATE* ) = Dummy_ScriptApplyDigitSubstitution;
\r
6031 HRESULT ( WINAPI*CUniBuffer::_ScriptStringAnalyse )( HDC, const void*, int, int, int, DWORD, int, SCRIPT_CONTROL*,
\r
6032 SCRIPT_STATE*, const int*, SCRIPT_TABDEF*, const BYTE*,
\r
6033 SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringAnalyse;
\r
6034 HRESULT ( WINAPI*CUniBuffer::_ScriptStringCPtoX )( SCRIPT_STRING_ANALYSIS, int, BOOL, int* ) = Dummy_ScriptStringCPtoX;
\r
6035 HRESULT ( WINAPI*CUniBuffer::_ScriptStringXtoCP )( SCRIPT_STRING_ANALYSIS, int, int*, int* ) = Dummy_ScriptStringXtoCP;
\r
6036 HRESULT ( WINAPI*CUniBuffer::_ScriptStringFree )( SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringFree;
\r
6037 const SCRIPT_LOGATTR* ( WINAPI*CUniBuffer::_ScriptString_pLogAttr )( SCRIPT_STRING_ANALYSIS ) =
\r
6038 Dummy_ScriptString_pLogAttr;
\r
6039 const int* ( WINAPI*CUniBuffer::_ScriptString_pcOutChars )( SCRIPT_STRING_ANALYSIS ) =
\r
6040 Dummy_ScriptString_pcOutChars;
\r
6041 bool CDXUTEditBox::s_bHideCaret; // If true, we don't render the caret.
\r
6045 //--------------------------------------------------------------------------------------
\r
6046 // CDXUTEditBox class
\r
6047 //--------------------------------------------------------------------------------------
\r
6049 // When scrolling, EDITBOX_SCROLLEXTENT is reciprocal of the amount to scroll.
\r
6050 // If EDITBOX_SCROLLEXTENT = 4, then we scroll 1/4 of the control each time.
\r
6051 #define EDITBOX_SCROLLEXTENT 4
\r
6053 //--------------------------------------------------------------------------------------
\r
6054 CDXUTEditBox::CDXUTEditBox( CDXUTDialog* pDialog )
\r
6056 m_Type = DXUT_CONTROL_EDITBOX;
\r
6057 m_pDialog = pDialog;
\r
6059 m_nBorder = 5; // Default border width
\r
6060 m_nSpacing = 4; // Default spacing
\r
6062 m_bCaretOn = true;
\r
6063 m_dfBlink = GetCaretBlinkTime() * 0.001f;
\r
6064 m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime();
\r
6065 s_bHideCaret = false;
\r
6066 m_nFirstVisible = 0;
\r
6067 m_TextColor = D3DCOLOR_ARGB( 255, 16, 16, 16 );
\r
6068 m_SelTextColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
\r
6069 m_SelBkColor = D3DCOLOR_ARGB( 255, 40, 50, 92 );
\r
6070 m_CaretColor = D3DCOLOR_ARGB( 255, 0, 0, 0 );
\r
6071 m_nCaret = m_nSelStart = 0;
\r
6072 m_bInsertMode = true;
\r
6074 m_bMouseDrag = false;
\r
6078 //--------------------------------------------------------------------------------------
\r
6079 CDXUTEditBox::~CDXUTEditBox()
\r
6084 //--------------------------------------------------------------------------------------
\r
6085 // PlaceCaret: Set the caret to a character position, and adjust the scrolling if
\r
6087 //--------------------------------------------------------------------------------------
\r
6088 void CDXUTEditBox::PlaceCaret( int nCP )
\r
6090 assert( nCP >= 0 && nCP <= m_Buffer.GetTextSize() );
\r
6093 // Obtain the X offset of the character.
\r
6094 int nX1st, nX, nX2;
\r
6095 m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // 1st visible char
\r
6096 m_Buffer.CPtoX( nCP, FALSE, &nX ); // LEAD
\r
6097 // If nCP is the NULL terminator, get the leading edge instead of trailing.
\r
6098 if( nCP == m_Buffer.GetTextSize() )
\r
6101 m_Buffer.CPtoX( nCP, TRUE, &nX2 ); // TRAIL
\r
6103 // If the left edge of the char is smaller than the left edge of the 1st visible char,
\r
6104 // we need to scroll left until this char is visible.
\r
6107 // Simply make the first visible character the char at the new caret position.
\r
6108 m_nFirstVisible = nCP;
\r
6110 else // If the right of the character is bigger than the offset of the control's
\r
6111 // right edge, we need to scroll right to this character.
\r
6112 if( nX2 > nX1st + RectWidth( m_rcText ) )
\r
6114 // Compute the X of the new left-most pixel
\r
6115 int nXNewLeft = nX2 - RectWidth( m_rcText );
\r
6117 // Compute the char position of this character
\r
6118 int nCPNew1st, nNewTrail;
\r
6119 m_Buffer.XtoCP( nXNewLeft, &nCPNew1st, &nNewTrail );
\r
6121 // If this coordinate is not on a character border,
\r
6122 // start from the next character so that the caret
\r
6123 // position does not fall outside the text rectangle.
\r
6125 m_Buffer.CPtoX( nCPNew1st, FALSE, &nXNew1st );
\r
6126 if( nXNew1st < nXNewLeft )
\r
6129 m_nFirstVisible = nCPNew1st;
\r
6134 //--------------------------------------------------------------------------------------
\r
6135 void CDXUTEditBox::ClearText()
\r
6138 m_nFirstVisible = 0;
\r
6144 //--------------------------------------------------------------------------------------
\r
6145 void CDXUTEditBox::SetText( LPCWSTR wszText, bool bSelected )
\r
6147 assert( wszText != NULL );
\r
6149 m_Buffer.SetText( wszText );
\r
6150 m_nFirstVisible = 0;
\r
6151 // Move the caret to the end of the text
\r
6152 PlaceCaret( m_Buffer.GetTextSize() );
\r
6153 m_nSelStart = bSelected ? 0 : m_nCaret;
\r
6157 //--------------------------------------------------------------------------------------
\r
6158 HRESULT CDXUTEditBox::GetTextCopy( __out_ecount(bufferCount) LPWSTR strDest,
\r
6159 UINT bufferCount )
\r
6161 assert( strDest );
\r
6163 wcscpy_s( strDest, bufferCount, m_Buffer.GetBuffer() );
\r
6169 //--------------------------------------------------------------------------------------
\r
6170 void CDXUTEditBox::DeleteSelectionText()
\r
6172 int nFirst = __min( m_nCaret, m_nSelStart );
\r
6173 int nLast = __max( m_nCaret, m_nSelStart );
\r
6174 // Update caret and selection
\r
6175 PlaceCaret( nFirst );
\r
6176 m_nSelStart = m_nCaret;
\r
6177 // Remove the characters
\r
6178 for( int i = nFirst; i < nLast; ++i )
\r
6179 m_Buffer.RemoveChar( nFirst );
\r
6183 //--------------------------------------------------------------------------------------
\r
6184 void CDXUTEditBox::UpdateRects()
\r
6186 CDXUTControl::UpdateRects();
\r
6188 // Update the text rectangle
\r
6189 m_rcText = m_rcBoundingBox;
\r
6190 // First inflate by m_nBorder to compute render rects
\r
6191 InflateRect( &m_rcText, -m_nBorder, -m_nBorder );
\r
6193 // Update the render rectangles
\r
6194 m_rcRender[0] = m_rcText;
\r
6195 SetRect( &m_rcRender[1], m_rcBoundingBox.left, m_rcBoundingBox.top, m_rcText.left, m_rcText.top );
\r
6196 SetRect( &m_rcRender[2], m_rcText.left, m_rcBoundingBox.top, m_rcText.right, m_rcText.top );
\r
6197 SetRect( &m_rcRender[3], m_rcText.right, m_rcBoundingBox.top, m_rcBoundingBox.right, m_rcText.top );
\r
6198 SetRect( &m_rcRender[4], m_rcBoundingBox.left, m_rcText.top, m_rcText.left, m_rcText.bottom );
\r
6199 SetRect( &m_rcRender[5], m_rcText.right, m_rcText.top, m_rcBoundingBox.right, m_rcText.bottom );
\r
6200 SetRect( &m_rcRender[6], m_rcBoundingBox.left, m_rcText.bottom, m_rcText.left, m_rcBoundingBox.bottom );
\r
6201 SetRect( &m_rcRender[7], m_rcText.left, m_rcText.bottom, m_rcText.right, m_rcBoundingBox.bottom );
\r
6202 SetRect( &m_rcRender[8], m_rcText.right, m_rcText.bottom, m_rcBoundingBox.right, m_rcBoundingBox.bottom );
\r
6204 // Inflate further by m_nSpacing
\r
6205 InflateRect( &m_rcText, -m_nSpacing, -m_nSpacing );
\r
6209 void CDXUTEditBox::CopyToClipboard()
\r
6211 // Copy the selection text to the clipboard
\r
6212 if( m_nCaret != m_nSelStart && OpenClipboard( NULL ) )
\r
6216 HGLOBAL hBlock = GlobalAlloc( GMEM_MOVEABLE, sizeof( WCHAR ) * ( m_Buffer.GetTextSize() + 1 ) );
\r
6219 WCHAR* pwszText = ( WCHAR* )GlobalLock( hBlock );
\r
6222 int nFirst = __min( m_nCaret, m_nSelStart );
\r
6223 int nLast = __max( m_nCaret, m_nSelStart );
\r
6224 if( nLast - nFirst > 0 )
\r
6225 CopyMemory( pwszText, m_Buffer.GetBuffer() + nFirst, ( nLast - nFirst ) * sizeof( WCHAR ) );
\r
6226 pwszText[nLast - nFirst] = L'\0'; // Terminate it
\r
6227 GlobalUnlock( hBlock );
\r
6229 SetClipboardData( CF_UNICODETEXT, hBlock );
\r
6232 // We must not free the object until CloseClipboard is called.
\r
6234 GlobalFree( hBlock );
\r
6239 void CDXUTEditBox::PasteFromClipboard()
\r
6241 DeleteSelectionText();
\r
6243 if( OpenClipboard( NULL ) )
\r
6245 HANDLE handle = GetClipboardData( CF_UNICODETEXT );
\r
6248 // Convert the ANSI string to Unicode, then
\r
6249 // insert to our buffer.
\r
6250 WCHAR* pwszText = ( WCHAR* )GlobalLock( handle );
\r
6253 // Copy all characters up to null.
\r
6254 if( m_Buffer.InsertString( m_nCaret, pwszText ) )
\r
6255 PlaceCaret( m_nCaret + lstrlenW( pwszText ) );
\r
6256 m_nSelStart = m_nCaret;
\r
6257 GlobalUnlock( handle );
\r
6265 //--------------------------------------------------------------------------------------
\r
6266 bool CDXUTEditBox::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
6268 if( !m_bEnabled || !m_bVisible )
\r
6271 bool bHandled = false;
\r
6280 // We don't process Tab in case keyboard input is enabled and the user
\r
6281 // wishes to Tab to other controls.
\r
6286 if( GetKeyState( VK_SHIFT ) >= 0 )
\r
6287 // Shift is not down. Update selection
\r
6288 // start along with the caret.
\r
6289 m_nSelStart = m_nCaret;
\r
6290 ResetCaretBlink();
\r
6295 PlaceCaret( m_Buffer.GetTextSize() );
\r
6296 if( GetKeyState( VK_SHIFT ) >= 0 )
\r
6297 // Shift is not down. Update selection
\r
6298 // start along with the caret.
\r
6299 m_nSelStart = m_nCaret;
\r
6300 ResetCaretBlink();
\r
6305 if( GetKeyState( VK_CONTROL ) < 0 )
\r
6307 // Control Insert. Copy to clipboard
\r
6308 CopyToClipboard();
\r
6310 else if( GetKeyState( VK_SHIFT ) < 0 )
\r
6312 // Shift Insert. Paste from clipboard
\r
6313 PasteFromClipboard();
\r
6317 // Toggle caret insert mode
\r
6318 m_bInsertMode = !m_bInsertMode;
\r
6323 // Check if there is a text selection.
\r
6324 if( m_nCaret != m_nSelStart )
\r
6326 DeleteSelectionText();
\r
6327 m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
\r
6331 // Deleting one character
\r
6332 if( m_Buffer.RemoveChar( m_nCaret ) )
\r
6333 m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
\r
6335 ResetCaretBlink();
\r
6340 if( GetKeyState( VK_CONTROL ) < 0 )
\r
6342 // Control is down. Move the caret to a new item
\r
6343 // instead of a character.
\r
6344 m_Buffer.GetPriorItemPos( m_nCaret, &m_nCaret );
\r
6345 PlaceCaret( m_nCaret );
\r
6347 else if( m_nCaret > 0 )
\r
6348 PlaceCaret( m_nCaret - 1 );
\r
6349 if( GetKeyState( VK_SHIFT ) >= 0 )
\r
6350 // Shift is not down. Update selection
\r
6351 // start along with the caret.
\r
6352 m_nSelStart = m_nCaret;
\r
6353 ResetCaretBlink();
\r
6358 if( GetKeyState( VK_CONTROL ) < 0 )
\r
6360 // Control is down. Move the caret to a new item
\r
6361 // instead of a character.
\r
6362 m_Buffer.GetNextItemPos( m_nCaret, &m_nCaret );
\r
6363 PlaceCaret( m_nCaret );
\r
6365 else if( m_nCaret < m_Buffer.GetTextSize() )
\r
6366 PlaceCaret( m_nCaret + 1 );
\r
6367 if( GetKeyState( VK_SHIFT ) >= 0 )
\r
6368 // Shift is not down. Update selection
\r
6369 // start along with the caret.
\r
6370 m_nSelStart = m_nCaret;
\r
6371 ResetCaretBlink();
\r
6377 // Trap up and down arrows so that the dialog
\r
6378 // does not switch focus to another control.
\r
6383 bHandled = wParam != VK_ESCAPE; // Let the application handle Esc.
\r
6391 //--------------------------------------------------------------------------------------
\r
6392 bool CDXUTEditBox::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
\r
6394 if( !m_bEnabled || !m_bVisible )
\r
6399 case WM_LBUTTONDOWN:
\r
6400 case WM_LBUTTONDBLCLK:
\r
6402 if( !m_bHasFocus )
\r
6403 m_pDialog->RequestFocus( this );
\r
6405 if( !ContainsPoint( pt ) )
\r
6408 m_bMouseDrag = true;
\r
6409 SetCapture( DXUTGetHWND() );
\r
6410 // Determine the character corresponding to the coordinates.
\r
6411 int nCP, nTrail, nX1st;
\r
6412 m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // X offset of the 1st visible char
\r
6413 if( SUCCEEDED( m_Buffer.XtoCP( pt.x - m_rcText.left + nX1st, &nCP, &nTrail ) ) )
\r
6415 // Cap at the NULL character.
\r
6416 if( nTrail && nCP < m_Buffer.GetTextSize() )
\r
6417 PlaceCaret( nCP + 1 );
\r
6419 PlaceCaret( nCP );
\r
6420 m_nSelStart = m_nCaret;
\r
6421 ResetCaretBlink();
\r
6426 case WM_LBUTTONUP:
\r
6428 m_bMouseDrag = false;
\r
6431 case WM_MOUSEMOVE:
\r
6432 if( m_bMouseDrag )
\r
6434 // Determine the character corresponding to the coordinates.
\r
6435 int nCP, nTrail, nX1st;
\r
6436 m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nX1st ); // X offset of the 1st visible char
\r
6437 if( SUCCEEDED( m_Buffer.XtoCP( pt.x - m_rcText.left + nX1st, &nCP, &nTrail ) ) )
\r
6439 // Cap at the NULL character.
\r
6440 if( nTrail && nCP < m_Buffer.GetTextSize() )
\r
6441 PlaceCaret( nCP + 1 );
\r
6443 PlaceCaret( nCP );
\r
6453 //--------------------------------------------------------------------------------------
\r
6454 void CDXUTEditBox::OnFocusIn()
\r
6456 CDXUTControl::OnFocusIn();
\r
6458 ResetCaretBlink();
\r
6462 //--------------------------------------------------------------------------------------
\r
6463 bool CDXUTEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
\r
6465 if( !m_bEnabled || !m_bVisible )
\r
6470 // Make sure that while editing, the keyup and keydown messages associated with
\r
6471 // WM_CHAR messages don't go to any non-focused controls or cameras
\r
6478 switch( ( WCHAR )wParam )
\r
6483 // If there's a selection, treat this
\r
6484 // like a delete key.
\r
6485 if( m_nCaret != m_nSelStart )
\r
6487 DeleteSelectionText();
\r
6488 m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
\r
6490 else if( m_nCaret > 0 )
\r
6492 // Move the caret, then delete the char.
\r
6493 PlaceCaret( m_nCaret - 1 );
\r
6494 m_nSelStart = m_nCaret;
\r
6495 m_Buffer.RemoveChar( m_nCaret );
\r
6496 m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
\r
6498 ResetCaretBlink();
\r
6502 case 24: // Ctrl-X Cut
\r
6503 case VK_CANCEL: // Ctrl-C Copy
\r
6505 CopyToClipboard();
\r
6507 // If the key is Ctrl-X, delete the selection too.
\r
6508 if( ( WCHAR )wParam == 24 )
\r
6510 DeleteSelectionText();
\r
6511 m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
\r
6520 PasteFromClipboard();
\r
6521 m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
\r
6525 // Ctrl-A Select All
\r
6527 if( m_nSelStart == m_nCaret )
\r
6530 PlaceCaret( m_Buffer.GetTextSize() );
\r
6535 // Invoke the callback when the user presses Enter.
\r
6536 m_pDialog->SendEvent( EVENT_EDITBOX_STRING, true, this );
\r
6539 // Junk characters we don't want in the string
\r
6540 case 26: // Ctrl Z
\r
6542 case 14: // Ctrl N
\r
6543 case 19: // Ctrl S
\r
6547 case 10: // Ctrl J
\r
6548 case 11: // Ctrl K
\r
6549 case 12: // Ctrl L
\r
6550 case 17: // Ctrl Q
\r
6551 case 23: // Ctrl W
\r
6553 case 18: // Ctrl R
\r
6554 case 20: // Ctrl T
\r
6555 case 25: // Ctrl Y
\r
6556 case 21: // Ctrl U
\r
6558 case 15: // Ctrl O
\r
6559 case 16: // Ctrl P
\r
6560 case 27: // Ctrl [
\r
6561 case 29: // Ctrl ]
\r
6562 case 28: // Ctrl \
\r
6567 // If there's a selection and the user
\r
6568 // starts to type, the selection should
\r
6570 if( m_nCaret != m_nSelStart )
\r
6571 DeleteSelectionText();
\r
6573 // If we are in overwrite mode and there is already
\r
6574 // a char at the caret's position, simply replace it.
\r
6575 // Otherwise, we insert the char as normal.
\r
6576 if( !m_bInsertMode && m_nCaret < m_Buffer.GetTextSize() )
\r
6578 m_Buffer[m_nCaret] = ( WCHAR )wParam;
\r
6579 PlaceCaret( m_nCaret + 1 );
\r
6580 m_nSelStart = m_nCaret;
\r
6584 // Insert the char
\r
6585 if( m_Buffer.InsertChar( m_nCaret, ( WCHAR )wParam ) )
\r
6587 PlaceCaret( m_nCaret + 1 );
\r
6588 m_nSelStart = m_nCaret;
\r
6591 ResetCaretBlink();
\r
6592 m_pDialog->SendEvent( EVENT_EDITBOX_CHANGE, true, this );
\r
6602 //--------------------------------------------------------------------------------------
\r
6603 void CDXUTEditBox::Render( float fElapsedTime )
\r
6605 if( m_bVisible == false )
\r
6609 int nSelStartX = 0, nCaretX = 0; // Left and right X cordinates of the selection region
\r
6611 CDXUTElement* pElement = GetElement( 0 );
\r
6614 m_Buffer.SetFontNode( m_pDialog->GetFont( pElement->iFont ) );
\r
6615 PlaceCaret( m_nCaret ); // Call PlaceCaret now that we have the font info (node),
\r
6616 // so that scrolling can be handled.
\r
6619 // Render the control graphics
\r
6620 for( int e = 0; e < 9; ++e )
\r
6622 pElement = m_Elements.GetAt( e );
\r
6623 pElement->TextureColor.Blend( DXUT_STATE_NORMAL, fElapsedTime );
\r
6625 m_pDialog->DrawSprite( pElement, &m_rcRender[e], DXUT_FAR_BUTTON_DEPTH );
\r
6629 // Compute the X coordinates of the first visible character.
\r
6632 m_Buffer.CPtoX( m_nFirstVisible, FALSE, &nXFirst );
\r
6635 // Compute the X coordinates of the selection rectangle
\r
6637 hr = m_Buffer.CPtoX( m_nCaret, FALSE, &nCaretX );
\r
6638 if( m_nCaret != m_nSelStart )
\r
6639 hr = m_Buffer.CPtoX( m_nSelStart, FALSE, &nSelStartX );
\r
6641 nSelStartX = nCaretX;
\r
6644 // Render the selection rectangle
\r
6646 RECT rcSelection; // Make this available for rendering selected text
\r
6647 if( m_nCaret != m_nSelStart )
\r
6649 int nSelLeftX = nCaretX, nSelRightX = nSelStartX;
\r
6650 // Swap if left is bigger than right
\r
6651 if( nSelLeftX > nSelRightX )
\r
6653 int nTemp = nSelLeftX; nSelLeftX = nSelRightX; nSelRightX = nTemp;
\r
6656 SetRect( &rcSelection, nSelLeftX, m_rcText.top, nSelRightX, m_rcText.bottom );
\r
6657 OffsetRect( &rcSelection, m_rcText.left - nXFirst, 0 );
\r
6658 IntersectRect( &rcSelection, &m_rcText, &rcSelection );
\r
6660 IDirect3DDevice9* pd3dDevice = m_pDialog->GetManager()->GetD3D9Device();
\r
6662 pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
\r
6663 m_pDialog->DrawRect( &rcSelection, m_SelBkColor );
\r
6665 pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
\r
6669 // Render the text
\r
6671 // Element 0 for text
\r
6672 m_Elements.GetAt( 0 )->FontColor.Current = m_TextColor;
\r
6673 m_pDialog->DrawText( m_Buffer.GetBuffer() + m_nFirstVisible, m_Elements.GetAt( 0 ), &m_rcText );
\r
6675 // Render the selected text
\r
6676 if( m_nCaret != m_nSelStart )
\r
6678 int nFirstToRender = __max( m_nFirstVisible, __min( m_nSelStart, m_nCaret ) );
\r
6679 int nNumChatToRender = __max( m_nSelStart, m_nCaret ) - nFirstToRender;
\r
6680 m_Elements.GetAt( 0 )->FontColor.Current = m_SelTextColor;
\r
6681 m_pDialog->DrawText( m_Buffer.GetBuffer() + nFirstToRender,
\r
6682 m_Elements.GetAt( 0 ), &rcSelection, false, nNumChatToRender );
\r
6686 // Blink the caret
\r
6688 if( DXUTGetGlobalTimer()->GetAbsoluteTime() - m_dfLastBlink >= m_dfBlink )
\r
6690 m_bCaretOn = !m_bCaretOn;
\r
6691 m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime();
\r
6695 // Render the caret if this control has the focus
\r
6697 if( m_bHasFocus && m_bCaretOn && !s_bHideCaret )
\r
6699 // Start the rectangle with insert mode caret
\r
6702 m_rcText.left - nXFirst + nCaretX - 1, m_rcText.top,
\r
6703 m_rcText.left - nXFirst + nCaretX + 1, m_rcText.bottom
\r
6706 // If we are in overwrite mode, adjust the caret rectangle
\r
6707 // to fill the entire character.
\r
6708 if( !m_bInsertMode )
\r
6710 // Obtain the right edge X coord of the current character
\r
6712 m_Buffer.CPtoX( m_nCaret, TRUE, &nRightEdgeX );
\r
6713 rcCaret.right = m_rcText.left - nXFirst + nRightEdgeX;
\r
6716 m_pDialog->DrawRect( &rcCaret, m_CaretColor );
\r
6721 #define IN_FLOAT_CHARSET( c ) \
\r
6722 ( (c) == L'-' || (c) == L'.' || ( (c) >= L'0' && (c) <= L'9' ) )
\r
6724 void CDXUTEditBox::ParseFloatArray( float* pNumbers, int nCount )
\r
6726 int nWritten = 0; // Number of floats written
\r
6727 const WCHAR* pToken, *pEnd;
\r
6728 WCHAR wszToken[60];
\r
6730 pToken = m_Buffer.GetBuffer();
\r
6731 while( nWritten < nCount && *pToken != L'\0' )
\r
6733 // Skip leading spaces
\r
6734 while( *pToken == L' ' )
\r
6737 if( *pToken == L'\0' )
\r
6740 // Locate the end of number
\r
6742 while( IN_FLOAT_CHARSET( *pEnd ) )
\r
6745 // Copy the token to our buffer
\r
6746 int nTokenLen = __min( sizeof( wszToken ) / sizeof( wszToken[0] ) - 1, int( pEnd - pToken ) );
\r
6747 wcscpy_s( wszToken, nTokenLen, pToken );
\r
6748 *pNumbers = ( float )wcstod( wszToken, NULL );
\r
6756 void CDXUTEditBox::SetTextFloatArray( const float* pNumbers, int nCount )
\r
6758 WCHAR wszBuffer[512] =
\r
6764 if( pNumbers == NULL )
\r
6767 for( int i = 0; i < nCount; ++i )
\r
6769 swprintf_s( wszTmp, 64, L"%.4f ", pNumbers[i] );
\r
6770 wcscat_s( wszBuffer, 512, wszTmp );
\r
6773 // Don't want the last space
\r
6774 if( nCount > 0 && wcslen( wszBuffer ) > 0 )
\r
6775 wszBuffer[wcslen( wszBuffer ) - 1] = 0;
\r
6777 SetText( wszBuffer );
\r
6783 //--------------------------------------------------------------------------------------
\r
6784 void CUniBuffer::Initialize()
\r
6786 if( s_hDll ) // Only need to do once
\r
6789 s_hDll = LoadLibrary( UNISCRIBE_DLLNAME );
\r
6793 GETPROCADDRESS( s_hDll, ScriptApplyDigitSubstitution, Temp );
\r
6794 GETPROCADDRESS( s_hDll, ScriptStringAnalyse, Temp );
\r
6795 GETPROCADDRESS( s_hDll, ScriptStringCPtoX, Temp );
\r
6796 GETPROCADDRESS( s_hDll, ScriptStringXtoCP, Temp );
\r
6797 GETPROCADDRESS( s_hDll, ScriptStringFree, Temp );
\r
6798 GETPROCADDRESS( s_hDll, ScriptString_pLogAttr, Temp );
\r
6799 GETPROCADDRESS( s_hDll, ScriptString_pcOutChars, Temp );
\r
6804 //--------------------------------------------------------------------------------------
\r
6805 void CUniBuffer::Uninitialize()
\r
6809 PLACEHOLDERPROC( ScriptApplyDigitSubstitution );
\r
6810 PLACEHOLDERPROC( ScriptStringAnalyse );
\r
6811 PLACEHOLDERPROC( ScriptStringCPtoX );
\r
6812 PLACEHOLDERPROC( ScriptStringXtoCP );
\r
6813 PLACEHOLDERPROC( ScriptStringFree );
\r
6814 PLACEHOLDERPROC( ScriptString_pLogAttr );
\r
6815 PLACEHOLDERPROC( ScriptString_pcOutChars );
\r
6817 FreeLibrary( s_hDll );
\r
6823 //--------------------------------------------------------------------------------------
\r
6824 bool CUniBuffer::SetBufferSize( int nNewSize )
\r
6826 // If the current size is already the maximum allowed,
\r
6827 // we can't possibly allocate more.
\r
6828 if( m_nBufferSize == DXUT_MAX_EDITBOXLENGTH )
\r
6831 int nAllocateSize = ( nNewSize == -1 || nNewSize < m_nBufferSize * 2 ) ? ( m_nBufferSize ? m_nBufferSize *
\r
6832 2 : 256 ) : nNewSize * 2;
\r
6834 // Cap the buffer size at the maximum allowed.
\r
6835 if( nAllocateSize > DXUT_MAX_EDITBOXLENGTH )
\r
6836 nAllocateSize = DXUT_MAX_EDITBOXLENGTH;
\r
6838 WCHAR* pTempBuffer = new WCHAR[nAllocateSize];
\r
6839 if( !pTempBuffer )
\r
6842 ZeroMemory( pTempBuffer, sizeof( WCHAR ) * nAllocateSize );
\r
6844 if( m_pwszBuffer )
\r
6846 CopyMemory( pTempBuffer, m_pwszBuffer, m_nBufferSize * sizeof( WCHAR ) );
\r
6847 delete[] m_pwszBuffer;
\r
6850 m_pwszBuffer = pTempBuffer;
\r
6851 m_nBufferSize = nAllocateSize;
\r
6856 //--------------------------------------------------------------------------------------
\r
6857 // Uniscribe -- Analyse() analyses the string in the buffer
\r
6858 //--------------------------------------------------------------------------------------
\r
6859 HRESULT CUniBuffer::Analyse()
\r
6862 _ScriptStringFree( &m_Analysis );
\r
6864 SCRIPT_CONTROL ScriptControl; // For uniscribe
\r
6865 SCRIPT_STATE ScriptState; // For uniscribe
\r
6866 ZeroMemory( &ScriptControl, sizeof( ScriptControl ) );
\r
6867 ZeroMemory( &ScriptState, sizeof( ScriptState ) );
\r
6868 _ScriptApplyDigitSubstitution( NULL, &ScriptControl, &ScriptState );
\r
6870 if( !m_pFontNode )
\r
6874 ( m_pFontNode->pFont9 ? m_pFontNode->pFont9->GetDC() : NULL );
\r
6875 HRESULT hr = _ScriptStringAnalyse( hDC,
\r
6877 lstrlenW( m_pwszBuffer ) + 1, // NULL is also analyzed.
\r
6878 lstrlenW( m_pwszBuffer ) * 3 / 2 + 16,
\r
6880 SSA_BREAK | SSA_GLYPHS | SSA_FALLBACK | SSA_LINK,
\r
6888 if( SUCCEEDED( hr ) )
\r
6889 m_bAnalyseRequired = false; // Analysis is up-to-date
\r
6894 //--------------------------------------------------------------------------------------
\r
6895 CUniBuffer::CUniBuffer( int nInitialSize )
\r
6897 CUniBuffer::Initialize(); // ensure static vars are properly init'ed first
\r
6899 m_nBufferSize = 0;
\r
6900 m_pwszBuffer = NULL;
\r
6901 m_bAnalyseRequired = true;
\r
6902 m_Analysis = NULL;
\r
6903 m_pFontNode = NULL;
\r
6905 if( nInitialSize > 0 )
\r
6906 SetBufferSize( nInitialSize );
\r
6910 //--------------------------------------------------------------------------------------
\r
6911 CUniBuffer::~CUniBuffer()
\r
6913 delete[] m_pwszBuffer;
\r
6915 _ScriptStringFree( &m_Analysis );
\r
6919 //--------------------------------------------------------------------------------------
\r
6920 WCHAR& CUniBuffer::operator[]( int n ) // No param checking
\r
6922 // This version of operator[] is called only
\r
6923 // if we are asking for write access, so
\r
6924 // re-analysis is required.
\r
6925 m_bAnalyseRequired = true;
\r
6926 return m_pwszBuffer[n];
\r
6930 //--------------------------------------------------------------------------------------
\r
6931 void CUniBuffer::Clear()
\r
6933 *m_pwszBuffer = L'\0';
\r
6934 m_bAnalyseRequired = true;
\r
6938 //--------------------------------------------------------------------------------------
\r
6939 // Inserts the char at specified index.
\r
6940 // If nIndex == -1, insert to the end.
\r
6941 //--------------------------------------------------------------------------------------
\r
6942 bool CUniBuffer::InsertChar( int nIndex, WCHAR wChar )
\r
6944 assert( nIndex >= 0 );
\r
6946 if( nIndex < 0 || nIndex > lstrlenW( m_pwszBuffer ) )
\r
6947 return false; // invalid index
\r
6949 // Check for maximum length allowed
\r
6950 if( GetTextSize() + 1 >= DXUT_MAX_EDITBOXLENGTH )
\r
6953 if( lstrlenW( m_pwszBuffer ) + 1 >= m_nBufferSize )
\r
6955 if( !SetBufferSize( -1 ) )
\r
6956 return false; // out of memory
\r
6959 assert( m_nBufferSize >= 2 );
\r
6961 // Shift the characters after the index, start by copying the null terminator
\r
6962 WCHAR* dest = m_pwszBuffer + lstrlenW( m_pwszBuffer ) + 1;
\r
6963 WCHAR* stop = m_pwszBuffer + nIndex;
\r
6964 WCHAR* src = dest - 1;
\r
6966 while( dest > stop )
\r
6971 // Set new character
\r
6972 m_pwszBuffer[ nIndex ] = wChar;
\r
6973 m_bAnalyseRequired = true;
\r
6979 //--------------------------------------------------------------------------------------
\r
6980 // Removes the char at specified index.
\r
6981 // If nIndex == -1, remove the last char.
\r
6982 //--------------------------------------------------------------------------------------
\r
6983 bool CUniBuffer::RemoveChar( int nIndex )
\r
6985 if( !lstrlenW( m_pwszBuffer ) || nIndex < 0 || nIndex >= lstrlenW( m_pwszBuffer ) )
\r
6986 return false; // Invalid index
\r
6988 MoveMemory( m_pwszBuffer + nIndex, m_pwszBuffer + nIndex + 1, sizeof( WCHAR ) *
\r
6989 ( lstrlenW( m_pwszBuffer ) - nIndex ) );
\r
6990 m_bAnalyseRequired = true;
\r
6995 //--------------------------------------------------------------------------------------
\r
6996 // Inserts the first nCount characters of the string pStr at specified index.
\r
6997 // If nCount == -1, the entire string is inserted.
\r
6998 // If nIndex == -1, insert to the end.
\r
6999 //--------------------------------------------------------------------------------------
\r
7000 bool CUniBuffer::InsertString( int nIndex, const WCHAR* pStr, int nCount )
\r
7002 assert( nIndex >= 0 );
\r
7006 if( nIndex > lstrlenW( m_pwszBuffer ) )
\r
7007 return false; // invalid index
\r
7009 if( -1 == nCount )
\r
7010 nCount = lstrlenW( pStr );
\r
7012 // Check for maximum length allowed
\r
7013 if( GetTextSize() + nCount >= DXUT_MAX_EDITBOXLENGTH )
\r
7016 if( lstrlenW( m_pwszBuffer ) + nCount >= m_nBufferSize )
\r
7018 if( !SetBufferSize( lstrlenW( m_pwszBuffer ) + nCount + 1 ) )
\r
7019 return false; // out of memory
\r
7022 MoveMemory( m_pwszBuffer + nIndex + nCount, m_pwszBuffer + nIndex, sizeof( WCHAR ) *
\r
7023 ( lstrlenW( m_pwszBuffer ) - nIndex + 1 ) );
\r
7024 CopyMemory( m_pwszBuffer + nIndex, pStr, nCount * sizeof( WCHAR ) );
\r
7025 m_bAnalyseRequired = true;
\r
7031 //--------------------------------------------------------------------------------------
\r
7032 bool CUniBuffer::SetText( LPCWSTR wszText )
\r
7034 assert( wszText != NULL );
\r
7036 int nRequired = int( wcslen( wszText ) + 1 );
\r
7038 // Check for maximum length allowed
\r
7039 if( nRequired >= DXUT_MAX_EDITBOXLENGTH )
\r
7042 while( GetBufferSize() < nRequired )
\r
7043 if( !SetBufferSize( -1 ) )
\r
7045 // Check again in case out of memory occurred inside while loop.
\r
7046 if( GetBufferSize() >= nRequired )
\r
7048 wcscpy_s( m_pwszBuffer, GetBufferSize(), wszText );
\r
7049 m_bAnalyseRequired = true;
\r
7057 //--------------------------------------------------------------------------------------
\r
7058 HRESULT CUniBuffer::CPtoX( int nCP, BOOL bTrail, int* pX )
\r
7061 *pX = 0; // Default
\r
7063 HRESULT hr = S_OK;
\r
7064 if( m_bAnalyseRequired )
\r
7067 if( SUCCEEDED( hr ) )
\r
7068 hr = _ScriptStringCPtoX( m_Analysis, nCP, bTrail, pX );
\r
7074 //--------------------------------------------------------------------------------------
\r
7075 HRESULT CUniBuffer::XtoCP( int nX, int* pCP, int* pnTrail )
\r
7077 assert( pCP && pnTrail );
\r
7078 *pCP = 0; *pnTrail = FALSE; // Default
\r
7080 HRESULT hr = S_OK;
\r
7081 if( m_bAnalyseRequired )
\r
7084 if( SUCCEEDED( hr ) )
\r
7085 hr = _ScriptStringXtoCP( m_Analysis, nX, pCP, pnTrail );
\r
7087 // If the coordinate falls outside the text region, we
\r
7088 // can get character positions that don't exist. We must
\r
7089 // filter them here and convert them to those that do exist.
\r
7090 if( *pCP == -1 && *pnTrail == TRUE )
\r
7092 *pCP = 0; *pnTrail = FALSE;
\r
7094 else if( *pCP > lstrlenW( m_pwszBuffer ) && *pnTrail == FALSE )
\r
7096 *pCP = lstrlenW( m_pwszBuffer ); *pnTrail = TRUE;
\r
7103 //--------------------------------------------------------------------------------------
\r
7104 void CUniBuffer::GetPriorItemPos( int nCP, int* pPrior )
\r
7106 *pPrior = nCP; // Default is the char itself
\r
7108 if( m_bAnalyseRequired )
\r
7109 if( FAILED( Analyse() ) )
\r
7112 const SCRIPT_LOGATTR* pLogAttr = _ScriptString_pLogAttr( m_Analysis );
\r
7116 if( !_ScriptString_pcOutChars( m_Analysis ) )
\r
7118 int nInitial = *_ScriptString_pcOutChars( m_Analysis );
\r
7119 if( nCP - 1 < nInitial )
\r
7120 nInitial = nCP - 1;
\r
7121 for( int i = nInitial; i > 0; --i )
\r
7122 if( pLogAttr[i].fWordStop || // Either the fWordStop flag is set
\r
7123 ( !pLogAttr[i].fWhiteSpace && // Or the previous char is whitespace but this isn't.
\r
7124 pLogAttr[i - 1].fWhiteSpace ) )
\r
7129 // We have reached index 0. 0 is always a break point, so simply return it.
\r
7134 //--------------------------------------------------------------------------------------
\r
7135 void CUniBuffer::GetNextItemPos( int nCP, int* pPrior )
\r
7137 *pPrior = nCP; // Default is the char itself
\r
7139 HRESULT hr = S_OK;
\r
7140 if( m_bAnalyseRequired )
\r
7142 if( FAILED( hr ) )
\r
7145 const SCRIPT_LOGATTR* pLogAttr = _ScriptString_pLogAttr( m_Analysis );
\r
7149 if( !_ScriptString_pcOutChars( m_Analysis ) )
\r
7151 int nInitial = *_ScriptString_pcOutChars( m_Analysis );
\r
7152 if( nCP + 1 < nInitial )
\r
7153 nInitial = nCP + 1;
\r
7156 int limit = *_ScriptString_pcOutChars( m_Analysis );
\r
7157 while( limit > 0 && i < limit - 1 )
\r
7159 if( pLogAttr[i].fWordStop ) // Either the fWordStop flag is set
\r
7164 else if( pLogAttr[i].fWhiteSpace && // Or this whitespace but the next char isn't.
\r
7165 !pLogAttr[i + 1].fWhiteSpace )
\r
7167 *pPrior = i + 1; // The next char is a word stop
\r
7172 limit = *_ScriptString_pcOutChars( m_Analysis );
\r
7174 // We have reached the end. It's always a word stop, so simply return it.
\r
7175 *pPrior = *_ScriptString_pcOutChars( m_Analysis ) - 1;
\r
7179 //--------------------------------------------------------------------------------------
\r
7180 void CDXUTEditBox::ResetCaretBlink()
\r
7182 m_bCaretOn = true;
\r
7183 m_dfLastBlink = DXUTGetGlobalTimer()->GetAbsoluteTime();
\r
7187 //--------------------------------------------------------------------------------------
\r
7188 void DXUTBlendColor::Init( D3DCOLOR defaultColor, D3DCOLOR disabledColor, D3DCOLOR hiddenColor )
\r
7190 for( int i = 0; i < MAX_CONTROL_STATES; i++ )
\r
7192 States[ i ] = defaultColor;
\r
7195 States[ DXUT_STATE_DISABLED ] = disabledColor;
\r
7196 States[ DXUT_STATE_HIDDEN ] = hiddenColor;
\r
7197 Current = hiddenColor;
\r
7201 //--------------------------------------------------------------------------------------
\r
7202 void DXUTBlendColor::Blend( UINT iState, float fElapsedTime, float fRate )
\r
7204 D3DXCOLOR destColor = States[ iState ];
\r
7205 D3DXColorLerp( &Current, &Current, &destColor, 1.0f - powf( fRate, 30 * fElapsedTime ) );
\r
7210 //--------------------------------------------------------------------------------------
\r
7211 void CDXUTElement::SetTexture( UINT iTexture, RECT* prcTexture, D3DCOLOR defaultTextureColor )
\r
7213 this->iTexture = iTexture;
\r
7216 rcTexture = *prcTexture;
\r
7218 SetRectEmpty( &rcTexture );
\r
7220 TextureColor.Init( defaultTextureColor );
\r
7224 //--------------------------------------------------------------------------------------
\r
7225 void CDXUTElement::SetFont( UINT iFont, D3DCOLOR defaultFontColor, DWORD dwTextFormat )
\r
7227 this->iFont = iFont;
\r
7228 this->dwTextFormat = dwTextFormat;
\r
7230 FontColor.Init( defaultFontColor );
\r
7234 //--------------------------------------------------------------------------------------
\r
7235 void CDXUTElement::Refresh()
\r
7237 TextureColor.Current = TextureColor.States[ DXUT_STATE_HIDDEN ];
\r
7238 FontColor.Current = FontColor.States[ DXUT_STATE_HIDDEN ];
\r