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.

199 lines
6.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <assert.h>
  8. #include <math.h>
  9. #include <stdio.h>
  10. #include <vgui_controls/RotatingProgressBar.h>
  11. #include <vgui/IVGui.h>
  12. #include <vgui/ILocalize.h>
  13. #include <vgui/IScheme.h>
  14. #include <vgui/ISurface.h>
  15. #include <KeyValues.h>
  16. #include "mathlib/mathlib.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include <tier0/memdbgon.h>
  19. using namespace vgui;
  20. DECLARE_BUILD_FACTORY( RotatingProgressBar );
  21. //-----------------------------------------------------------------------------
  22. // Purpose: Constructor
  23. //-----------------------------------------------------------------------------
  24. RotatingProgressBar::RotatingProgressBar(Panel *parent, const char *panelName) : ProgressBar(parent, panelName)
  25. {
  26. m_flStartRadians = 0;
  27. m_flEndRadians = 0;
  28. m_flLastAngle = 0;
  29. m_nTextureId = -1;
  30. m_pszImageName = NULL;
  31. m_flTickDelay = 30;
  32. ivgui()->AddTickSignal(GetVPanel(), m_flTickDelay );
  33. SetPaintBorderEnabled(false);
  34. }
  35. //-----------------------------------------------------------------------------
  36. // Purpose: Destructor
  37. //-----------------------------------------------------------------------------
  38. RotatingProgressBar::~RotatingProgressBar()
  39. {
  40. if ( vgui::surface() && m_nTextureId != -1 )
  41. {
  42. vgui::surface()->DestroyTextureID( m_nTextureId );
  43. m_nTextureId = -1;
  44. }
  45. delete [] m_pszImageName;
  46. }
  47. //-----------------------------------------------------------------------------
  48. // Purpose:
  49. //-----------------------------------------------------------------------------
  50. void RotatingProgressBar::ApplySettings(KeyValues *inResourceData)
  51. {
  52. const char *imageName = inResourceData->GetString("image", "");
  53. if (*imageName)
  54. {
  55. SetImage( imageName );
  56. }
  57. // Find min and max rotations in radians
  58. m_flStartRadians = DEG2RAD(inResourceData->GetFloat( "start_degrees", 0 ) );
  59. m_flEndRadians = DEG2RAD( inResourceData->GetFloat( "end_degrees", 0 ) );
  60. // Start at 0 progress
  61. m_flLastAngle = m_flStartRadians;
  62. // approach speed is specified in degrees per second.
  63. // convert to radians per 1/30th of a second
  64. float flDegressPerSecond = DEG2RAD( inResourceData->GetFloat( "approach_speed", 360.0 ) ); // default is super fast
  65. m_flApproachSpeed = flDegressPerSecond * ( m_flTickDelay / 1000.0f ); // divide by number of frames in a second
  66. m_flRotOriginX = inResourceData->GetFloat( "rot_origin_x_percent", 0.5f );
  67. m_flRotOriginY = inResourceData->GetFloat( "rot_origin_y_percent", 0.5f );
  68. m_flRotatingX = inResourceData->GetFloat( "rotating_x", 0 );
  69. m_flRotatingY = inResourceData->GetFloat( "rotating_y", 0 );
  70. m_flRotatingWide = inResourceData->GetFloat( "rotating_wide", 0 );
  71. m_flRotatingTall = inResourceData->GetFloat( "rotating_tall", 0 );
  72. BaseClass::ApplySettings( inResourceData );
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose:
  76. //-----------------------------------------------------------------------------
  77. void RotatingProgressBar::ApplySchemeSettings(IScheme *pScheme)
  78. {
  79. BaseClass::ApplySchemeSettings(pScheme);
  80. if ( m_pszImageName && strlen( m_pszImageName ) > 0 )
  81. {
  82. if ( m_nTextureId == -1 )
  83. {
  84. m_nTextureId = surface()->CreateNewTextureID();
  85. }
  86. surface()->DrawSetTextureFile( m_nTextureId, m_pszImageName, true, false);
  87. }
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose: sets an image by file name
  91. //-----------------------------------------------------------------------------
  92. void RotatingProgressBar::SetImage(const char *imageName)
  93. {
  94. if ( m_pszImageName )
  95. {
  96. delete [] m_pszImageName;
  97. m_pszImageName = NULL;
  98. }
  99. const char *pszDir = "vgui/";
  100. int len = Q_strlen(imageName) + 1;
  101. len += strlen(pszDir);
  102. m_pszImageName = new char[ len ];
  103. Q_snprintf( m_pszImageName, len, "%s%s", pszDir, imageName );
  104. InvalidateLayout(false, true); // force applyschemesettings to run
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose:
  108. //-----------------------------------------------------------------------------
  109. void RotatingProgressBar::PaintBackground()
  110. {
  111. // No background
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Purpose: Update event when we aren't drawing so we don't get huge sweeps
  115. // when we start drawing it
  116. //-----------------------------------------------------------------------------
  117. void RotatingProgressBar::OnTick( void )
  118. {
  119. float flDesiredAngle = RemapVal( GetProgress(), 0.0, 1.0, m_flStartRadians, m_flEndRadians );
  120. m_flLastAngle = Approach( flDesiredAngle, m_flLastAngle, m_flApproachSpeed );
  121. BaseClass::OnTick();
  122. }
  123. //-----------------------------------------------------------------------------
  124. // Purpose:
  125. //-----------------------------------------------------------------------------
  126. void RotatingProgressBar::Paint()
  127. {
  128. // we have an image that we rotate based on the progress,
  129. // where '0' is not rotated,'90' is rotated 90 degrees to the right.
  130. // Image is rotated around its center.
  131. // desired rotation is GetProgress() ( 0.0 -> 1.0 ) mapped into
  132. // ( m_flStartDegrees -> m_flEndDegrees )
  133. vgui::surface()->DrawSetTexture( m_nTextureId );
  134. vgui::surface()->DrawSetColor( Color(255,255,255,255) );
  135. int wide, tall;
  136. GetSize( wide, tall );
  137. float mid_x = m_flRotatingX + m_flRotOriginX * m_flRotatingWide;
  138. float mid_y = m_flRotatingY + m_flRotOriginY * m_flRotatingTall;
  139. Vertex_t vert[4];
  140. vert[0].Init( Vector2D( m_flRotatingX, m_flRotatingY ), Vector2D(0,0) );
  141. vert[1].Init( Vector2D( m_flRotatingX+m_flRotatingWide, m_flRotatingY ), Vector2D(1,0) );
  142. vert[2].Init( Vector2D( m_flRotatingX+m_flRotatingWide, m_flRotatingY+m_flRotatingTall ), Vector2D(1,1) );
  143. vert[3].Init( Vector2D( m_flRotatingX, m_flRotatingY+m_flRotatingTall ), Vector2D(0,1) );
  144. float flCosA = cos(m_flLastAngle);
  145. float flSinA = sin(m_flLastAngle);
  146. // rotate each point around (mid_x, mid_y) by flAngle radians
  147. for ( int i=0;i<4;i++ )
  148. {
  149. Vector2D result;
  150. // subtract the (x,y) we're rotating around, we'll add it on at the end.
  151. vert[i].m_Position.x -= mid_x;
  152. vert[i].m_Position.y -= mid_y;
  153. result.x = ( vert[i].m_Position.x * flCosA - vert[i].m_Position.y * flSinA ) + mid_x;
  154. result.y = ( vert[i].m_Position.x * flSinA + vert[i].m_Position.y * flCosA ) + mid_y;
  155. vert[i].m_Position = result;
  156. }
  157. vgui::surface()->DrawTexturedPolygon( 4, vert );
  158. }