mirror of
https://github.com/dashr9230/SA-MP.git
synced 2025-01-04 00:23:22 +08:00
539 lines
15 KiB
C++
539 lines
15 KiB
C++
//--------------------------------------------------------------------------------------
|
|
// File: DXUTgui.cpp
|
|
//
|
|
// Desc:
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//--------------------------------------------------------------------------------------
|
|
#include "dxstdafx.h"
|
|
#include "DXUTgui.h"
|
|
#include "DXUTsettingsDlg.h"
|
|
#undef min // use __min instead
|
|
#undef max // use __max instead
|
|
|
|
double CDXUTDialog::s_fTimeRefresh = 0.0f;
|
|
CDXUTControl* CDXUTDialog::s_pControlFocus = NULL; // The control which has focus
|
|
CDXUTControl* CDXUTDialog::s_pControlPressed = NULL; // The control currently pressed
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
// CDXUTDialog class
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTDialog::CDXUTDialog()
|
|
{
|
|
m_x = 0;
|
|
m_y = 0;
|
|
m_width = 0;
|
|
m_height = 0;
|
|
|
|
m_pManager = NULL;
|
|
m_bVisible = true;
|
|
m_bCaption = false;
|
|
m_bMinimized = false;
|
|
m_wszCaption[0] = L'\0';
|
|
m_nCaptionHeight = 18;
|
|
|
|
m_colorTopLeft = 0;
|
|
m_colorTopRight = 0;
|
|
m_colorBottomLeft = 0;
|
|
m_colorBottomRight = 0;
|
|
|
|
m_pCallbackEvent = NULL;
|
|
m_pCallbackEventUserContext = NULL;
|
|
|
|
m_fTimeLastRefresh = 0;
|
|
|
|
m_pControlMouseOver = NULL;
|
|
|
|
m_pNextDialog = this;
|
|
m_pPrevDialog = this;
|
|
|
|
m_nDefaultControlID = 0xffff;
|
|
m_bNonUserEvents = false;
|
|
m_bKeyboardInput = false;
|
|
m_bMouseInput = true;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTDialog::~CDXUTDialog()
|
|
{
|
|
int i=0;
|
|
|
|
RemoveAllControls();
|
|
|
|
m_Fonts.RemoveAll();
|
|
m_Textures.RemoveAll();
|
|
|
|
for( i=0; i < m_DefaultElements.GetSize(); i++ )
|
|
{
|
|
DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
|
|
SAFE_DELETE( pElementHolder );
|
|
}
|
|
|
|
m_DefaultElements.RemoveAll();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTDialog::SetCallback( PCALLBACKDXUTGUIEVENT pCallback, void* pUserContext )
|
|
{
|
|
// If this assert triggers, you need to call CDXUTDialog::Init() first. This change
|
|
// was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
|
|
// creation and interfacing with CDXUTDialogResourceManager is now the responsibility
|
|
// of the application if it wishes to use DXUT's GUI.
|
|
assert( m_pManager != NULL && "To fix call CDXUTDialog::Init() first. See comments for details." );
|
|
|
|
m_pCallbackEvent = pCallback;
|
|
m_pCallbackEventUserContext = pUserContext;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTDialog::RemoveAllControls()
|
|
{
|
|
if( s_pControlFocus && s_pControlFocus->m_pDialog == this )
|
|
s_pControlFocus = NULL;
|
|
if( s_pControlPressed && s_pControlPressed->m_pDialog == this )
|
|
s_pControlPressed = NULL;
|
|
m_pControlMouseOver = NULL;
|
|
|
|
for( int i=0; i < m_Controls.GetSize(); i++ )
|
|
{
|
|
CDXUTControl* pControl = m_Controls.GetAt( i );
|
|
SAFE_DELETE( pControl );
|
|
}
|
|
|
|
m_Controls.RemoveAll();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTDialogResourceManager::CDXUTDialogResourceManager()
|
|
{
|
|
m_pd3dDevice = NULL;
|
|
m_pStateBlock = NULL;
|
|
m_pSprite = NULL;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
HRESULT CDXUTDialogResourceManager::OnResetDevice()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
for( int i=0; i < m_FontCache.GetSize(); i++ )
|
|
{
|
|
DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
|
|
|
|
if( pFontNode->pFont )
|
|
pFontNode->pFont->OnResetDevice();
|
|
}
|
|
|
|
if( m_pSprite )
|
|
m_pSprite->OnResetDevice();
|
|
|
|
m_pd3dDevice->CreateStateBlock( D3DSBT_ALL, &m_pStateBlock );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTDialogResourceManager::OnLostDevice()
|
|
{
|
|
for( int i=0; i < m_FontCache.GetSize(); i++ )
|
|
{
|
|
DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
|
|
|
|
if( pFontNode->pFont )
|
|
pFontNode->pFont->OnLostDevice();
|
|
}
|
|
|
|
if( m_pSprite )
|
|
m_pSprite->OnLostDevice();
|
|
|
|
SAFE_RELEASE( m_pStateBlock );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTDialogResourceManager::OnDestroyDevice()
|
|
{
|
|
int i=0;
|
|
|
|
//m_pd3dDevice = NULL;
|
|
|
|
// Release the resources but don't clear the cache, as these will need to be
|
|
// recreated if the device is recreated
|
|
for( i=0; i < m_FontCache.GetSize(); i++ )
|
|
{
|
|
DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
|
|
SAFE_RELEASE( pFontNode->pFont );
|
|
}
|
|
|
|
for( i=0; i < m_TextureCache.GetSize(); i++ )
|
|
{
|
|
DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
|
|
SAFE_RELEASE( pTextureNode->pTexture );
|
|
}
|
|
|
|
SAFE_RELEASE( m_pSprite );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTDialog::Refresh()
|
|
{
|
|
if( s_pControlFocus )
|
|
s_pControlFocus->OnFocusOut();
|
|
|
|
if( m_pControlMouseOver )
|
|
m_pControlMouseOver->OnMouseLeave();
|
|
|
|
s_pControlFocus = NULL;
|
|
s_pControlPressed = NULL;
|
|
m_pControlMouseOver = NULL;
|
|
|
|
for( int i=0; i < m_Controls.GetSize(); i++ )
|
|
{
|
|
CDXUTControl* pControl = m_Controls.GetAt(i);
|
|
pControl->Refresh();
|
|
}
|
|
|
|
if( m_bKeyboardInput )
|
|
FocusDefaultControl();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
VOID CDXUTDialog::SendEvent( UINT nEvent, bool bTriggeredByUser, CDXUTControl* pControl )
|
|
{
|
|
// If no callback has been registered there's nowhere to send the event to
|
|
if( m_pCallbackEvent == NULL )
|
|
return;
|
|
|
|
// Discard events triggered programatically if these types of events haven't been
|
|
// enabled
|
|
if( !bTriggeredByUser && !m_bNonUserEvents )
|
|
return;
|
|
|
|
m_pCallbackEvent( nEvent, pControl->GetID(), pControl, m_pCallbackEventUserContext );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
int CDXUTDialogResourceManager::AddFont( LPCTSTR strFaceName, LONG height, LONG weight )
|
|
{
|
|
// See if this font already exists
|
|
for( int i=0; i < m_FontCache.GetSize(); i++ )
|
|
{
|
|
DXUTFontNode* pFontNode = m_FontCache.GetAt(i);
|
|
if( 0 == _strnicmp( pFontNode->strFace, strFaceName, MAX_PATH-1 ) &&
|
|
pFontNode->nHeight == height &&
|
|
pFontNode->nWeight == weight )
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// Add a new font and try to create it
|
|
DXUTFontNode* pNewFontNode = new DXUTFontNode();
|
|
if( pNewFontNode == NULL )
|
|
return -1;
|
|
|
|
ZeroMemory( pNewFontNode, sizeof(DXUTFontNode) );
|
|
StringCchCopy( pNewFontNode->strFace, MAX_PATH, strFaceName );
|
|
pNewFontNode->nHeight = height;
|
|
pNewFontNode->nWeight = weight;
|
|
m_FontCache.Add( pNewFontNode );
|
|
|
|
int iFont = m_FontCache.GetSize()-1;
|
|
|
|
// If a device is available, try to create immediately
|
|
if( m_pd3dDevice )
|
|
CreateFont( iFont );
|
|
|
|
return iFont;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
HRESULT CDXUTDialog::SetFont( UINT index, LPCTSTR strFaceName, LONG height, LONG weight )
|
|
{
|
|
// If this assert triggers, you need to call CDXUTDialog::Init() first. This change
|
|
// was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
|
|
// creation and interfacing with CDXUTDialogResourceManager is now the responsibility
|
|
// of the application if it wishes to use DXUT's GUI.
|
|
assert( m_pManager != NULL && "To fix call CDXUTDialog::Init() first. See comments for details." );
|
|
|
|
// Make sure the list is at least as large as the index being set
|
|
UINT i;
|
|
for( i=m_Fonts.GetSize(); i <= index; i++ )
|
|
{
|
|
m_Fonts.Add( -1 );
|
|
}
|
|
|
|
int iFont = m_pManager->AddFont( strFaceName, height, weight );
|
|
m_Fonts.SetAt( index, iFont );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
DXUTFontNode* CDXUTDialog::GetFont( UINT index )
|
|
{
|
|
if( NULL == m_pManager )
|
|
return NULL;
|
|
return m_pManager->GetFontNode( m_Fonts.GetAt( index ) );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
HRESULT CDXUTDialog::InitControl( CDXUTControl* pControl )
|
|
{
|
|
HRESULT hr;
|
|
|
|
if( pControl == NULL )
|
|
return E_INVALIDARG;
|
|
|
|
pControl->m_Index = m_Controls.GetSize();
|
|
|
|
// Look for a default Element entries
|
|
for( int i=0; i < m_DefaultElements.GetSize(); i++ )
|
|
{
|
|
DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
|
|
if( pElementHolder->nControlType == pControl->GetType() )
|
|
pControl->SetElement( pElementHolder->iElement, &pElementHolder->Element );
|
|
}
|
|
|
|
V_RETURN( pControl->OnInit() );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
HRESULT CDXUTDialog::AddControl( CDXUTControl* pControl )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = InitControl( pControl );
|
|
if( FAILED(hr) )
|
|
return DXTRACE_ERR( "CDXUTDialog::InitControl", hr );
|
|
|
|
// Add to the list
|
|
hr = m_Controls.Add( pControl );
|
|
if( FAILED(hr) )
|
|
{
|
|
return DXTRACE_ERR( "CGrowableArray::Add", hr );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTControl* CDXUTDialog::GetControl( int ID )
|
|
{
|
|
// Try to find the control with the given ID
|
|
for( int i=0; i < m_Controls.GetSize(); i++ )
|
|
{
|
|
CDXUTControl* pControl = m_Controls.GetAt( i );
|
|
|
|
if( pControl->GetID() == ID )
|
|
{
|
|
return pControl;
|
|
}
|
|
}
|
|
|
|
// Not found
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTControl* CDXUTDialog::GetControl( int ID, UINT nControlType )
|
|
{
|
|
// Try to find the control with the given ID
|
|
for( int i=0; i < m_Controls.GetSize(); i++ )
|
|
{
|
|
CDXUTControl* pControl = m_Controls.GetAt( i );
|
|
|
|
if( pControl->GetID() == ID && pControl->GetType() == nControlType )
|
|
{
|
|
return pControl;
|
|
}
|
|
}
|
|
|
|
// Not found
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTControl* CDXUTDialog::GetNextControl( CDXUTControl* pControl )
|
|
{
|
|
int index = pControl->m_Index + 1;
|
|
|
|
CDXUTDialog* pDialog = pControl->m_pDialog;
|
|
|
|
// Cycle through dialogs in the loop to find the next control. Note
|
|
// that if only one control exists in all looped dialogs it will
|
|
// be the returned 'next' control.
|
|
while( index >= (int) pDialog->m_Controls.GetSize() )
|
|
{
|
|
pDialog = pDialog->m_pNextDialog;
|
|
index = 0;
|
|
}
|
|
|
|
return pDialog->m_Controls.GetAt( index );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTControl* CDXUTDialog::GetPrevControl( CDXUTControl* pControl )
|
|
{
|
|
int index = pControl->m_Index - 1;
|
|
|
|
CDXUTDialog* pDialog = pControl->m_pDialog;
|
|
|
|
// Cycle through dialogs in the loop to find the next control. Note
|
|
// that if only one control exists in all looped dialogs it will
|
|
// be the returned 'previous' control.
|
|
while( index < 0 )
|
|
{
|
|
pDialog = pDialog->m_pPrevDialog;
|
|
if( pDialog == NULL )
|
|
pDialog = pControl->m_pDialog;
|
|
|
|
index = pDialog->m_Controls.GetSize() - 1;
|
|
}
|
|
|
|
return pDialog->m_Controls.GetAt( index );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
// CDXUTControl class
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
CDXUTControl::CDXUTControl( CDXUTDialog *pDialog )
|
|
{
|
|
m_Type = DXUT_CONTROL_BUTTON;
|
|
m_pDialog = pDialog;
|
|
m_ID = 0;
|
|
m_Index = 0;
|
|
m_pUserData = NULL;
|
|
|
|
m_bEnabled = true;
|
|
m_bVisible = true;
|
|
m_bMouseOver = false;
|
|
m_bHasFocus = false;
|
|
m_bIsDefault = false;
|
|
|
|
m_pDialog = NULL;
|
|
|
|
m_x = 0;
|
|
m_y = 0;
|
|
m_width = 0;
|
|
m_height = 0;
|
|
|
|
ZeroMemory( &m_rcBoundingBox, sizeof( m_rcBoundingBox ) );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
// CDXUTStatic class
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
HRESULT CDXUTStatic::GetTextCopy( PCHAR strDest, UINT bufferCount )
|
|
{
|
|
// Validate incoming parameters
|
|
if( strDest == NULL || bufferCount == 0 )
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// Copy the window text
|
|
StringCchCopy( strDest, bufferCount, m_strText );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
// CDXUTIMEEditBox class
|
|
//--------------------------------------------------------------------------------------
|
|
bool CDXUTIMEEditBox::s_bEnableImeSystem; // Whether the IME system is active
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
// Enable/disable the entire IME system. When disabled, the default IME handling
|
|
// kicks in.
|
|
void CDXUTIMEEditBox::EnableImeSystem( bool bEnable )
|
|
{
|
|
s_bEnableImeSystem = bEnable;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void DXUTBlendColor::Init( D3DCOLOR defaultColor, D3DCOLOR disabledColor, D3DCOLOR hiddenColor )
|
|
{
|
|
for( int i=0; i < MAX_CONTROL_STATES; i++ )
|
|
{
|
|
States[ i ] = defaultColor;
|
|
}
|
|
|
|
States[ DXUT_STATE_DISABLED ] = disabledColor;
|
|
States[ DXUT_STATE_HIDDEN ] = hiddenColor;
|
|
Current = hiddenColor;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void DXUTBlendColor::Blend( UINT iState, float fElapsedTime, float fRate )
|
|
{
|
|
D3DXCOLOR destColor = States[ iState ];
|
|
D3DXColorLerp( &Current, &Current, &destColor, 1.0f - powf( fRate, 30 * fElapsedTime ) );
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTElement::SetTexture( UINT iTexture, RECT* prcTexture, D3DCOLOR defaultTextureColor )
|
|
{
|
|
this->iTexture = iTexture;
|
|
|
|
if( prcTexture )
|
|
rcTexture = *prcTexture;
|
|
else
|
|
SetRectEmpty( &rcTexture );
|
|
|
|
TextureColor.Init( defaultTextureColor );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTElement::SetFont( UINT iFont, D3DCOLOR defaultFontColor, DWORD dwTextFormat )
|
|
{
|
|
this->iFont = iFont;
|
|
this->dwTextFormat = dwTextFormat;
|
|
|
|
FontColor.Init( defaultFontColor );
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
void CDXUTElement::Refresh()
|
|
{
|
|
TextureColor.Current = TextureColor.States[ DXUT_STATE_HIDDEN ];
|
|
FontColor.Current = FontColor.States[ DXUT_STATE_HIDDEN ];
|
|
}
|
|
|