//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #include "cbase.h" #if defined( REPLAY_ENABLED ) #include "replaybrowserpreviewpanel.h" #include "replaybrowsermainpanel.h" #include "replaybrowsermovieplayerpanel.h" #include "replaybrowserlistitempanel.h" #include "replay/ireplaymovie.h" #include "replay/screenshot.h" #include "vgui/ISurface.h" #include "econ/econ_controls.h" // memdbgon must be the last include file in a .cpp file!!! #include //----------------------------------------------------------------------------- CReplayPreviewPanelBase::CReplayPreviewPanelBase( Panel *pParent, QueryableReplayItemHandle_t hItem, IReplayItemManager *pItemManager ) : EditablePanel( pParent, "PreviewPanel" ), m_hItem( hItem ), m_pItemManager( pItemManager ) { CGenericClassBasedReplay *pReplay = GetReplay(); IQueryableReplayItem *pItem = pItemManager->GetItem( hItem ); // Setup class image char szImage[MAX_OSPATH]; m_pClassImage = new ImagePanel( this, "ClassImage" ); V_snprintf( szImage, sizeof( szImage ), "class_sel_sm_%s_%s", pReplay->GetMaterialFriendlyPlayerClass(), pReplay->GetPlayerTeam() ); // Cause default image to display m_pClassImage->SetImage( szImage ); m_pInfoPanel = new vgui::EditablePanel( this, "InfoPanel" ); // Setup map label const char *pMapName = pReplay->m_szMapName; const char *pUnderscore = V_strstr( pMapName, "_" ); if ( pUnderscore ) { pMapName = pUnderscore + 1; } m_pMapLabel = new CExLabel( m_pInfoPanel, "MapLabel", pMapName ); // Setup record date/time const CReplayTime &RecordTime = pItem->GetItemDate(); int nDay, nMonth, nYear; RecordTime.GetDate( nDay, nMonth, nYear ); int nHour, nMin, nSec; RecordTime.GetTime( nHour, nMin, nSec ); const wchar_t *pDateAndTime = CReplayTime::GetLocalizedDate( g_pVGuiLocalize, nDay, nMonth, nYear, &nHour, &nMin, &nSec ); // Setup date / time label m_pDateTimeLabel = new CExLabel( m_pInfoPanel, "DateTimeLabel", pDateAndTime ); // Setup info labels for ( int i = 0; i < NUM_INFO_LABELS; ++i ) { for ( int j = 0; j < 2; ++j ) { m_pReplayInfoLabels[i][j] = new CExLabel( m_pInfoPanel, VarArgs("Label%d_%d", i, j), "" ); } } m_pReplayInfoLabels[ LABEL_PLAYED_AS ][1]->SetText( pReplay->GetPlayerClass() ); m_pReplayInfoLabels[ LABEL_KILLED_BY ][1]->SetText( pReplay->WasKilled() ? pReplay->GetKillerName() : "#Replay_NoKiller" ); m_pReplayInfoLabels[ LABEL_LIFE_LENGTH ][1]->SetText( CReplayTime::FormatTimeString( (int)pItem->GetItemLength() ) ); } CReplayPreviewPanelBase::~CReplayPreviewPanelBase() { } void CReplayPreviewPanelBase::ApplySchemeSettings( IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme ); LoadControlSettings( "resource/ui/replaybrowser/previewpanel.res", "GAME" ); #if !defined( TF_CLIENT_DLL ) m_pClassImage->SetVisible( false ); #endif } void CReplayPreviewPanelBase::PerformLayout() { BaseClass::PerformLayout(); CGenericClassBasedReplay *pReplay = GetReplay(); if ( !pReplay ) return; int nWide = XRES(18); int nTall = YRES(18); int nScreenshotH = 0; // Represents the height of the screenshot OR the "no screenshot" label LayoutView( nWide, nTall, nScreenshotH ); int iInfoHeight = m_pInfoPanel->GetTall(); nTall += iInfoHeight; if ( m_pClassImage ) { int w, h; m_pClassImage->GetImage()->GetContentSize( w, h ); float s = ShoudlUseLargeClassImage() ? 1.25f : 1.0f; int nClassTall = s*h; m_pClassImage->SetSize( s*w, nClassTall ); m_pClassImage->SetShouldScaleImage( true ); m_pClassImage->SetScaleAmount( s ); // The panel should be at least as tall as the height of the screenshot // (or "no screenshot" label) and the class image. if ( nTall < nClassTall ) { nTall = nClassTall; } m_pClassImage->SetPos( XRES(9), nTall - nClassTall ); } const int nLabelX = m_pClassImage->GetWide() + XRES( 18 ); int iInfoWidth = nWide - nLabelX; m_pMapLabel->SetSize( iInfoWidth, m_pMapLabel->GetTall() ); m_pDateTimeLabel->SetSize( iInfoWidth, m_pMapLabel->GetTall() ); m_pInfoPanel->SetBounds( nLabelX, nTall - iInfoHeight, iInfoWidth, iInfoHeight ); nTall += YRES(9); SetSize( nWide, nTall ); } void CReplayPreviewPanelBase::LayoutView( int &nWide, int &nTall, int &nCurY ) { nWide = XRES( 188 ); nTall = YRES(9); nCurY = nTall; } CGenericClassBasedReplay *CReplayPreviewPanelBase::GetReplay() { return ToGenericClassBasedReplay( m_pItemManager->GetItem( m_hItem )->GetItemReplay() ); } ReplayHandle_t CReplayPreviewPanelBase::GetReplayHandle() { return GetReplay()->GetHandle(); } //----------------------------------------------------------------------------- CReplayPreviewPanelSlideshow::CReplayPreviewPanelSlideshow( Panel *pParent, QueryableReplayItemHandle_t hReplay, IReplayItemManager *pItemManager ) : BaseClass( pParent, hReplay, pItemManager ), m_pScreenshotPanel( NULL ) { // Setup screenshot slideshow panel CGenericClassBasedReplay *pReplay = GetReplay(); const int nScreenshotCount = pReplay->GetScreenshotCount(); if ( nScreenshotCount ) { m_pScreenshotPanel = new CReplayScreenshotSlideshowPanel( this, "ScreenshotSlideshowPanel", hReplay ); // Set pretty quick transition times based on the screenshot count m_pScreenshotPanel->SetInterval( ( nScreenshotCount == 2 ) ? 3.0f : 2.0f ); m_pScreenshotPanel->SetTransitionTime( 0.5f ); } // Setup the no screenshot label m_pNoScreenshotLabel = new CExLabel( this, "NoScreenshotLabel", "#Replay_NoScreenshot" ); m_pNoScreenshotLabel->SetVisible( false ); } void CReplayPreviewPanelSlideshow::PerformLayout() { BaseClass::PerformLayout(); m_pNoScreenshotLabel->SizeToContents(); m_pNoScreenshotLabel->SetWide( GetWide() ); } void CReplayPreviewPanelSlideshow::LayoutView( int &nWide, int &nTall, int &nCurY ) { if ( m_pScreenshotPanel ) { // Use the dimensions from the first screenshot to figure out the scale, even though the dimensions // may vary if the user changed resolutions during gameplay CGenericClassBasedReplay *pReplay = GetReplay(); const CReplayScreenshot *pScreenshot = pReplay->GetScreenshot( 0 ); int nScreenshotW = pScreenshot->m_nWidth; int nScreenshotH = pScreenshot->m_nHeight; // Scale the screenshot if it's too big for the current resolution float flScreenshotScale = 1.0f; int nMaxScreenshotWidth = ScreenWidth() / 3; if ( nScreenshotW > nMaxScreenshotWidth ) { flScreenshotScale = (float)nMaxScreenshotWidth / pScreenshot->m_nWidth; nScreenshotW = nMaxScreenshotWidth; } nCurY = nScreenshotH * flScreenshotScale; m_pScreenshotPanel->GetImagePanel()->SetShouldScaleImage( true ); m_pScreenshotPanel->GetImagePanel()->SetScaleAmount( flScreenshotScale ); nWide += nScreenshotW; nTall += nCurY; m_pScreenshotPanel->SetBounds( (nWide - nScreenshotW) * 0.5, YRES(9), nScreenshotW, nCurY ); } else { int w, h; m_pNoScreenshotLabel->SetContentAlignment( Label::a_center ); m_pNoScreenshotLabel->GetContentSize( w, h ); nTall += YRES( 20 ); m_pNoScreenshotLabel->SetBounds( 0, nTall, w, h ); nTall += YRES( 20 ); m_pNoScreenshotLabel->SetVisible( true ); nWide += XRES( 213 ); // Default width (maps to 640 on 1920x1200) nTall += h; nCurY = nTall; } } //----------------------------------------------------------------------------- CReplayPreviewPanelMovie::CReplayPreviewPanelMovie( Panel *pParent, QueryableReplayItemHandle_t hItem, IReplayItemManager *pItemManager ) : BaseClass( pParent, hItem, pItemManager ), m_pMoviePlayerPanel( NULL ) { m_flCreateTime = gpGlobals->realtime; ivgui()->AddTickSignal( GetVPanel(), 10 ); } CReplayPreviewPanelMovie::~CReplayPreviewPanelMovie() { ivgui()->RemoveTickSignal( GetVPanel() ); } void CReplayPreviewPanelMovie::OnTick() { if ( gpGlobals->realtime >= m_flCreateTime + 0.5f ) { if ( !m_pMoviePlayerPanel ) { m_pMoviePlayerPanel = new CMoviePlayerPanel( this, "MoviePlayer", GetReplayMovie()->GetMovieFilename() ); InvalidateLayout( true, false ); } if ( !m_pMoviePlayerPanel->IsPlaying() ) { m_pMoviePlayerPanel->SetLooping( true ); m_pMoviePlayerPanel->Play(); } } } IReplayMovie* CReplayPreviewPanelMovie::GetReplayMovie() { return static_cast< IReplayMovie * >( m_pItemManager->GetItem( m_hItem ) ); } void CReplayPreviewPanelMovie::LayoutView( int &nWide, int &nTall, int &nCurY ) { // Get frame dimensions int nFrameWidth, nFrameHeight; IReplayMovie* pReplayMovie = GetReplayMovie(); pReplayMovie->GetFrameDimensions( nFrameWidth, nFrameHeight ); int nScaledWidth = nFrameWidth; int nScaledHeight = nFrameHeight; // Scale the screenshot if it's too big for the current resolution float flScale = 1.0f; int nMaxWidth = ScreenWidth() / 3; if ( nFrameWidth > nMaxWidth ) { flScale = (float)nMaxWidth / nFrameWidth; nScaledWidth = nMaxWidth; nScaledHeight = nFrameHeight * flScale; } nWide += nScaledWidth; nTall += nScaledHeight; nCurY = nTall; // Layout movie player panel if it's ready if ( m_pMoviePlayerPanel ) { m_pMoviePlayerPanel->SetBounds( 9, 9, nScaledWidth, nScaledHeight ); m_pMoviePlayerPanel->SetEnabled( true ); m_pMoviePlayerPanel->SetVisible( true ); m_pMoviePlayerPanel->SetZPos( 101 ); } } #endif