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.

146 lines
4.8 KiB

  1. //=========== Copyright Valve Corporation, All rights reserved. ===============//
  2. //
  3. // Purpose:
  4. //=============================================================================//
  5. #ifndef UILENGTH_H
  6. #define UILENGTH_H
  7. #ifdef _WIN32
  8. #pragma once
  9. #endif
  10. #include "float.h"
  11. #include "tier0/dbg.h"
  12. #include "tier1/utlvector.h"
  13. #include "mathlib/mathlib.h"
  14. #include "../panorama.h"
  15. namespace panorama
  16. {
  17. //-----------------------------------------------------------------------------
  18. // Purpose: defines
  19. //-----------------------------------------------------------------------------
  20. const float k_flFloatAuto = FLT_MAX;
  21. const float k_flFloatNotSet = FLT_MIN;
  22. // Sometimes we want to say "infinite width/height", but we can't use FLT_MAX as it's "auto"
  23. const float k_flMaxWidthOrHeight = 512000000.0f;
  24. //-----------------------------------------------------------------------------
  25. // Purpose: Represents possible length values
  26. //-----------------------------------------------------------------------------
  27. class CUILength
  28. {
  29. public:
  30. enum EUILengthTypes
  31. {
  32. k_EUILengthUnset,
  33. k_EUILengthLength,
  34. k_EUILengthPercent,
  35. k_EUILengthFitChildren,
  36. k_EUILengthFillParentFlow,
  37. k_EUILengthHeightPercentage,
  38. k_EUILengthWidthPercentage,
  39. };
  40. CUILength() : m_flValue( k_flFloatNotSet ), m_eType( k_EUILengthUnset ) {}
  41. CUILength( float flValue, EUILengthTypes eType ) : m_flValue( flValue ), m_eType( eType ) {}
  42. bool IsSet() const { return (m_eType != k_EUILengthUnset); }
  43. bool IsLength() const { return (m_eType == k_EUILengthLength); }
  44. bool IsPercent() const { return (m_eType == k_EUILengthPercent); }
  45. bool IsFitChildren() const { return (m_eType == k_EUILengthFitChildren); }
  46. bool IsFillParentFlow() const { return (m_eType == k_EUILengthFillParentFlow); }
  47. bool IsHeightPercentage() const { return (m_eType == k_EUILengthHeightPercentage); }
  48. bool IsWidthPercentage() const { return (m_eType == k_EUILengthWidthPercentage); }
  49. float GetValue() const { return m_flValue; }
  50. CUILength::EUILengthTypes GetType() const { return m_eType; }
  51. void SetFitChildren() { Set( k_flFloatAuto, k_EUILengthFitChildren ); }
  52. void SetLength( float flValue ) { Set( flValue, k_EUILengthLength ); }
  53. void SetPercent( float flValue ) { Set( flValue, k_EUILengthPercent ); }
  54. void SetFillParentFlow( float flWeight ) { Set( flWeight, k_EUILengthFillParentFlow ); }
  55. void SetParentFlow( float flValue ) { Set( flValue, k_EUILengthFillParentFlow ); }
  56. void SetHeightPercentage( float flValue ) { Set( flValue, k_EUILengthHeightPercentage ); }
  57. void SetWidthPercentage( float flValue ) { Set( flValue, k_EUILengthWidthPercentage ); }
  58. void Set( float flValue, EUILengthTypes eType )
  59. {
  60. m_flValue = flValue;
  61. m_eType = eType;
  62. }
  63. void ConvertToLength( float flTotalLength )
  64. {
  65. if ( m_eType == k_EUILengthPercent )
  66. Set( GetValueAsLength( flTotalLength ), k_EUILengthLength );
  67. else
  68. Assert( m_eType == k_EUILengthLength || m_eType == k_EUILengthUnset );
  69. }
  70. void ConvertToPercent( float flTotalLength )
  71. {
  72. if ( m_eType == k_EUILengthLength )
  73. Set( m_flValue / flTotalLength * 100.0, k_EUILengthPercent );
  74. else
  75. Assert( m_eType == k_EUILengthPercent || m_eType == k_EUILengthUnset );
  76. }
  77. float GetValueAsLength( float flTotalLength ) const
  78. {
  79. float flRet = m_flValue;
  80. if ( m_eType == k_EUILengthPercent )
  81. flRet = m_flValue * flTotalLength / 100.0;
  82. else
  83. Assert( m_eType == k_EUILengthLength );
  84. return flRet;
  85. }
  86. void ScaleLengthValue( float flScaleFactor )
  87. {
  88. if ( m_eType == k_EUILengthLength && m_flValue != k_flFloatAuto && m_flValue != k_flFloatNotSet )
  89. {
  90. // Don't make width/height values of 1.0 shrink, as things like 1 px horizontal rules will go invisible! Kind of hacky,
  91. // but this mostly works without issue as we have so few things < 1px.
  92. if ( fabsf( 1.0f - fabsf( m_flValue ) ) < 0.1f && flScaleFactor < 1.0f )
  93. {
  94. // Don't need to adjust
  95. }
  96. else
  97. {
  98. // If the original value was pixel aligned, try to keep that. This is important so text doesn't accumulate error layers down
  99. // from us and thus get blurry. Can't apply this rule to all values though as things like a shadow offset of 5.5 can be common
  100. // and the half pixel can be important for the shadow to balance on both sides of the layer.
  101. if ( fabsf( m_flValue - (float)RoundFloatToInt( m_flValue ) ) < 0.001f )
  102. m_flValue = (float)RoundFloatToInt( m_flValue * flScaleFactor );
  103. else
  104. m_flValue = m_flValue * flScaleFactor;
  105. }
  106. }
  107. }
  108. bool operator==( const CUILength &rhs ) const
  109. {
  110. return (m_flValue == rhs.m_flValue && m_eType == rhs.m_eType);
  111. }
  112. bool operator!=( const CUILength &rhs ) const
  113. {
  114. return !(*this == rhs);
  115. }
  116. private:
  117. float m_flValue;
  118. EUILengthTypes m_eType;
  119. };
  120. // Helper for doing lerp on ui length values, converting % and such
  121. CUILength LerpUILength( float flProgress, CUILength start, CUILength end, float flPixelSize );
  122. } // namespace panorama
  123. #endif //UILENGTH_H