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.
637 lines
18 KiB
637 lines
18 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
|
|
#include "LoadingDialog.h"
|
|
#include "EngineInterface.h"
|
|
#include "igameuifuncs.h"
|
|
|
|
#include <vgui/IInput.h>
|
|
#include <vgui/ISurface.h>
|
|
#include <vgui/ILocalize.h>
|
|
#include <vgui/IScheme.h>
|
|
#include <vgui/ISystem.h>
|
|
#include <vgui_controls/ProgressBar.h>
|
|
#include <vgui_controls/Label.h>
|
|
#include <vgui_controls/Button.h>
|
|
#include <vgui_controls/HTML.h>
|
|
#include <vgui_controls/RichText.h>
|
|
#include "tier0/icommandline.h"
|
|
|
|
#include "GameUI_Interface.h"
|
|
#include "ModInfo.h"
|
|
#include "basepanel.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include <tier0/memdbgon.h>
|
|
|
|
using namespace vgui;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CLoadingDialog::CLoadingDialog( vgui::Panel *parent ) : Frame(parent, "LoadingDialog")
|
|
{
|
|
SetDeleteSelfOnClose(true);
|
|
|
|
// Use console style
|
|
m_bConsoleStyle = GameUI().IsConsoleUI();
|
|
|
|
if ( !m_bConsoleStyle )
|
|
{
|
|
SetSize( 416, 100 );
|
|
SetTitle( "#GameUI_Loading", true );
|
|
}
|
|
|
|
// center the loading dialog, unless we have another dialog to show in the background
|
|
m_bCenter = !GameUI().HasLoadingBackgroundDialog();
|
|
|
|
m_bShowingSecondaryProgress = false;
|
|
m_flSecondaryProgress = 0.0f;
|
|
m_flLastSecondaryProgressUpdateTime = 0.0f;
|
|
m_flSecondaryProgressStartTime = 0.0f;
|
|
|
|
m_pProgress = new ProgressBar( this, "Progress" );
|
|
m_pProgress2 = new ProgressBar( this, "Progress2" );
|
|
m_pInfoLabel = new Label( this, "InfoLabel", "" );
|
|
m_pCancelButton = new Button( this, "CancelButton", "#GameUI_Cancel" );
|
|
m_pTimeRemainingLabel = new Label( this, "TimeRemainingLabel", "" );
|
|
m_pCancelButton->SetCommand( "Cancel" );
|
|
|
|
if ( ModInfo().IsSinglePlayerOnly() == false && m_bConsoleStyle == true )
|
|
{
|
|
m_pLoadingBackground = new Panel( this, "LoadingDialogBG" );
|
|
}
|
|
else
|
|
{
|
|
m_pLoadingBackground = NULL;
|
|
}
|
|
|
|
SetMinimizeButtonVisible( false );
|
|
SetMaximizeButtonVisible( false );
|
|
SetCloseButtonVisible( false );
|
|
SetSizeable( false );
|
|
SetMoveable( false );
|
|
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
m_bCenter = false;
|
|
m_pProgress->SetVisible( false );
|
|
m_pProgress2->SetVisible( false );
|
|
m_pInfoLabel->SetVisible( false );
|
|
m_pCancelButton->SetVisible( false );
|
|
m_pTimeRemainingLabel->SetVisible( false );
|
|
m_pCancelButton->SetVisible( false );
|
|
|
|
SetMinimumSize( 0, 0 );
|
|
SetTitleBarVisible( false );
|
|
|
|
m_flProgressFraction = 0;
|
|
}
|
|
else
|
|
{
|
|
m_pInfoLabel->SetBounds(20, 32, 392, 24);
|
|
m_pProgress->SetBounds(20, 64, 300, 24);
|
|
m_pCancelButton->SetBounds(330, 64, 72, 24);
|
|
m_pInfoLabel->SetTextColorState(Label::CS_DULL);
|
|
m_pProgress2->SetVisible(false);
|
|
}
|
|
|
|
SetupControlSettings( false );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Destructor
|
|
//-----------------------------------------------------------------------------
|
|
CLoadingDialog::~CLoadingDialog()
|
|
{
|
|
}
|
|
|
|
void CLoadingDialog::PaintBackground()
|
|
{
|
|
if ( !m_bConsoleStyle )
|
|
{
|
|
BaseClass::PaintBackground();
|
|
return;
|
|
}
|
|
|
|
// draw solid progress bar with curved endcaps
|
|
int panelWide, panelTall;
|
|
GetSize( panelWide, panelTall );
|
|
int barWide, barTall;
|
|
m_pProgress->GetSize( barWide, barTall );
|
|
int x = ( panelWide - barWide )/2;
|
|
int y = panelTall - barTall;
|
|
|
|
if ( m_pLoadingBackground )
|
|
{
|
|
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
|
Color color = GetSchemeColor( "TanDarker", Color(255, 255, 255, 255), vgui::scheme()->GetIScheme(scheme) );
|
|
|
|
m_pLoadingBackground->SetFgColor( color );
|
|
m_pLoadingBackground->SetBgColor( color );
|
|
|
|
m_pLoadingBackground->SetPaintBackgroundEnabled( true );
|
|
}
|
|
|
|
if ( ModInfo().IsSinglePlayerOnly() )
|
|
{
|
|
DrawBox( x, y, barWide, barTall, Color( 0, 0, 0, 255 ), 1.0f );
|
|
}
|
|
|
|
DrawBox( x+2, y+2, barWide-4, barTall-4, Color( 100, 100, 100, 255 ), 1.0f );
|
|
|
|
barWide = m_flProgressFraction * ( barWide - 4 );
|
|
if ( barWide >= 12 )
|
|
{
|
|
// cannot draw a curved box smaller than 12 without artifacts
|
|
DrawBox( x+2, y+2, barWide, barTall-4, Color( 200, 100, 0, 255 ), 1.0f );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: sets up dialog layout
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::SetupControlSettings( bool bForceShowProgressText )
|
|
{
|
|
m_bShowingVACInfo = false;
|
|
|
|
#if defined( BASEPANEL_LEGACY_SOURCE1 )
|
|
if ( GameUI().IsConsoleUI() )
|
|
{
|
|
KeyValues *pControlSettings = BasePanel()->GetConsoleControlSettings()->FindKey( "LoadingDialogNoBanner.res" );
|
|
LoadControlSettings( "null", NULL, pControlSettings );
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if ( ModInfo().IsSinglePlayerOnly() && !bForceShowProgressText )
|
|
{
|
|
LoadControlSettings("Resource/LoadingDialogNoBannerSingle.res");
|
|
}
|
|
else if ( gameuifuncs->IsConnectedToVACSecureServer() )
|
|
{
|
|
LoadControlSettings("Resource/LoadingDialogVAC.res");
|
|
m_bShowingVACInfo = true;
|
|
}
|
|
else
|
|
{
|
|
LoadControlSettings("Resource/LoadingDialogNoBanner.res");
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Activates the loading screen, initializing and making it visible
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::Open()
|
|
{
|
|
if ( !m_bConsoleStyle )
|
|
{
|
|
SetTitle( "#GameUI_Loading", true );
|
|
}
|
|
|
|
HideOtherDialogs( true );
|
|
BaseClass::Activate();
|
|
|
|
if ( !m_bConsoleStyle )
|
|
{
|
|
m_pProgress->SetVisible( true );
|
|
if ( !ModInfo().IsSinglePlayerOnly() )
|
|
{
|
|
m_pInfoLabel->SetVisible( true );
|
|
}
|
|
m_pInfoLabel->SetText("");
|
|
|
|
m_pCancelButton->SetText("#GameUI_Cancel");
|
|
m_pCancelButton->SetCommand("Cancel");
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: error display file
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::SetupControlSettingsForErrorDisplay( const char *settingsFile )
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_bCenter = true;
|
|
SetTitle("#GameUI_Disconnected", true);
|
|
m_pInfoLabel->SetText("");
|
|
LoadControlSettings( settingsFile );
|
|
HideOtherDialogs( true );
|
|
|
|
BaseClass::Activate();
|
|
|
|
m_pProgress->SetVisible(false);
|
|
|
|
m_pInfoLabel->SetVisible(true);
|
|
m_pCancelButton->SetText("#GameUI_Close");
|
|
m_pCancelButton->SetCommand("Close");
|
|
m_pInfoLabel->InvalidateLayout();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: shows or hides other top-level dialogs
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::HideOtherDialogs( bool bHide )
|
|
{
|
|
if ( bHide )
|
|
{
|
|
if ( GameUI().HasLoadingBackgroundDialog() )
|
|
{
|
|
// if we have a loading background dialog, hide any other dialogs by moving the full-screen background dialog to the
|
|
// front, then moving ourselves in front of it
|
|
GameUI().ShowLoadingBackgroundDialog();
|
|
vgui::ipanel()->MoveToFront( GetVPanel() );
|
|
vgui::input()->SetAppModalSurface( GetVPanel() );
|
|
}
|
|
else
|
|
{
|
|
// if there is no loading background dialog, use VGUI paint restrictions to hide other dialogs
|
|
vgui::surface()->RestrictPaintToSinglePanel(GetVPanel());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( GameUI().HasLoadingBackgroundDialog() )
|
|
{
|
|
GameUI().HideLoadingBackgroundDialog();
|
|
vgui::input()->SetAppModalSurface( NULL );
|
|
}
|
|
else
|
|
{
|
|
// remove any rendering restrictions
|
|
vgui::surface()->RestrictPaintToSinglePanel(NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Turns dialog into error display
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::DisplayGenericError(const char *failureReason, const char *extendedReason)
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// In certain race conditions, DisplayGenericError can get called AFTER OnClose() has been called.
|
|
// If that happens and we don't call Activate(), then it'll continue closing when we don't want it to.
|
|
Activate();
|
|
|
|
SetupControlSettingsForErrorDisplay("Resource/LoadingDialogError.res");
|
|
|
|
if ( extendedReason && strlen( extendedReason ) > 0 )
|
|
{
|
|
wchar_t compositeReason[256], finalMsg[512], formatStr[256];
|
|
if ( extendedReason[0] == '#' )
|
|
{
|
|
wcsncpy(compositeReason, g_pVGuiLocalize->Find(extendedReason), sizeof( compositeReason ) / sizeof( wchar_t ) );
|
|
}
|
|
else
|
|
{
|
|
g_pVGuiLocalize->ConvertANSIToUnicode(extendedReason, compositeReason, sizeof( compositeReason ));
|
|
}
|
|
|
|
if ( failureReason[0] == '#' )
|
|
{
|
|
wcsncpy(formatStr, g_pVGuiLocalize->Find(failureReason), sizeof( formatStr ) / sizeof( wchar_t ) );
|
|
}
|
|
else
|
|
{
|
|
g_pVGuiLocalize->ConvertANSIToUnicode(failureReason, formatStr, sizeof( formatStr ));
|
|
}
|
|
|
|
g_pVGuiLocalize->ConstructString(finalMsg, sizeof( finalMsg ), formatStr, 1, compositeReason);
|
|
m_pInfoLabel->SetText(finalMsg);
|
|
}
|
|
else
|
|
{
|
|
m_pInfoLabel->SetText(failureReason);
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: explain to the user they can't join secure servers due to a VAC ban
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::DisplayVACBannedError()
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetupControlSettingsForErrorDisplay("Resource/LoadingDialogErrorVACBanned.res");
|
|
SetTitle("#VAC_ConnectionRefusedTitle", true);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: explain to the user they can't connect to public servers due to
|
|
// not having a valid connection to Steam
|
|
// this should only happen if they are a pirate
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::DisplayNoSteamConnectionError()
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetupControlSettingsForErrorDisplay("Resource/LoadingDialogErrorNoSteamConnection.res");
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: explain to the user they got kicked from a server due to that same account
|
|
// logging in from another location. This also triggers the refresh login dialog on OK
|
|
// being pressed.
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::DisplayLoggedInElsewhereError()
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetupControlSettingsForErrorDisplay("Resource/LoadingDialogErrorLoggedInElsewhere.res");
|
|
m_pCancelButton->SetText("#GameUI_RefreshLogin_Login");
|
|
m_pCancelButton->SetCommand("Login");
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: sets status info text
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::SetStatusText(const char *statusText)
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_pInfoLabel->SetText(statusText);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: returns the previous state
|
|
//-----------------------------------------------------------------------------
|
|
bool CLoadingDialog::SetShowProgressText( bool show )
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool bret = m_pInfoLabel->IsVisible();
|
|
if ( bret != show )
|
|
{
|
|
SetupControlSettings( show );
|
|
m_pInfoLabel->SetVisible( show );
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: updates time remaining
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::OnThink()
|
|
{
|
|
BaseClass::OnThink();
|
|
|
|
if ( !m_bConsoleStyle && m_bShowingSecondaryProgress )
|
|
{
|
|
// calculate the time remaining string
|
|
wchar_t unicode[512];
|
|
if (m_flSecondaryProgress >= 1.0f)
|
|
{
|
|
m_pTimeRemainingLabel->SetText("complete");
|
|
}
|
|
else if (ProgressBar::ConstructTimeRemainingString(unicode, sizeof(unicode), m_flSecondaryProgressStartTime, (float)system()->GetFrameTime(), m_flSecondaryProgress, m_flLastSecondaryProgressUpdateTime, true))
|
|
{
|
|
m_pTimeRemainingLabel->SetText(unicode);
|
|
}
|
|
else
|
|
{
|
|
m_pTimeRemainingLabel->SetText("");
|
|
}
|
|
}
|
|
|
|
SetAlpha( 255 );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::PerformLayout()
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
// place in lower center
|
|
int screenWide, screenTall;
|
|
surface()->GetScreenSize( screenWide, screenTall );
|
|
int wide,tall;
|
|
GetSize( wide, tall );
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
if ( ModInfo().IsSinglePlayerOnly() )
|
|
{
|
|
x = ( screenWide - wide ) * 0.50f;
|
|
y = ( screenTall - tall ) * 0.86f;
|
|
}
|
|
else
|
|
{
|
|
x = ( screenWide - ( wide * 1.30f ) );
|
|
y = ( ( screenTall * 0.875f ) );
|
|
}
|
|
|
|
SetPos( x, y );
|
|
}
|
|
else if ( m_bCenter )
|
|
{
|
|
MoveToCenterOfScreen();
|
|
}
|
|
else
|
|
{
|
|
// if we're not supposed to be centered, move ourselves to the lower right hand corner of the screen
|
|
int x, y, screenWide, screenTall;
|
|
surface()->GetWorkspaceBounds( x, y, screenWide, screenTall );
|
|
int wide,tall;
|
|
GetSize( wide, tall );
|
|
|
|
if ( IsPC() )
|
|
{
|
|
x = screenWide - ( wide + 10 );
|
|
y = screenTall - ( tall + 10 );
|
|
}
|
|
else
|
|
{
|
|
// Move farther in so we're title safe
|
|
x = screenWide - wide - (screenWide * 0.05);
|
|
y = screenTall - tall - (screenTall * 0.05);
|
|
}
|
|
|
|
x -= m_iAdditionalIndentX;
|
|
y -= m_iAdditionalIndentY;
|
|
|
|
SetPos( x, y );
|
|
}
|
|
|
|
BaseClass::PerformLayout();
|
|
|
|
vgui::ipanel()->MoveToFront( GetVPanel() );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: returns true if the number of ticks has changed
|
|
//-----------------------------------------------------------------------------
|
|
bool CLoadingDialog::SetProgressPoint( float fraction )
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
if ( fraction >= 0.99f )
|
|
{
|
|
// show the progress artifically completed to fill in 100%
|
|
fraction = 1.0f;
|
|
}
|
|
fraction = clamp( fraction, 0.0f, 1.0f );
|
|
if ( (int)(fraction * 25) != (int)(m_flProgressFraction * 25) )
|
|
{
|
|
m_flProgressFraction = fraction;
|
|
return true;
|
|
}
|
|
return IsGameConsole();
|
|
}
|
|
|
|
if ( !m_bShowingVACInfo && gameuifuncs->IsConnectedToVACSecureServer() )
|
|
{
|
|
SetupControlSettings( false );
|
|
}
|
|
|
|
int nOldDrawnSegments = m_pProgress->GetDrawnSegmentCount();
|
|
m_pProgress->SetProgress( fraction );
|
|
int nNewDrawSegments = m_pProgress->GetDrawnSegmentCount();
|
|
return (nOldDrawnSegments != nNewDrawSegments) || IsGameConsole();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: sets and shows the secondary progress bar
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::SetSecondaryProgress( float progress )
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
return;
|
|
|
|
// don't show the progress if we've jumped right to completion
|
|
if (!m_bShowingSecondaryProgress && progress > 0.99f)
|
|
return;
|
|
|
|
// if we haven't yet shown secondary progress then reconfigure the dialog
|
|
if (!m_bShowingSecondaryProgress)
|
|
{
|
|
LoadControlSettings("Resource/LoadingDialogDualProgress.res");
|
|
m_bShowingSecondaryProgress = true;
|
|
m_pProgress2->SetVisible(true);
|
|
m_flSecondaryProgressStartTime = (float)system()->GetFrameTime();
|
|
}
|
|
|
|
// if progress has increased then update the progress counters
|
|
if (progress > m_flSecondaryProgress)
|
|
{
|
|
m_pProgress2->SetProgress(progress);
|
|
m_flSecondaryProgress = progress;
|
|
m_flLastSecondaryProgressUpdateTime = (float)system()->GetFrameTime();
|
|
}
|
|
|
|
// if progress has decreased then reset progress counters
|
|
if (progress < m_flSecondaryProgress)
|
|
{
|
|
m_pProgress2->SetProgress(progress);
|
|
m_flSecondaryProgress = progress;
|
|
m_flLastSecondaryProgressUpdateTime = (float)system()->GetFrameTime();
|
|
m_flSecondaryProgressStartTime = (float)system()->GetFrameTime();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::SetSecondaryProgressText(const char *statusText)
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetControlString( "SecondaryProgressLabel", statusText );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::OnClose()
|
|
{
|
|
// remove any rendering restrictions
|
|
HideOtherDialogs( false );
|
|
|
|
BaseClass::OnClose();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: command handler
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::OnCommand(const char *command)
|
|
{
|
|
if ( !stricmp(command, "Cancel") )
|
|
{
|
|
// disconnect from the server
|
|
engine->ClientCmd_Unrestricted("disconnect\n");
|
|
|
|
// close
|
|
Close();
|
|
}
|
|
else
|
|
{
|
|
BaseClass::OnCommand(command);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Maps ESC to quiting loading
|
|
//-----------------------------------------------------------------------------
|
|
void CLoadingDialog::OnKeyCodePressed(KeyCode code)
|
|
{
|
|
if ( m_bConsoleStyle )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( code == KEY_ESCAPE )
|
|
{
|
|
OnCommand("Cancel");
|
|
}
|
|
else
|
|
{
|
|
BaseClass::OnKeyCodePressed(code);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Singleton accessor
|
|
//-----------------------------------------------------------------------------
|
|
extern vgui::DHANDLE<CLoadingDialog> g_hLoadingDialog;
|
|
CLoadingDialog *LoadingDialog()
|
|
{
|
|
return g_hLoadingDialog.Get();
|
|
}
|