You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
361 lines
10 KiB
361 lines
10 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "vgui_controls/MessageDialog.h" |
|
#include "vgui/ILocalize.h" |
|
#include "vgui/ISurface.h" |
|
|
|
// NOTE: This has to be the last file included! |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// CMessageDialog |
|
//----------------------------------------------------------------------------- |
|
CMessageDialog::CMessageDialog( vgui::Panel *pParent, const uint nType, const char *pTitle, const char *pMsg, const char *pCmdA, const char *pCmdB, vgui::Panel *pCreator, bool bShowActivity ) |
|
: BaseClass( pParent, "MessageDialog" ) |
|
{ |
|
SetSize( 500, 200 ); |
|
SetDeleteSelfOnClose( true ); |
|
SetTitleBarVisible( false ); |
|
SetCloseButtonVisible( false ); |
|
SetSizeable( false ); |
|
|
|
m_pControlSettings = NULL; |
|
m_pCreator = pCreator ? pCreator : pParent; |
|
|
|
m_nType = nType; |
|
m_pTitle = new vgui::Label( this, "TitleLabel", pTitle ); |
|
m_pMsg = new vgui::Label( this, "MessageLabel", pMsg ); |
|
m_pAnimatingPanel = new vgui::AnimatingImagePanel( this, "AnimatingPanel" ); |
|
|
|
m_bShowActivity = bShowActivity; |
|
|
|
if ( nType & MD_SIMPLEFRAME ) |
|
{ |
|
SetPaintBackgroundEnabled( true ); |
|
m_pBackground = NULL; |
|
} |
|
else |
|
{ |
|
m_pBackground = new vgui::ImagePanel( this, "Background" ); |
|
if ( nType & MD_WARNING ) |
|
{ |
|
m_pBackground->SetName( "WarningBackground" ); |
|
} |
|
else if ( nType & MD_ERROR ) |
|
{ |
|
m_pBackground->SetName( "ErrorBackground" ); |
|
} |
|
} |
|
|
|
Q_memset( m_pCommands, 0, sizeof( m_pCommands ) ); |
|
Q_memset( m_Buttons, 0, sizeof( m_Buttons ) ); |
|
|
|
if ( pCmdA ) |
|
{ |
|
const int len = Q_strlen( pCmdA ) + 1; |
|
m_pCommands[BTN_A] = (char*)malloc( len ); |
|
Q_strncpy( m_pCommands[BTN_A], pCmdA, len ); |
|
} |
|
|
|
if ( pCmdB ) |
|
{ |
|
const int len = Q_strlen( pCmdB ) + 1; |
|
m_pCommands[BTN_B] = (char*)malloc( len ); |
|
Q_strncpy( m_pCommands[BTN_B], pCmdB, len ); |
|
} |
|
|
|
// invalid until pressed |
|
m_ButtonPressed = BTN_INVALID; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Destructor |
|
//----------------------------------------------------------------------------- |
|
CMessageDialog::~CMessageDialog() |
|
{ |
|
if ( m_ButtonPressed != BTN_INVALID && ( m_nType & MD_COMMANDAFTERCLOSE ) ) |
|
{ |
|
// caller wants the command sent after closure |
|
m_pCreator->OnCommand( m_pCommands[m_ButtonPressed] ); |
|
} |
|
else if ( m_nType & MD_COMMANDONFORCECLOSE ) |
|
{ |
|
// caller wants the command sent after closure |
|
m_pCreator->OnCommand( m_pCommands[BTN_A] ); |
|
} |
|
|
|
for ( int i = 0; i < MAX_BUTTONS; ++i ) |
|
{ |
|
free( m_pCommands[i] ); |
|
m_pCommands[i] = NULL; |
|
|
|
delete m_Buttons[i].pIcon; |
|
delete m_Buttons[i].pText; |
|
} |
|
|
|
delete m_pTitle; |
|
m_pTitle = NULL; |
|
|
|
delete m_pMsg; |
|
m_pMsg = NULL; |
|
|
|
delete m_pBackground; |
|
m_pBackground = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the keyvalues to pass to LoadControlSettings() |
|
//----------------------------------------------------------------------------- |
|
void CMessageDialog::SetControlSettingsKeys( KeyValues *pKeys ) |
|
{ |
|
m_pControlSettings = pKeys; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Create a new button |
|
//----------------------------------------------------------------------------- |
|
void CMessageDialog::CreateButtonLabel( ButtonLabel_s *pButton, const char *pIcon, const char *pText ) |
|
{ |
|
pButton->nWide = m_ButtonIconLabelSpace; |
|
pButton->bCreated = true; |
|
|
|
pButton->pIcon = new vgui::Label( this, "icon", pIcon ); |
|
SETUP_PANEL( pButton->pIcon ); |
|
pButton->pIcon->SetFont( m_hButtonFont ); |
|
pButton->pIcon->SizeToContents(); |
|
pButton->nWide += pButton->pIcon->GetWide(); |
|
|
|
pButton->pText = new vgui::Label( this, "text", pText ); |
|
SETUP_PANEL( pButton->pText ); |
|
pButton->pText->SetFont( m_hTextFont ); |
|
pButton->pText->SizeToContents(); |
|
pButton->pText->SetFgColor( m_ButtonTextColor ); |
|
pButton->nWide += pButton->pText->GetWide(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Create and arrange the panel button labels according to the dialog type |
|
//----------------------------------------------------------------------------- |
|
void CMessageDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
LoadControlSettings( "resource/UI/MessageDialog.res", "GAME", m_pControlSettings ); |
|
|
|
m_hButtonFont = pScheme->GetFont( "GameUIButtons" ); |
|
m_hTextFont = pScheme->GetFont( "MenuLarge" ); |
|
|
|
if ( m_nType & MD_OK ) |
|
{ |
|
CreateButtonLabel( &m_Buttons[BTN_A], "#GameUI_Icons_A_BUTTON", "#GameUI_OK" ); |
|
} |
|
else if ( m_nType & MD_CANCEL ) |
|
{ |
|
CreateButtonLabel( &m_Buttons[BTN_B], "#GameUI_Icons_B_BUTTON", "#GameUI_Cancel" ); |
|
} |
|
else if ( m_nType & MD_OKCANCEL ) |
|
{ |
|
CreateButtonLabel( &m_Buttons[BTN_A], "#GameUI_Icons_A_BUTTON", "#GameUI_OK" ); |
|
CreateButtonLabel( &m_Buttons[BTN_B], "#GameUI_Icons_B_BUTTON", "#GameUI_Cancel" ); |
|
} |
|
else if ( m_nType & MD_YESNO ) |
|
{ |
|
CreateButtonLabel( &m_Buttons[BTN_A], "#GameUI_Icons_A_BUTTON", "#GameUI_Yes" ); |
|
CreateButtonLabel( &m_Buttons[BTN_B], "#GameUI_Icons_B_BUTTON", "#GameUI_No" ); |
|
} |
|
|
|
// count the buttons and add up their widths |
|
int cButtons = 0; |
|
int nTotalWide = 0; |
|
for ( int i = 0; i < MAX_BUTTONS; ++i ) |
|
{ |
|
if ( m_Buttons[i].bCreated ) |
|
{ |
|
++cButtons; |
|
nTotalWide += m_Buttons[i].nWide; |
|
} |
|
} |
|
|
|
// make sure text and icons are center-aligned vertically with each other |
|
int nButtonTall = vgui::surface()->GetFontTall( m_hButtonFont ); |
|
int nTextTall = vgui::surface()->GetFontTall( m_hTextFont ); |
|
int nVerticalAdjust = ( nButtonTall - nTextTall ) / 2; |
|
|
|
// position the buttons with even horizontal spacing |
|
int xpos = 0; |
|
int ypos = GetTall() - max( nButtonTall, nTextTall ) - m_ButtonMargin; |
|
int nSpacing = ( GetWide() - nTotalWide ) / ( cButtons + 1 ); |
|
for ( int i = 0; i < MAX_BUTTONS; ++i ) |
|
{ |
|
if ( m_Buttons[i].bCreated ) |
|
{ |
|
xpos += nSpacing; |
|
m_Buttons[i].pIcon->SetPos( xpos, ypos ); |
|
xpos += m_Buttons[i].pIcon->GetWide() + m_ButtonIconLabelSpace; |
|
m_Buttons[i].pText->SetPos( xpos, ypos + nVerticalAdjust ); |
|
xpos += m_Buttons[i].pText->GetWide(); |
|
} |
|
} |
|
|
|
m_clrNotSimpleBG = pScheme->GetColor( "MessageDialog.MatchmakingBG", Color( 200, 184, 151, 255 ) ); |
|
m_clrNotSimpleBGBlack = pScheme->GetColor( "MessageDialog.MatchmakingBGBlack", Color( 52, 48, 55, 255 ) ); |
|
|
|
if ( !m_bShowActivity ) |
|
{ |
|
if ( m_pAnimatingPanel ) |
|
{ |
|
if ( m_pAnimatingPanel->IsVisible() ) |
|
{ |
|
|
|
m_pAnimatingPanel->SetVisible( false ); |
|
} |
|
|
|
m_pAnimatingPanel->StopAnimation(); |
|
} |
|
} |
|
else |
|
{ |
|
if ( m_pAnimatingPanel ) |
|
{ |
|
if ( !m_pAnimatingPanel->IsVisible() ) |
|
{ |
|
m_pAnimatingPanel->SetVisible( true ); |
|
} |
|
|
|
m_pAnimatingPanel->StartAnimation(); |
|
} |
|
} |
|
|
|
MoveToCenterOfScreen(); |
|
|
|
if ( m_bShowActivity && m_ActivityIndent ) |
|
{ |
|
// If we're animating, we push our text label in, and reduce its width |
|
int iX,iY,iW,iH; |
|
m_pMsg->GetBounds( iX, iY, iW, iH ); |
|
m_pMsg->SetBounds( iX + m_ActivityIndent, iY, max(0,iW-m_ActivityIndent), iH ); |
|
} |
|
|
|
// Invalidate the scheme on our message label so that it recalculates |
|
// its line breaks in case it was resized when we loaded our .res file. |
|
m_pMsg->InvalidateLayout( false, true ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Create and arrange the panel button labels according to the dialog type |
|
//----------------------------------------------------------------------------- |
|
void CMessageDialog::ApplySettings( KeyValues *inResourceData ) |
|
{ |
|
BaseClass::ApplySettings( inResourceData ); |
|
|
|
m_pTitle->SetFgColor( inResourceData->GetColor( "titlecolor" ) ); |
|
|
|
m_pMsg->SetFgColor( inResourceData->GetColor( "messagecolor" ) ); |
|
|
|
m_ButtonTextColor = inResourceData->GetColor( "buttontextcolor" ); |
|
|
|
m_FooterTall = inResourceData->GetInt( "footer_tall", 0 ); |
|
m_ButtonMargin = inResourceData->GetInt( "button_margin", 25 ); |
|
m_ButtonIconLabelSpace = inResourceData->GetInt( "button_separator", 10 ); |
|
m_ActivityIndent = inResourceData->GetInt( "activity_indent", 0 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
uint CMessageDialog::GetType( void ) |
|
{ |
|
return m_nType; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMessageDialog::DoCommand( int button ) |
|
{ |
|
if ( button == BTN_INVALID || ( m_nType & MD_COMMANDONFORCECLOSE ) ) |
|
{ |
|
return; |
|
} |
|
|
|
if ( m_pCommands[button] ) |
|
{ |
|
m_ButtonPressed = button; |
|
if ( !( m_nType & MD_COMMANDAFTERCLOSE ) ) |
|
{ |
|
// caller wants the command sent before closure |
|
m_pCreator->OnCommand( m_pCommands[m_ButtonPressed] ); |
|
} |
|
m_pCreator->OnCommand( "ReleaseModalWindow" ); |
|
Close(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMessageDialog::OnKeyCodePressed( vgui::KeyCode code ) |
|
{ |
|
if ( m_ButtonPressed != BTN_INVALID || GetAlpha() != 255 ) |
|
{ |
|
// inhibit any further key activity or during transitions |
|
return; |
|
} |
|
|
|
switch ( GetBaseButtonCode( code ) ) |
|
{ |
|
case KEY_XBUTTON_A: |
|
case STEAMCONTROLLER_A: |
|
DoCommand( BTN_A ); |
|
break; |
|
|
|
case KEY_XBUTTON_B: |
|
case STEAMCONTROLLER_B: |
|
DoCommand( BTN_B ); |
|
break; |
|
|
|
default: |
|
break; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMessageDialog::PaintBackground( void ) |
|
{ |
|
int wide, tall; |
|
GetSize( wide, tall ); |
|
|
|
if ( !( m_nType & MD_SIMPLEFRAME ) ) |
|
{ |
|
int nAlpha = GetAlpha(); |
|
|
|
m_clrNotSimpleBG[3] = nAlpha; |
|
m_clrNotSimpleBGBlack[3] = nAlpha; |
|
|
|
DrawBox( 0, 0, wide, tall, m_clrNotSimpleBGBlack, 1.0f ); |
|
DrawBox( 0, 0, wide, tall - m_FooterTall, m_clrNotSimpleBG, 1.0f ); |
|
|
|
return; |
|
} |
|
|
|
Color col = GetBgColor(); |
|
DrawBox( 0, 0, wide, tall, col, 1.0f ); |
|
|
|
// offset the inset by title |
|
int titleX, titleY, titleWide, titleTall; |
|
m_pTitle->GetBounds( titleX, titleY, titleWide, titleTall ); |
|
int y = titleY + titleTall; |
|
|
|
// draw an inset |
|
Color darkColor; |
|
darkColor.SetColor( 0.70f * (float)col.r(), 0.70f * (float)col.g(), 0.70f * (float)col.b(), col.a() ); |
|
vgui::surface()->DrawSetColor( darkColor ); |
|
vgui::surface()->DrawFilledRect( 8, y, wide - 8, tall - 8 ); |
|
}
|
|
|