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.

443 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "vgui_basebudgetpanel.h"
  7. #include "vgui_controls/Label.h"
  8. // memdbgon must be the last include file in a .cpp file!!!
  9. #include "tier0/memdbgon.h"
  10. CBaseBudgetPanel::CBaseBudgetPanel( vgui::Panel *pParent, const char *pElementName )
  11. : vgui::Panel( pParent, pElementName )
  12. {
  13. m_BudgetHistoryOffset = 0;
  14. SetProportional( false );
  15. SetKeyBoardInputEnabled( false );
  16. SetMouseInputEnabled( false );
  17. SetVisible( true );
  18. // set the scheme before any child control is created
  19. vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFile("resource/SourceScheme.res", "Client");
  20. SetScheme( scheme );
  21. m_pBudgetHistoryPanel = NULL;
  22. m_pBudgetBarGraphPanel = NULL;
  23. SetZPos( 1001 );
  24. m_bDedicated = false;
  25. }
  26. CBaseBudgetPanel::~CBaseBudgetPanel()
  27. {
  28. }
  29. float CBaseBudgetPanel::GetBudgetGroupPercent( float value )
  30. {
  31. if ( m_ConfigData.m_flBarGraphRange == 0.0f )
  32. return 1.0f;
  33. return value / m_ConfigData.m_flBarGraphRange;
  34. }
  35. const double *CBaseBudgetPanel::GetBudgetGroupData( int &nGroups, int &nSamplesPerGroup, int &nSampleOffset ) const
  36. {
  37. nGroups = m_ConfigData.m_BudgetGroupInfo.Count();
  38. nSamplesPerGroup = BUDGET_HISTORY_COUNT;
  39. nSampleOffset = m_BudgetHistoryOffset;
  40. if( m_BudgetGroupTimes.Count() == 0 )
  41. {
  42. return NULL;
  43. }
  44. else
  45. {
  46. return &m_BudgetGroupTimes[0].m_Time[0];
  47. }
  48. }
  49. void CBaseBudgetPanel::ClearTimesForAllGroupsForThisFrame( void )
  50. {
  51. int i;
  52. for( i = 0; i < m_ConfigData.m_BudgetGroupInfo.Count(); i++ )
  53. {
  54. m_BudgetGroupTimes[i].m_Time[m_BudgetHistoryOffset] = 0.0;
  55. }
  56. }
  57. void CBaseBudgetPanel::ClearAllTimesForGroup( int groupID )
  58. {
  59. int i;
  60. for( i = 0; i < BUDGET_HISTORY_COUNT; i++ )
  61. {
  62. m_BudgetGroupTimes[groupID].m_Time[i] = 0.0;
  63. }
  64. }
  65. void CBaseBudgetPanel::OnConfigDataChanged( const CBudgetPanelConfigData &data )
  66. {
  67. int oldNumGroups = m_ConfigData.m_BudgetGroupInfo.Count();
  68. // Copy in the config data and rebuild everything.
  69. Rebuild( data );
  70. if ( m_ConfigData.m_BudgetGroupInfo.Count() > m_BudgetGroupTimes.Count() )
  71. {
  72. m_BudgetGroupTimes.EnsureCount( m_ConfigData.m_BudgetGroupInfo.Count() );
  73. for ( int i = oldNumGroups; i < m_ConfigData.m_BudgetGroupInfo.Count(); i++ )
  74. {
  75. ClearAllTimesForGroup( i );
  76. }
  77. }
  78. else
  79. {
  80. m_BudgetGroupTimes.SetSize( m_ConfigData.m_BudgetGroupInfo.Count() );
  81. for ( int i = 0; i < m_BudgetGroupTimes.Count(); i++ )
  82. {
  83. ClearAllTimesForGroup( i );
  84. }
  85. }
  86. InvalidateLayout( false, true );
  87. }
  88. void CBaseBudgetPanel::ResetAll()
  89. {
  90. m_ConfigData.m_BudgetGroupInfo.Purge();
  91. for ( int i=0; i < m_GraphLabels.Count(); i++ )
  92. m_GraphLabels[i]->MarkForDeletion();
  93. m_GraphLabels.Purge();
  94. for ( int i=0; i < m_TimeLabels.Count(); i++ )
  95. m_TimeLabels[i]->MarkForDeletion();
  96. m_TimeLabels.Purge();
  97. }
  98. void CBaseBudgetPanel::Rebuild( const CBudgetPanelConfigData &data )
  99. {
  100. int oldNumBudgetGroups = m_ConfigData.m_BudgetGroupInfo.Count();
  101. int oldNumHistoryLabels = m_ConfigData.m_HistoryLabelValues.Count();
  102. int oldNumTimeLabels = m_TimeLabels.Count();
  103. // Copy the new config in.
  104. m_ConfigData = data;
  105. int nParentWidth, nParentHeight;
  106. GetParent()->GetSize( nParentWidth, nParentHeight );
  107. if ( m_ConfigData.m_Width > nParentWidth )
  108. {
  109. m_ConfigData.m_Width = nParentWidth;
  110. }
  111. if ( m_ConfigData.m_Height > nParentHeight )
  112. {
  113. m_ConfigData.m_Height = nParentHeight;
  114. }
  115. if ( m_ConfigData.m_xCoord + m_ConfigData.m_Width > nParentWidth )
  116. {
  117. m_ConfigData.m_xCoord = nParentWidth - m_ConfigData.m_Width;
  118. }
  119. if ( m_ConfigData.m_yCoord + m_ConfigData.m_Height > nParentHeight )
  120. {
  121. m_ConfigData.m_yCoord = nParentHeight - m_ConfigData.m_Height;
  122. }
  123. // Recreate the history and bar graph panels.
  124. if( m_pBudgetHistoryPanel )
  125. {
  126. m_pBudgetHistoryPanel->MarkForDeletion();
  127. }
  128. m_pBudgetHistoryPanel = new CBudgetHistoryPanel( this, "FrametimeHistory" );
  129. if( m_pBudgetBarGraphPanel )
  130. {
  131. m_pBudgetBarGraphPanel->MarkForDeletion();
  132. }
  133. m_pBudgetBarGraphPanel = new CBudgetBarGraphPanel( this, "BudgetBarGraph" );
  134. // Create any new labels we need.
  135. int i;
  136. if ( m_ConfigData.m_BudgetGroupInfo.Count() > m_GraphLabels.Count() )
  137. {
  138. m_GraphLabels.EnsureCount( m_ConfigData.m_BudgetGroupInfo.Count() );
  139. for( i = oldNumBudgetGroups; i < m_ConfigData.m_BudgetGroupInfo.Count(); i++ )
  140. {
  141. const char *pBudgetGroupName = m_ConfigData.m_BudgetGroupInfo[i].m_Name.String();
  142. m_GraphLabels[i] = new vgui::Label( this, pBudgetGroupName, pBudgetGroupName );
  143. }
  144. }
  145. else
  146. {
  147. while ( m_GraphLabels.Count() > m_ConfigData.m_BudgetGroupInfo.Count() )
  148. {
  149. m_GraphLabels[m_GraphLabels.Count()-1]->MarkForDeletion();
  150. m_GraphLabels.Remove( m_GraphLabels.Count()-1 );
  151. }
  152. }
  153. Assert( m_GraphLabels.Count() == m_ConfigData.m_BudgetGroupInfo.Count() );
  154. // Create new history labels.
  155. if ( m_ConfigData.m_HistoryLabelValues.Count() > m_HistoryLabels.Count() )
  156. {
  157. m_HistoryLabels.EnsureCount( m_ConfigData.m_HistoryLabelValues.Count() );
  158. for ( i=oldNumHistoryLabels; i < m_HistoryLabels.Count(); i++ )
  159. {
  160. m_HistoryLabels[i] = new vgui::Label( this, "history label", "history label" );
  161. }
  162. }
  163. else
  164. {
  165. while ( m_HistoryLabels.Count() > m_ConfigData.m_HistoryLabelValues.Count() )
  166. {
  167. m_HistoryLabels[m_HistoryLabels.Count()-1]->MarkForDeletion();
  168. m_HistoryLabels.Remove( m_HistoryLabels.Count()-1 );
  169. }
  170. }
  171. SetHistoryLabelText();
  172. // Note: the time lines still use milliseconds for the computations about where to draw them,
  173. // but each BudgetGroupDataType_t has its own scale.
  174. int nTimeLabels = m_ConfigData.m_flBarGraphRange + data.m_flTimeLabelInterval;
  175. if ( data.m_flTimeLabelInterval != 0.0f )
  176. {
  177. nTimeLabels /= data.m_flTimeLabelInterval;
  178. }
  179. if ( nTimeLabels > m_TimeLabels.Count() )
  180. {
  181. m_TimeLabels.EnsureCount( nTimeLabels );
  182. for( i = oldNumTimeLabels; i < m_TimeLabels.Count(); i++ )
  183. {
  184. char name[1024];
  185. Q_snprintf( name, sizeof( name ), "time_label_%d", i );
  186. m_TimeLabels[i] = new vgui::Label( this, name, "TEXT NOT SET YET" );
  187. }
  188. }
  189. else
  190. {
  191. while ( m_TimeLabels.Count() > nTimeLabels )
  192. {
  193. m_TimeLabels[m_TimeLabels.Count()-1]->MarkForDeletion();
  194. m_TimeLabels.Remove( m_TimeLabels.Count()-1 );
  195. }
  196. }
  197. SetTimeLabelText();
  198. }
  199. void CBaseBudgetPanel::UpdateWindowGeometry()
  200. {
  201. if( m_ConfigData.m_Width > BUDGET_HISTORY_COUNT )
  202. {
  203. m_ConfigData.m_Width = BUDGET_HISTORY_COUNT;
  204. }
  205. SetPos( m_ConfigData.m_xCoord, m_ConfigData.m_yCoord );
  206. SetSize( m_ConfigData.m_Width, m_ConfigData.m_Height );
  207. }
  208. void CBaseBudgetPanel::PerformLayout()
  209. {
  210. if ( !m_pBudgetHistoryPanel || !m_pBudgetBarGraphPanel )
  211. return;
  212. int maxFPSLabelWidth = 0;
  213. int i;
  214. for( i = 0; i < m_HistoryLabels.Count(); i++ )
  215. {
  216. int labelWidth, labelHeight;
  217. m_HistoryLabels[i]->GetContentSize( labelWidth, labelHeight );
  218. if( labelWidth > maxFPSLabelWidth )
  219. {
  220. maxFPSLabelWidth = labelWidth;
  221. }
  222. }
  223. m_pBudgetHistoryPanel->SetRange( 0, m_ConfigData.m_flHistoryRange );
  224. float bottomOfHistoryPercentage = m_ConfigData.m_flBottomOfHistoryFraction;
  225. UpdateWindowGeometry();
  226. int x, y, totalWidth, totalHeight;
  227. int totalHeightMinusTimeLabels;
  228. GetPos( x, y );
  229. GetSize( totalWidth, totalHeight );
  230. int maxTimeLabelHeight = 0;
  231. for( i = 0; i < m_TimeLabels.Count(); i++ )
  232. {
  233. int labelWidth, labelHeight;
  234. m_TimeLabels[i]->GetContentSize( labelWidth, labelHeight );
  235. maxTimeLabelHeight = max( maxTimeLabelHeight, labelHeight );
  236. }
  237. totalHeightMinusTimeLabels = totalHeight - maxTimeLabelHeight;
  238. m_pBudgetHistoryPanel->SetPos( 0, 0 );
  239. int budgetHistoryHeight = totalHeightMinusTimeLabels * bottomOfHistoryPercentage;
  240. m_pBudgetHistoryPanel->SetSize( totalWidth - maxFPSLabelWidth,
  241. budgetHistoryHeight );
  242. int maxLabelWidth = 0;
  243. for( i = 0; i < m_GraphLabels.Count(); i++ )
  244. {
  245. int width, height;
  246. m_GraphLabels[i]->GetContentSize( width, height );
  247. if( maxLabelWidth < width )
  248. {
  249. maxLabelWidth = width;
  250. }
  251. }
  252. m_pBudgetBarGraphPanel->SetPos( maxLabelWidth,
  253. totalHeightMinusTimeLabels * bottomOfHistoryPercentage );
  254. m_pBudgetBarGraphPanel->SetSize( totalWidth - maxLabelWidth,
  255. totalHeightMinusTimeLabels * ( 1 - bottomOfHistoryPercentage ) );
  256. for( i = 0; i < m_GraphLabels.Count(); i++ )
  257. {
  258. m_GraphLabels[i]->SetPos( 0,
  259. ( bottomOfHistoryPercentage * totalHeightMinusTimeLabels ) +
  260. ( i * totalHeightMinusTimeLabels *
  261. ( 1 - bottomOfHistoryPercentage ) ) / m_ConfigData.m_BudgetGroupInfo.Count() );
  262. // fudge height by 1 for rounding
  263. m_GraphLabels[i]->SetSize( maxLabelWidth, 1 + ( totalHeightMinusTimeLabels *
  264. ( 1 - bottomOfHistoryPercentage ) ) / m_ConfigData.m_BudgetGroupInfo.Count() );
  265. m_GraphLabels[i]->SetContentAlignment( vgui::Label::a_east );
  266. }
  267. // Note: the time lines still use milliseconds for the computations about where to draw them,
  268. // but each BudgetGroupDataType_t has its own scale.
  269. float fRange = m_ConfigData.m_flBarGraphRange;
  270. for( i = 0; i < m_TimeLabels.Count(); i++ )
  271. {
  272. int labelWidth, labelHeight;
  273. m_TimeLabels[i]->GetContentSize( labelWidth, labelHeight );
  274. x = maxLabelWidth + ( i * m_ConfigData.m_flTimeLabelInterval ) / fRange * ( totalWidth - maxLabelWidth );
  275. m_TimeLabels[i]->SetPos( x - ( labelWidth * 0.5 ), totalHeight - labelHeight );
  276. m_TimeLabels[i]->SetSize( labelWidth, labelHeight );
  277. m_TimeLabels[i]->SetContentAlignment( vgui::Label::a_east );
  278. }
  279. // position the fps labels
  280. fRange = m_ConfigData.m_flHistoryRange;
  281. for( i = 0; i < m_HistoryLabels.Count(); i++ )
  282. {
  283. int labelWidth, labelHeight;
  284. m_HistoryLabels[i]->GetContentSize( labelWidth, labelHeight );
  285. y = (fRange != 0) ? budgetHistoryHeight * m_ConfigData.m_HistoryLabelValues[i] / ( float )fRange : 0.0f;
  286. int top = ( int )( budgetHistoryHeight - y - 1 - labelHeight * 0.5f );
  287. m_HistoryLabels[i]->SetPos( totalWidth - maxFPSLabelWidth, top );
  288. m_HistoryLabels[i]->SetSize( labelWidth, labelHeight );
  289. m_HistoryLabels[i]->SetContentAlignment( vgui::Label::a_east );
  290. }
  291. }
  292. void CBaseBudgetPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  293. {
  294. BaseClass::ApplySchemeSettings( pScheme );
  295. int i;
  296. for( i = 0; i < m_ConfigData.m_BudgetGroupInfo.Count(); i++ )
  297. {
  298. m_GraphLabels[i]->SetFgColor( m_ConfigData.m_BudgetGroupInfo[i].m_Color );
  299. m_GraphLabels[i]->SetBgColor( Color( 0, 0, 0, 255 ) );
  300. m_GraphLabels[i]->SetPaintBackgroundEnabled( false );
  301. m_GraphLabels[i]->SetFont( pScheme->GetFont( "BudgetLabel", IsProportional() ) );
  302. if ( m_bDedicated )
  303. {
  304. m_GraphLabels[i]->SetBgColor( pScheme->GetColor( "ControlBG", Color( 0, 0, 0, 255 ) ) );
  305. }
  306. }
  307. for( i = 0; i < m_TimeLabels.Count(); i++ )
  308. {
  309. int red, green, blue, alpha;
  310. red = green = blue = alpha = 255;
  311. m_TimeLabels[i]->SetFgColor( Color( red, green, blue, alpha ) );
  312. m_TimeLabels[i]->SetBgColor( Color( 0, 0, 0, 255 ) );
  313. m_TimeLabels[i]->SetPaintBackgroundEnabled( false );
  314. m_TimeLabels[i]->SetFont( pScheme->GetFont( "BudgetLabel", IsProportional() ) );
  315. if ( m_bDedicated )
  316. {
  317. m_TimeLabels[i]->SetBgColor( pScheme->GetColor( "ControlBG", Color( 0, 0, 0, 255 ) ) );
  318. }
  319. }
  320. for( i = 0; i < m_HistoryLabels.Count(); i++ )
  321. {
  322. int red, green, blue, alpha;
  323. red = green = blue = alpha = 255;
  324. m_HistoryLabels[i]->SetFgColor( Color( red, green, blue, alpha ) );
  325. m_HistoryLabels[i]->SetBgColor( Color( 0, 0, 0, 255 ) );
  326. m_HistoryLabels[i]->SetPaintBackgroundEnabled( false );
  327. m_HistoryLabels[i]->SetFont( pScheme->GetFont( "BudgetLabel", IsProportional() ) );
  328. if ( m_bDedicated )
  329. {
  330. m_HistoryLabels[i]->SetBgColor( pScheme->GetColor( "ControlBG", Color( 0, 0, 0, 255 ) ) );
  331. }
  332. }
  333. m_hFont = pScheme->GetFont( "DefaultFixed" );
  334. if ( m_bDedicated )
  335. {
  336. SetBgColor( pScheme->GetColor( "ControlBG", Color( 0, 0, 0, 255 ) ) );
  337. }
  338. SetPaintBackgroundEnabled( true );
  339. }
  340. void CBaseBudgetPanel::PaintBackground()
  341. {
  342. if ( m_bDedicated )
  343. {
  344. m_pBudgetBarGraphPanel->SetBgColor( GetBgColor() );
  345. }
  346. else
  347. {
  348. SetBgColor( Color( 0, 0, 0, m_ConfigData.m_flBackgroundAlpha ) );
  349. }
  350. BaseClass::PaintBackground();
  351. }
  352. void CBaseBudgetPanel::Paint()
  353. {
  354. m_pBudgetHistoryPanel->SetData( &m_BudgetGroupTimes[0].m_Time[0], GetNumCachedBudgetGroups(), BUDGET_HISTORY_COUNT, m_BudgetHistoryOffset );
  355. BaseClass::Paint();
  356. }
  357. void CBaseBudgetPanel::MarkForFullRepaint()
  358. {
  359. Repaint();
  360. m_pBudgetHistoryPanel->Repaint();
  361. m_pBudgetBarGraphPanel->Repaint();
  362. }
  363. //-----------------------------------------------------------------------------
  364. // Purpose:
  365. //-----------------------------------------------------------------------------
  366. void CBaseBudgetPanel::GetGraphLabelScreenSpaceTopAndBottom( int id, int &top, int &bottom )
  367. {
  368. int x = 0;
  369. int y = 0;
  370. m_GraphLabels[id]->LocalToScreen( x, y );
  371. top = y;
  372. bottom = top + m_GraphLabels[id]->GetTall();
  373. }