Team Fortress 2 Source Code as on 22/4/2020
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.

300 lines
9.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #if defined( REPLAY_ENABLED )
  8. #include "replaybrowserpreviewpanel.h"
  9. #include "replaybrowsermainpanel.h"
  10. #include "replaybrowsermovieplayerpanel.h"
  11. #include "replaybrowserlistitempanel.h"
  12. #include "replay/ireplaymovie.h"
  13. #include "replay/screenshot.h"
  14. #include "vgui/ISurface.h"
  15. #include "econ/econ_controls.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include <tier0/memdbgon.h>
  18. //-----------------------------------------------------------------------------
  19. CReplayPreviewPanelBase::CReplayPreviewPanelBase( Panel *pParent, QueryableReplayItemHandle_t hItem, IReplayItemManager *pItemManager )
  20. : EditablePanel( pParent, "PreviewPanel" ),
  21. m_hItem( hItem ),
  22. m_pItemManager( pItemManager )
  23. {
  24. CGenericClassBasedReplay *pReplay = GetReplay();
  25. IQueryableReplayItem *pItem = pItemManager->GetItem( hItem );
  26. // Setup class image
  27. char szImage[MAX_OSPATH];
  28. m_pClassImage = new ImagePanel( this, "ClassImage" );
  29. V_snprintf( szImage, sizeof( szImage ), "class_sel_sm_%s_%s", pReplay->GetMaterialFriendlyPlayerClass(), pReplay->GetPlayerTeam() ); // Cause default image to display
  30. m_pClassImage->SetImage( szImage );
  31. m_pInfoPanel = new vgui::EditablePanel( this, "InfoPanel" );
  32. // Setup map label
  33. const char *pMapName = pReplay->m_szMapName;
  34. const char *pUnderscore = V_strstr( pMapName, "_" );
  35. if ( pUnderscore )
  36. {
  37. pMapName = pUnderscore + 1;
  38. }
  39. m_pMapLabel = new CExLabel( m_pInfoPanel, "MapLabel", pMapName );
  40. // Setup record date/time
  41. const CReplayTime &RecordTime = pItem->GetItemDate();
  42. int nDay, nMonth, nYear;
  43. RecordTime.GetDate( nDay, nMonth, nYear );
  44. int nHour, nMin, nSec;
  45. RecordTime.GetTime( nHour, nMin, nSec );
  46. const wchar_t *pDateAndTime = CReplayTime::GetLocalizedDate( g_pVGuiLocalize, nDay, nMonth, nYear, &nHour, &nMin, &nSec );
  47. // Setup date / time label
  48. m_pDateTimeLabel = new CExLabel( m_pInfoPanel, "DateTimeLabel", pDateAndTime );
  49. // Setup info labels
  50. for ( int i = 0; i < NUM_INFO_LABELS; ++i )
  51. {
  52. for ( int j = 0; j < 2; ++j )
  53. {
  54. m_pReplayInfoLabels[i][j] = new CExLabel( m_pInfoPanel, VarArgs("Label%d_%d", i, j), "" );
  55. }
  56. }
  57. m_pReplayInfoLabels[ LABEL_PLAYED_AS ][1]->SetText( pReplay->GetPlayerClass() );
  58. m_pReplayInfoLabels[ LABEL_KILLED_BY ][1]->SetText( pReplay->WasKilled() ? pReplay->GetKillerName() : "#Replay_NoKiller" );
  59. m_pReplayInfoLabels[ LABEL_LIFE_LENGTH ][1]->SetText( CReplayTime::FormatTimeString( (int)pItem->GetItemLength() ) );
  60. }
  61. CReplayPreviewPanelBase::~CReplayPreviewPanelBase()
  62. {
  63. }
  64. void CReplayPreviewPanelBase::ApplySchemeSettings( IScheme *pScheme )
  65. {
  66. BaseClass::ApplySchemeSettings( pScheme );
  67. LoadControlSettings( "resource/ui/replaybrowser/previewpanel.res", "GAME" );
  68. #if !defined( TF_CLIENT_DLL )
  69. m_pClassImage->SetVisible( false );
  70. #endif
  71. }
  72. void CReplayPreviewPanelBase::PerformLayout()
  73. {
  74. BaseClass::PerformLayout();
  75. CGenericClassBasedReplay *pReplay = GetReplay();
  76. if ( !pReplay )
  77. return;
  78. int nWide = XRES(18);
  79. int nTall = YRES(18);
  80. int nScreenshotH = 0; // Represents the height of the screenshot OR the "no screenshot" label
  81. LayoutView( nWide, nTall, nScreenshotH );
  82. int iInfoHeight = m_pInfoPanel->GetTall();
  83. nTall += iInfoHeight;
  84. if ( m_pClassImage )
  85. {
  86. int w, h;
  87. m_pClassImage->GetImage()->GetContentSize( w, h );
  88. float s = ShoudlUseLargeClassImage() ? 1.25f : 1.0f;
  89. int nClassTall = s*h;
  90. m_pClassImage->SetSize( s*w, nClassTall );
  91. m_pClassImage->SetShouldScaleImage( true );
  92. m_pClassImage->SetScaleAmount( s );
  93. // The panel should be at least as tall as the height of the screenshot
  94. // (or "no screenshot" label) and the class image.
  95. if ( nTall < nClassTall )
  96. {
  97. nTall = nClassTall;
  98. }
  99. m_pClassImage->SetPos( XRES(9), nTall - nClassTall );
  100. }
  101. const int nLabelX = m_pClassImage->GetWide() + XRES( 18 );
  102. int iInfoWidth = nWide - nLabelX;
  103. m_pMapLabel->SetSize( iInfoWidth, m_pMapLabel->GetTall() );
  104. m_pDateTimeLabel->SetSize( iInfoWidth, m_pMapLabel->GetTall() );
  105. m_pInfoPanel->SetBounds( nLabelX, nTall - iInfoHeight, iInfoWidth, iInfoHeight );
  106. nTall += YRES(9);
  107. SetSize( nWide, nTall );
  108. }
  109. void CReplayPreviewPanelBase::LayoutView( int &nWide, int &nTall, int &nCurY )
  110. {
  111. nWide = XRES( 188 );
  112. nTall = YRES(9);
  113. nCurY = nTall;
  114. }
  115. CGenericClassBasedReplay *CReplayPreviewPanelBase::GetReplay()
  116. {
  117. return ToGenericClassBasedReplay( m_pItemManager->GetItem( m_hItem )->GetItemReplay() );
  118. }
  119. ReplayHandle_t CReplayPreviewPanelBase::GetReplayHandle()
  120. {
  121. return GetReplay()->GetHandle();
  122. }
  123. //-----------------------------------------------------------------------------
  124. CReplayPreviewPanelSlideshow::CReplayPreviewPanelSlideshow( Panel *pParent, QueryableReplayItemHandle_t hReplay, IReplayItemManager *pItemManager )
  125. : BaseClass( pParent, hReplay, pItemManager ),
  126. m_pScreenshotPanel( NULL )
  127. {
  128. // Setup screenshot slideshow panel
  129. CGenericClassBasedReplay *pReplay = GetReplay();
  130. const int nScreenshotCount = pReplay->GetScreenshotCount();
  131. if ( nScreenshotCount )
  132. {
  133. m_pScreenshotPanel = new CReplayScreenshotSlideshowPanel( this, "ScreenshotSlideshowPanel", hReplay );
  134. // Set pretty quick transition times based on the screenshot count
  135. m_pScreenshotPanel->SetInterval( ( nScreenshotCount == 2 ) ? 3.0f : 2.0f );
  136. m_pScreenshotPanel->SetTransitionTime( 0.5f );
  137. }
  138. // Setup the no screenshot label
  139. m_pNoScreenshotLabel = new CExLabel( this, "NoScreenshotLabel", "#Replay_NoScreenshot" );
  140. m_pNoScreenshotLabel->SetVisible( false );
  141. }
  142. void CReplayPreviewPanelSlideshow::PerformLayout()
  143. {
  144. BaseClass::PerformLayout();
  145. m_pNoScreenshotLabel->SizeToContents();
  146. m_pNoScreenshotLabel->SetWide( GetWide() );
  147. }
  148. void CReplayPreviewPanelSlideshow::LayoutView( int &nWide, int &nTall, int &nCurY )
  149. {
  150. if ( m_pScreenshotPanel )
  151. {
  152. // Use the dimensions from the first screenshot to figure out the scale, even though the dimensions
  153. // may vary if the user changed resolutions during gameplay
  154. CGenericClassBasedReplay *pReplay = GetReplay();
  155. const CReplayScreenshot *pScreenshot = pReplay->GetScreenshot( 0 );
  156. int nScreenshotW = pScreenshot->m_nWidth;
  157. int nScreenshotH = pScreenshot->m_nHeight;
  158. // Scale the screenshot if it's too big for the current resolution
  159. float flScreenshotScale = 1.0f;
  160. int nMaxScreenshotWidth = ScreenWidth() / 3;
  161. if ( nScreenshotW > nMaxScreenshotWidth )
  162. {
  163. flScreenshotScale = (float)nMaxScreenshotWidth / pScreenshot->m_nWidth;
  164. nScreenshotW = nMaxScreenshotWidth;
  165. }
  166. nCurY = nScreenshotH * flScreenshotScale;
  167. m_pScreenshotPanel->GetImagePanel()->SetShouldScaleImage( true );
  168. m_pScreenshotPanel->GetImagePanel()->SetScaleAmount( flScreenshotScale );
  169. nWide += nScreenshotW;
  170. nTall += nCurY;
  171. m_pScreenshotPanel->SetBounds( (nWide - nScreenshotW) * 0.5, YRES(9), nScreenshotW, nCurY );
  172. }
  173. else
  174. {
  175. int w, h;
  176. m_pNoScreenshotLabel->SetContentAlignment( Label::a_center );
  177. m_pNoScreenshotLabel->GetContentSize( w, h );
  178. nTall += YRES( 20 );
  179. m_pNoScreenshotLabel->SetBounds( 0, nTall, w, h );
  180. nTall += YRES( 20 );
  181. m_pNoScreenshotLabel->SetVisible( true );
  182. nWide += XRES( 213 ); // Default width (maps to 640 on 1920x1200)
  183. nTall += h;
  184. nCurY = nTall;
  185. }
  186. }
  187. //-----------------------------------------------------------------------------
  188. CReplayPreviewPanelMovie::CReplayPreviewPanelMovie( Panel *pParent, QueryableReplayItemHandle_t hItem, IReplayItemManager *pItemManager )
  189. : BaseClass( pParent, hItem, pItemManager ),
  190. m_pMoviePlayerPanel( NULL )
  191. {
  192. m_flCreateTime = gpGlobals->realtime;
  193. ivgui()->AddTickSignal( GetVPanel(), 10 );
  194. }
  195. CReplayPreviewPanelMovie::~CReplayPreviewPanelMovie()
  196. {
  197. ivgui()->RemoveTickSignal( GetVPanel() );
  198. }
  199. void CReplayPreviewPanelMovie::OnTick()
  200. {
  201. if ( gpGlobals->realtime >= m_flCreateTime + 0.5f )
  202. {
  203. if ( !m_pMoviePlayerPanel )
  204. {
  205. m_pMoviePlayerPanel = new CMoviePlayerPanel( this, "MoviePlayer", GetReplayMovie()->GetMovieFilename() );
  206. InvalidateLayout( true, false );
  207. }
  208. if ( !m_pMoviePlayerPanel->IsPlaying() )
  209. {
  210. m_pMoviePlayerPanel->SetLooping( true );
  211. m_pMoviePlayerPanel->Play();
  212. }
  213. }
  214. }
  215. IReplayMovie* CReplayPreviewPanelMovie::GetReplayMovie()
  216. {
  217. return static_cast< IReplayMovie * >( m_pItemManager->GetItem( m_hItem ) );
  218. }
  219. void CReplayPreviewPanelMovie::LayoutView( int &nWide, int &nTall, int &nCurY )
  220. {
  221. // Get frame dimensions
  222. int nFrameWidth, nFrameHeight;
  223. IReplayMovie* pReplayMovie = GetReplayMovie();
  224. pReplayMovie->GetFrameDimensions( nFrameWidth, nFrameHeight );
  225. int nScaledWidth = nFrameWidth;
  226. int nScaledHeight = nFrameHeight;
  227. // Scale the screenshot if it's too big for the current resolution
  228. float flScale = 1.0f;
  229. int nMaxWidth = ScreenWidth() / 3;
  230. if ( nFrameWidth > nMaxWidth )
  231. {
  232. flScale = (float)nMaxWidth / nFrameWidth;
  233. nScaledWidth = nMaxWidth;
  234. nScaledHeight = nFrameHeight * flScale;
  235. }
  236. nWide += nScaledWidth;
  237. nTall += nScaledHeight;
  238. nCurY = nTall;
  239. // Layout movie player panel if it's ready
  240. if ( m_pMoviePlayerPanel )
  241. {
  242. m_pMoviePlayerPanel->SetBounds( 9, 9, nScaledWidth, nScaledHeight );
  243. m_pMoviePlayerPanel->SetEnabled( true );
  244. m_pMoviePlayerPanel->SetVisible( true );
  245. m_pMoviePlayerPanel->SetZPos( 101 );
  246. }
  247. }
  248. #endif