summaryrefslogtreecommitdiff
path: root/public/panorama/layout
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /public/panorama/layout
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'public/panorama/layout')
-rw-r--r--public/panorama/layout/backgroundimage.h263
-rw-r--r--public/panorama/layout/csshelpers.h195
-rw-r--r--public/panorama/layout/fillbrush.h993
-rw-r--r--public/panorama/layout/panel2dfactory.h111
-rw-r--r--public/panorama/layout/stylefiletypes.h61
-rw-r--r--public/panorama/layout/stylesymbol.h73
-rw-r--r--public/panorama/layout/uilength.h147
7 files changed, 1843 insertions, 0 deletions
diff --git a/public/panorama/layout/backgroundimage.h b/public/panorama/layout/backgroundimage.h
new file mode 100644
index 0000000..6d3ded4
--- /dev/null
+++ b/public/panorama/layout/backgroundimage.h
@@ -0,0 +1,263 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef BACKGROUNDIMAGE_H
+#define BACKGROUNDIMAGE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "csshelpers.h"
+#include "../data/panoramavideoplayer.h"
+#include "utlstring.h"
+#include "uilength.h"
+
+namespace panorama
+{
+
+class IImageSource;
+class CMovie;
+class CPanel2D;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Background position for background image
+//-----------------------------------------------------------------------------
+class CBackgroundPosition
+{
+public:
+ CBackgroundPosition();
+ ~CBackgroundPosition() {}
+
+
+ EHorizontalAlignment GetHorizontalAlignment() const { return m_eHorizontalAlignment; }
+ CUILength GetHorizontalLength() const { return m_horizontal; }
+ EVerticalAlignment GetVeriticalAlignment() const { return m_eVerticalAlignment; }
+ CUILength GetVerticalLength() const { return m_vertical; }
+
+ bool IsHorizontalSet() const
+ {
+ return ( m_eHorizontalAlignment != k_EHorizontalAlignmentUnset && m_horizontal.IsSet() );
+ }
+
+ bool IsVerticalSet() const
+ {
+ return ( m_eVerticalAlignment != k_EVerticalAlignmentUnset && m_vertical.IsSet() );
+ }
+
+ bool IsSet() const
+ {
+ return ( IsHorizontalSet() && IsVerticalSet() );
+ }
+
+ void Set( EHorizontalAlignment eHorizontal, const CUILength &horizontal, EVerticalAlignment eVertical, const CUILength &vertical );
+ void ResolveDefaultValues();
+ void ToString( CFmtStr1024 *pfmtBuffer );
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ m_horizontal.ScaleLengthValue( flScaleFactor );
+ m_vertical.ScaleLengthValue( flScaleFactor );
+ }
+
+ bool operator==( const CBackgroundPosition &rhs ) const
+ {
+ return ( m_eHorizontalAlignment == rhs.m_eHorizontalAlignment && m_horizontal == rhs.m_horizontal && m_eVerticalAlignment == rhs.m_eVerticalAlignment && m_vertical == rhs.m_vertical );
+ }
+
+ bool operator!=( const CBackgroundPosition &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+private:
+ EHorizontalAlignment m_eHorizontalAlignment;
+ CUILength m_horizontal;
+
+ EVerticalAlignment m_eVerticalAlignment;
+ CUILength m_vertical;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Background images have a repeat in the x & y directions
+//-----------------------------------------------------------------------------
+class CBackgroundRepeat
+{
+public:
+ CBackgroundRepeat() { Set( k_EBackgroundRepeatUnset, k_EBackgroundRepeatUnset ); }
+ ~CBackgroundRepeat() {}
+
+ bool IsSet() const { return (m_eHorizontal != k_EBackgroundRepeatUnset && m_eVertical != k_EBackgroundRepeatUnset); }
+ void Set( EBackgroundRepeat eHorizontal, EBackgroundRepeat eVertical )
+ {
+ m_eHorizontal = eHorizontal;
+ m_eVertical = eVertical;
+ }
+
+ void ResolveDefaultValues()
+ {
+ if ( m_eHorizontal == k_EBackgroundRepeatUnset )
+ m_eHorizontal = k_EBackgroundRepeatRepeat;
+
+ if ( m_eVertical == k_EBackgroundRepeatUnset )
+ m_eVertical = k_EBackgroundRepeatRepeat;
+ }
+
+ EBackgroundRepeat GetHorizontal() const { return m_eHorizontal; }
+ EBackgroundRepeat GetVertical() const { return m_eVertical; }
+
+ bool operator==( const CBackgroundRepeat &rhs ) const
+ {
+ return ( m_eHorizontal == rhs.m_eHorizontal && m_eVertical == rhs.m_eVertical );
+ }
+
+ bool operator!=( const CBackgroundRepeat &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+private:
+ EBackgroundRepeat m_eHorizontal;
+ EBackgroundRepeat m_eVertical;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Can have multiple background image layers, each contains the following
+//-----------------------------------------------------------------------------
+class CBackgroundImageLayer
+{
+private:
+ enum EImagePath
+ {
+ k_EImagePathUnset,
+ k_EImagePathNone,
+ k_EImagePathSet
+ };
+
+public:
+
+ CBackgroundImageLayer();
+ ~CBackgroundImageLayer();
+
+ void SetPathUnset()
+ {
+ m_eImagePath = k_EImagePathUnset;
+ m_sURLPath.Clear();
+ }
+
+ void SetPathToNone()
+ {
+ m_eImagePath = m_eImagePath;
+ m_sURLPath.Clear();
+ }
+
+ void SetPath( const char *pchPath )
+ {
+ m_eImagePath = k_EImagePathSet;
+ m_sURLPath = pchPath;
+ }
+
+ bool IsPathSet() { return (m_eImagePath != k_EImagePathUnset); }
+ bool IsPathNone() { return (m_eImagePath == k_EImagePathNone); }
+ const char *GetPath() { return m_sURLPath.String(); }
+
+ // from background-position
+ const CBackgroundPosition &GetPosition() { return m_position; }
+ void SetPosition( const CBackgroundPosition &position ) { m_position = position; }
+
+ const CUILength &GetWidth() { return m_width; }
+ const CUILength &GetHeight() { return m_height; }
+ void SetBackgroundSize( const CUILength &width, const CUILength &height )
+ {
+ m_width = width;
+ m_height = height;
+ m_eBackgroundSizeConstant = k_EBackgroundSizeConstantNone;
+ }
+
+ EBackgroundSizeConstant GetBackgroundSizeConstant() { return m_eBackgroundSizeConstant; }
+ void SetBackgroundSize( EBackgroundSizeConstant eConstant )
+ {
+ Assert( eConstant != k_EBackgroundSizeConstantNone );
+ m_eBackgroundSizeConstant = eConstant;
+ m_width.SetLength( k_flFloatAuto );
+ m_height.SetLength( k_flFloatAuto );
+ }
+
+ CBackgroundRepeat GetRepeat() { return m_repeat; }
+ void SetRepeat( const CBackgroundRepeat &repeat ) { m_repeat = repeat; }
+
+ IImageSource *GetImage() { return m_pImage; }
+ CVideoPlayerPtr GetMovie() { return m_pVideoPlayer; }
+
+ bool IsCompletelyUnset()
+ {
+ return (m_eImagePath == k_EImagePathUnset && !m_position.IsSet() && !m_width.IsSet() && !m_height.IsSet() && !m_repeat.IsSet() );
+ }
+
+ bool IsSet()
+ {
+ return (m_eImagePath != k_EImagePathUnset && m_position.IsSet() && m_width.IsSet() && m_height.IsSet() && m_repeat.IsSet() );
+ }
+
+ void ResolveDefaultValues();
+ void ApplyUIScaleFactor( float flScaleFactor );
+ void OnAppliedToPanel( IUIPanel *pPanel );
+ void MergeTo( CBackgroundImageLayer *pTarget );
+ void ToString( CFmtStr1024 *pfmtBuffer );
+
+ // comparison operators
+ bool operator==( const CBackgroundImageLayer &rhs ) const
+ {
+ return ( m_eImagePath == rhs.m_eImagePath && m_sURLPath == rhs.m_sURLPath && m_position == rhs.m_position &&
+ m_width == rhs.m_width&& m_height == rhs.m_height && m_repeat == rhs.m_repeat && m_eBackgroundSizeConstant == rhs.m_eBackgroundSizeConstant );
+ }
+
+ bool operator!=( const CBackgroundImageLayer &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+ // helpers for drawing
+ void CalculateFinalDimensions( float *pflWidth, float *pflHeight, float flPanelWidth, float flPanelHeight, float flScaleFactor );
+ void CalculateFinalPosition( float *px, float *py, float flWidthPanel, float flHeightPanel, float flWidthImage, float flHeightImage );
+ void CalculateFinalSpacing( float *px, float *py, float flWidthPanel, float flHeightPanel, float flWidthImage, float flHeightImage );
+
+ void Set( const CBackgroundImageLayer &rhs );
+
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+private:
+ CBackgroundImageLayer( const CBackgroundImageLayer &rhs );
+ CBackgroundImageLayer& operator=( const CBackgroundImageLayer &rhs ) const;
+
+ // from background-image
+ CUtlString m_sURLPath;
+ EImagePath m_eImagePath;
+
+ // from background-position
+ CBackgroundPosition m_position;
+
+ // from background-size
+ EBackgroundSizeConstant m_eBackgroundSizeConstant;
+ CUILength m_width;
+ CUILength m_height;
+
+ // from background-repeat
+ CBackgroundRepeat m_repeat;
+
+ // loaded when applied to a panel
+ IImageSource *m_pImage;
+ CVideoPlayerPtr m_pVideoPlayer;
+};
+
+} // namespace panorama
+
+#endif //BACKGROUNDIMAGE_H
diff --git a/public/panorama/layout/csshelpers.h b/public/panorama/layout/csshelpers.h
new file mode 100644
index 0000000..e18662a
--- /dev/null
+++ b/public/panorama/layout/csshelpers.h
@@ -0,0 +1,195 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef CSSHELPERS_H
+#define CSSHELPERS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "float.h"
+#include "tier0/dbg.h"
+#include "tier1/utlvector.h"
+#include "mathlib/vmatrix.h"
+#include "mathlib/beziercurve.h"
+#include "uilength.h"
+#include "fillbrush.h"
+#include "fmtstr.h"
+#include "../text/iuitextlayout.h"
+#include "panorama/layout/stylesymbol.h"
+
+class CUtlString;
+class Color;
+class CUtlSymbol;
+
+namespace panorama
+{
+
+class CTransform3D;
+class CBackgroundPosition;
+class CBackgroundRepeat;
+
+const char k_rgchCSSDefaultTerm[] = { ' ', ';', '{', '}', ':' };
+const char k_rgchCSSAtRuleNameTerm[] = { ' ', ';', '{', '}' };
+const char k_rgchCSSSelectorTerm[] = { ';', '{', '}' };
+const char k_rgchCSSValueTerm[] = { ';', '{', '}' };
+const char k_rgchCSSValueTermOrEndOfString[] = { ';', '{', '}', '\0' };
+
+//-----------------------------------------------------------------------------
+// Purpose: defines
+//-----------------------------------------------------------------------------
+const int k_nCSSPropertyNameMax = 128;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: string to type routines
+//-----------------------------------------------------------------------------
+const char* PchNameFromEFontWeight( int nValue );
+const char* PchNameFromEFontStyle( int nValue );
+const char* PchNameFromETextAlign( int nValue );
+const char* PchNameFromETextDecoration( int nValue );
+const char *PchNameFromETextTransform( int nValue );
+const char* PchNameFromEAnimationTimingFunction( int nValue );
+const char *PchNameFromEHorizontalAlignment( EHorizontalAlignment eHorizontalAlignment );
+const char *PchNameFromEVerticalAlignment( EVerticalAlignment eVerticalAlignment );
+const char *PchNameFromEContextUIPosition( EContextUIPosition ePosition );
+const char *PchNameFromEBackgroundRepeat( int nValue );
+
+EFontWeight EFontWeightFromName( const char *pchName );
+EFontStyle EFontStyleFromName( const char *pchName );
+ETextAlign ETextAlignFromName( const char *pchName );
+ETextDecoration ETextDecorationFromName( const char *pchName );
+ETextTransform ETextTransformFromName( const char *pchName );
+EAnimationTimingFunction EAnimationTimingFunctionFromName( const char *pchName );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Common functions for dealing with CSS
+//-----------------------------------------------------------------------------
+namespace CSSHelpers
+{
+ bool BParseFillBrushCollection( CFillBrushCollection *pCollection, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseFillBrush( CFillBrush *pBrush, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseGradientColorStop( CGradientColorStop *pColorStop, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseGaussianBlur( float &flPasses, float &flStdDevHorizontal, float &flStdDevVertical, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseColor( Color *pColor, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseRect( CUILength *pTop, CUILength *pRight, CUILength *pBottom, CUILength *pLeft, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseNamedColor( Color *pColor, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseLength( float *pLength, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseNumber( float *pNumber, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseTime( double *pSeconds, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIdent( char *rgchIdent, int cubIdent, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIdentToSymbol( CPanoramaSymbol *pSymbol, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIdentToStyleSymbol( panorama::CStyleSymbol *pSymbol, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseQuotedString( CUtlString &sOutput, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseURL( CUtlString &sPath, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParsePercent( float *pPercent, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIntoUILengthForSizing( CUILength *pLength, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseIntoUILength( CUILength *pLength, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseIntoTwoUILengths( CUILength *pLength1, CUILength *pLength2, const char *pchString, const char **pchAfterParse, float flScalingFactor = 1.0f );
+ bool BParseTimingFunction( EAnimationTimingFunction *peTimingFunction, CCubicBezierCurve< Vector2D > *pCubicBezier, const char *pchString, const char **pchAfterParse );
+ bool BParseAnimationDirectionFunction( EAnimationDirection *peAnimationDirection, const char *pchString, const char **pchAfterParse );
+ bool BParseAngle( float *pDegrees, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseTransformFunction( CTransform3D **pTransform, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseBorderStyle( EBorderStyle *pStyle, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseHorizontalAlignment( EHorizontalAlignment *eHorizontalAlignment, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseVerticalAlignment( EVerticalAlignment *eVerticalAlignment, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseBackgroundPosition( CBackgroundPosition *pPosition, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseBackgroundRepeat( CBackgroundRepeat *pBackgroundRepeat, const char *pchString, const char **pchAfterParse );
+ bool BParseFunctionName( CPanoramaSymbol &symFunctionNameOut, const char *pchString, const char **pchAfterParse = NULL );
+
+ template <typename T> bool BParseCommaSepList( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char ** ), const char *pchString );
+ bool BParseCommaSepList( CUtlVector< EAnimationTimingFunction > *pvec, CUtlVector< CCubicBezierCurve< Vector2D > > *pvec2, bool (*func)( EAnimationTimingFunction *pvec, CCubicBezierCurve< Vector2D > *pvec2, const char *, const char ** ), const char *pchString );
+ template <typename T> bool BParseCommaSepListWithScaling( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char **, float ), const char *pchString, float flScalingFactor );
+
+
+ const char *SkipSpaces( const char *pchString );
+ bool BSkipComma( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipLeftParen( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipRightParen( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipQuote( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipSlash( const char *pchString, const char **pchAfterParse = NULL );
+
+ void AppendUILength( CFmtStr1024 *pfmtBuffer, const CUILength &length );
+ void AppendFloat( CFmtStr1024 *pfmtBuffer, float flValue );
+ void AppendColor( CFmtStr1024 *pfmtBuffer, Color c );
+ void AppendTransform( CFmtStr1024 *pfmtBuffer, CTransform3D *pTransform );
+ void AppendTime( CFmtStr1024 *pfmtBuffer, float flValue );
+ void AppendFillBrushCollection( CFmtStr1024 *pfmtBuffer, const CFillBrushCollection &collection );
+ void AppendFillBrush( CFmtStr1024 *pfmtBuffer, const CFillBrush &brush );
+ void AppendGradientColorStop( CFmtStr1024 *pfmtBuffer, const CGradientColorStop &stops );
+ void AppendURL( CFmtStr1024 *pfmtBuffer, const char *pchURL );
+ void AppendLength( CFmtStr1024 *pfmtBuffer, float flValue );
+
+ bool BParseTrueFalse( const char *pchString, bool *pbValue );
+
+ bool EatCSSComment( CUtlBuffer &buffer );
+ void EatCSSIgnorables( CUtlBuffer &buffer );
+ bool BPeekCSSToken( CUtlBuffer &buffer, char *pchNextChar );
+ bool BReadCSSComment( CUtlBuffer &buffer, char *pchBuffer, uint cubBuffer );
+
+ bool BReadCSSToken( CUtlBuffer &buffer, char *pchToken, uint cubToken );
+ bool BReadCSSToken( CUtlBuffer &buffer, char *pchToken, uint cubToken, const char *pchStopAt, uint cchStopAt );
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper to parse comma separated lists with same value type
+//-----------------------------------------------------------------------------
+template <typename T> bool CSSHelpers::BParseCommaSepList( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char ** ), const char *pchString )
+{
+ while ( *pchString != '\0' )
+ {
+ T val;
+ if ( !func( &val, pchString, &pchString ) )
+ return false;
+
+ pvec->AddToTail( val );
+
+ // done?
+ if ( !CSSHelpers::BSkipComma( pchString, &pchString ) )
+ {
+ // no comma, should be empty string
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if ( pchString[0] != '\0' )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper to parse comma separated lists with same value type
+//-----------------------------------------------------------------------------
+template <typename T> bool CSSHelpers::BParseCommaSepListWithScaling( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char **, float ), const char *pchString, float flScalingFactor )
+{
+ while ( *pchString != '\0' )
+ {
+ T val;
+ if ( !func( &val, pchString, &pchString, flScalingFactor ) )
+ return false;
+
+ pvec->AddToTail( val );
+
+ // done?
+ if ( !CSSHelpers::BSkipComma( pchString, &pchString ) )
+ {
+ // no comma, should be empty string
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if ( pchString[0] != '\0' )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace panorama
+
+
+#endif //CSSHELPERS_H
diff --git a/public/panorama/layout/fillbrush.h b/public/panorama/layout/fillbrush.h
new file mode 100644
index 0000000..97d528b
--- /dev/null
+++ b/public/panorama/layout/fillbrush.h
@@ -0,0 +1,993 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: Classes/types to represent fill brushes of varius types
+//
+//=============================================================================//
+
+#ifndef FILLBRUSH_H
+#define FILLBRUSH_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <float.h>
+#include "color.h"
+#include "utlvector.h"
+#include "uilength.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a gradient color stop value
+//-----------------------------------------------------------------------------
+class CGradientColorStop
+{
+public:
+
+ CGradientColorStop()
+ {
+ m_flPercent = 0.0f;
+ m_color = Color( 0, 0, 0, 0 );
+ }
+
+ CGradientColorStop( float flPercent, Color color )
+ {
+ m_flPercent = clamp( flPercent, 0.0f, 1.0f );
+ m_color = color;
+ }
+
+ void SetPosition( float flPercent )
+ {
+ m_flPercent = clamp( flPercent, 0.0f, 1.0f );
+ }
+
+ void SetColor( Color color )
+ {
+ m_color = color;
+ }
+
+ void SetColor( int r, int g, int b, int a )
+ {
+ m_color.SetColor( r, g, b, a );
+ }
+
+ float GetPosition() const { return m_flPercent; }
+ Color GetColor() const { return m_color; }
+
+ bool operator==( const CGradientColorStop &rhs ) const
+ {
+ return ( m_flPercent == rhs.m_flPercent && m_color == rhs.m_color );
+ }
+
+ bool operator!=( const CGradientColorStop &rhs ) const
+ {
+ return !(*this == rhs);
+ }
+
+private:
+
+ // 0.0->1.0f
+ float m_flPercent;
+
+ // rgba color
+ Color m_color;
+};
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a particle system
+//-----------------------------------------------------------------------------
+class CParticleSystem
+{
+public:
+
+ // Default constructor, sets empty system
+ CParticleSystem()
+ {
+ SetParticleSystem( Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ),
+ Vector( -9999999.0f, -9999999.0f, -9999999.0f ), Vector( 9999999.0f, 9999999.0f, 9999999.0f ),
+ Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ),
+ Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 0 ), Color (0, 0, 0, 0 ), 1.0, 0.0f, 0.0f, 0.0f );
+ }
+
+ CParticleSystem( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance,
+ Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance, float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ SetParticleSystem( vecBasePositon, vecBasePositionVariance, flSize, flSizeVariance, flParticlesPerSecond, flParticlesPerSecondVariance,
+ flLifeSpanSeconds, flLifeSpanSecondsVariance, vecInitialVelocity, vecInitialVelocityVariance, vecVelocityMin, vecVelocityMax,
+ vecGravityAcceleration, vecGravityAccelerationParticleVariance,
+ colorStart, colorStartVariance, colorEnd, colorEndVariance, flSharpness, flSharpnessVariance, flFlicker, flFlickerVariance );
+ }
+
+
+ void SetParticleSystem( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance, Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance,
+ float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ m_vecBasePosition = vecBasePositon;
+ m_vecBasePositionVariance = vecBasePositionVariance;
+
+ m_flParticleSize = flSize;
+ m_flParticleSizeVariance = flSizeVariance;
+
+ m_flParticlesPerSecond = flParticlesPerSecond;
+ m_flParticlesPerSecondVariance = flParticlesPerSecondVariance;
+
+ m_flParticleLifeSpanSeconds = flLifeSpanSeconds;
+ m_flParticleLifeSpanSecondsVariance = flLifeSpanSecondsVariance;
+
+ m_vecParticleInitialVelocity = vecInitialVelocity;
+ m_vecParticleInitialVelocityVariance = vecInitialVelocityVariance;
+
+ m_vecVelocityMin = vecVelocityMin;
+ m_vecVelocityMax = vecVelocityMax;
+
+ m_vecGravityAcceleration = vecGravityAcceleration;
+ m_vecGravityAccelerationParticleVariance = vecGravityAccelerationParticleVariance;
+
+ m_colorStartRGBA = colorStart;
+ m_colorStartRGBAVariance = colorStartVariance;
+
+ m_colorEndRGBA = colorEnd;
+ m_colorEndRGBAVariance = colorEndVariance;
+
+ m_flSharpness = flSharpness;
+ m_flSharpnessVariance = flSharpnessVariance;
+
+ m_flFlicker = flFlicker;
+ m_flFlickerVariance = flFlickerVariance;
+ }
+
+
+ bool operator==( const CParticleSystem &rhs ) const
+ {
+ if ( m_vecBasePosition != rhs.m_vecBasePosition )
+ return false;
+
+ if ( m_vecBasePositionVariance != rhs.m_vecBasePositionVariance )
+ return false;
+
+ if ( m_flParticleSize != rhs.m_flParticleSize )
+ return false;
+
+ if ( m_flParticleSizeVariance != rhs.m_flParticleSizeVariance )
+ return false;
+
+ if ( m_flParticlesPerSecond != rhs.m_flParticlesPerSecond )
+ return false;
+
+ if ( m_flParticlesPerSecondVariance != rhs.m_flParticlesPerSecondVariance )
+ return false;
+
+ if ( m_flParticleLifeSpanSeconds != rhs.m_flParticleLifeSpanSeconds )
+ return false;
+
+ if ( m_flParticleLifeSpanSecondsVariance != rhs.m_flParticleLifeSpanSecondsVariance )
+ return false;
+
+ if ( m_vecParticleInitialVelocity != rhs.m_vecParticleInitialVelocity )
+ return false;
+
+ if ( m_vecParticleInitialVelocityVariance != rhs.m_vecParticleInitialVelocityVariance )
+ return false;
+
+ if ( m_vecGravityAcceleration != rhs.m_vecGravityAcceleration )
+ return false;
+
+ if ( m_vecGravityAccelerationParticleVariance != rhs.m_vecGravityAccelerationParticleVariance )
+ return false;
+
+ if ( m_colorStartRGBA != rhs.m_colorStartRGBA )
+ return false;
+
+ if ( m_colorStartRGBAVariance != rhs.m_colorStartRGBAVariance )
+ return false;
+
+ if ( m_colorEndRGBA != rhs.m_colorEndRGBA )
+ return false;
+
+ if ( m_colorEndRGBAVariance != rhs.m_colorEndRGBAVariance )
+ return false;
+
+ if ( m_flSharpness != rhs.m_flSharpness )
+ return false;
+
+ if ( m_flSharpnessVariance != rhs.m_flSharpnessVariance )
+ return false;
+
+ if ( m_flFlicker != rhs.m_flFlicker )
+ return false;
+
+ if ( m_flFlickerVariance != rhs.m_flFlickerVariance )
+ return false;
+
+ if ( m_vecVelocityMin != rhs.m_vecVelocityMin )
+ return false;
+
+ if ( m_vecVelocityMax != rhs.m_vecVelocityMax )
+ return false;
+
+ return true;
+ }
+
+ void Interpolate( float flProgress, CParticleSystem &target )
+ {
+ m_vecBasePosition.x = Lerp( flProgress, m_vecBasePosition.x, target.m_vecBasePosition.x );
+ m_vecBasePosition.y = Lerp( flProgress, m_vecBasePosition.y, target.m_vecBasePosition.y );
+ m_vecBasePosition.z = Lerp( flProgress, m_vecBasePosition.z, target.m_vecBasePosition.z );
+
+ m_vecBasePositionVariance.x = Lerp( flProgress, m_vecBasePositionVariance.x, target.m_vecBasePositionVariance.x );
+ m_vecBasePositionVariance.y = Lerp( flProgress, m_vecBasePositionVariance.y, target.m_vecBasePositionVariance.y );
+ m_vecBasePositionVariance.z = Lerp( flProgress, m_vecBasePositionVariance.z, target.m_vecBasePositionVariance.z );
+
+ m_flParticleSize = Lerp( flProgress, m_flParticleSize, target.m_flParticleSize );
+ m_flParticleSizeVariance = Lerp( flProgress, m_flParticleSizeVariance, target.m_flParticleSizeVariance );
+
+ m_flParticlesPerSecond = Lerp( flProgress, m_flParticlesPerSecond, target.m_flParticlesPerSecond );
+ m_flParticlesPerSecondVariance = Lerp( flProgress, m_flParticlesPerSecondVariance, target.m_flParticlesPerSecondVariance );
+
+ m_vecParticleInitialVelocity.x = Lerp( flProgress, m_vecParticleInitialVelocity.x, target.m_vecParticleInitialVelocity.x );
+ m_vecParticleInitialVelocity.y = Lerp( flProgress, m_vecParticleInitialVelocity.y, target.m_vecParticleInitialVelocity.y );
+ m_vecParticleInitialVelocity.z = Lerp( flProgress, m_vecParticleInitialVelocity.z, target.m_vecParticleInitialVelocity.z );
+
+ m_vecParticleInitialVelocityVariance.x = Lerp( flProgress, m_vecParticleInitialVelocityVariance.x, target.m_vecParticleInitialVelocityVariance.x );
+ m_vecParticleInitialVelocityVariance.y = Lerp( flProgress, m_vecParticleInitialVelocityVariance.y, target.m_vecParticleInitialVelocityVariance.y );
+ m_vecParticleInitialVelocityVariance.z = Lerp( flProgress, m_vecParticleInitialVelocityVariance.z, target.m_vecParticleInitialVelocityVariance.z );
+
+ m_vecVelocityMin.x = Lerp( flProgress, m_vecVelocityMin.x, target.m_vecVelocityMin.x );
+ m_vecVelocityMin.y = Lerp( flProgress, m_vecVelocityMin.y, target.m_vecVelocityMin.y );
+
+ m_vecVelocityMax.x = Lerp( flProgress, m_vecVelocityMax.x, target.m_vecVelocityMax.x );
+ m_vecVelocityMax.y = Lerp( flProgress, m_vecVelocityMax.y, target.m_vecVelocityMax.y );
+
+ m_vecGravityAcceleration.x = Lerp( flProgress, m_vecGravityAcceleration.x, target.m_vecGravityAcceleration.x );
+ m_vecGravityAcceleration.y = Lerp( flProgress, m_vecGravityAcceleration.y, target.m_vecGravityAcceleration.y );
+ m_vecGravityAcceleration.z = Lerp( flProgress, m_vecGravityAcceleration.z, target.m_vecGravityAcceleration.z );
+
+ m_vecGravityAccelerationParticleVariance.x = Lerp( flProgress, m_vecGravityAccelerationParticleVariance.x, target.m_vecGravityAccelerationParticleVariance.x );
+ m_vecGravityAccelerationParticleVariance.y = Lerp( flProgress, m_vecGravityAccelerationParticleVariance.y, target.m_vecGravityAccelerationParticleVariance.y );
+ m_vecGravityAccelerationParticleVariance.z = Lerp( flProgress, m_vecGravityAccelerationParticleVariance.z, target.m_vecGravityAccelerationParticleVariance.z );
+
+ m_colorStartRGBA.SetColor(
+ Lerp( flProgress, m_colorStartRGBA.r(), target.m_colorStartRGBA.r() ),
+ Lerp( flProgress, m_colorStartRGBA.g(), target.m_colorStartRGBA.g() ),
+ Lerp( flProgress, m_colorStartRGBA.b(), target.m_colorStartRGBA.b() ),
+ Lerp( flProgress, m_colorStartRGBA.a(), target.m_colorStartRGBA.a() )
+ );
+
+ m_colorStartRGBAVariance.SetColor(
+ Lerp( flProgress, m_colorStartRGBAVariance.r(), target.m_colorStartRGBAVariance.r() ),
+ Lerp( flProgress, m_colorStartRGBAVariance.g(), target.m_colorStartRGBAVariance.g() ),
+ Lerp( flProgress, m_colorStartRGBAVariance.b(), target.m_colorStartRGBAVariance.b() ),
+ Lerp( flProgress, m_colorStartRGBAVariance.a(), target.m_colorStartRGBAVariance.a() )
+ );
+
+ m_colorEndRGBA.SetColor(
+ Lerp( flProgress, m_colorEndRGBA.r(), target.m_colorEndRGBA.r() ),
+ Lerp( flProgress, m_colorEndRGBA.g(), target.m_colorEndRGBA.g() ),
+ Lerp( flProgress, m_colorEndRGBA.b(), target.m_colorEndRGBA.b() ),
+ Lerp( flProgress, m_colorEndRGBA.a(), target.m_colorEndRGBA.a() )
+ );
+
+ m_colorEndRGBAVariance.SetColor(
+ Lerp( flProgress, m_colorEndRGBAVariance.r(), target.m_colorEndRGBAVariance.r() ),
+ Lerp( flProgress, m_colorEndRGBAVariance.g(), target.m_colorEndRGBAVariance.g() ),
+ Lerp( flProgress, m_colorEndRGBAVariance.b(), target.m_colorEndRGBAVariance.b() ),
+ Lerp( flProgress, m_colorEndRGBAVariance.a(), target.m_colorEndRGBAVariance.a() )
+ );
+
+ m_flSharpness = Lerp( flProgress, m_flSharpness, target.m_flSharpness );
+ m_flSharpnessVariance = Lerp( flProgress, m_flSharpnessVariance, target.m_flSharpnessVariance );
+
+ m_flFlicker = Lerp( flProgress, m_flFlicker, target.m_flFlicker );
+ m_flFlickerVariance = Lerp( flProgress, m_flFlickerVariance, target.m_flFlickerVariance );
+
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ // Scale all X/Y size/position values
+ m_vecBasePosition.x *= flScaleFactor;
+ m_vecBasePosition.y *= flScaleFactor;
+
+ m_vecBasePositionVariance.x *= flScaleFactor;
+ m_vecBasePositionVariance.y *= flScaleFactor;
+
+ m_flParticleSize *= flScaleFactor;
+ m_flParticleSizeVariance *= flScaleFactor;
+
+ m_vecParticleInitialVelocity.x *= flScaleFactor;
+ m_vecParticleInitialVelocity.y *= flScaleFactor;
+
+ m_vecParticleInitialVelocityVariance.x *= flScaleFactor;
+ m_vecParticleInitialVelocityVariance.y *= flScaleFactor;
+
+ m_vecGravityAcceleration.x *= flScaleFactor;
+ m_vecGravityAcceleration.y *= flScaleFactor;
+
+ m_vecGravityAccelerationParticleVariance.x *= flScaleFactor;
+ m_vecGravityAccelerationParticleVariance.y *= flScaleFactor;
+
+ m_vecVelocityMin.x *= flScaleFactor;
+ m_vecVelocityMin.y *= flScaleFactor;
+
+ m_vecVelocityMax.x *= flScaleFactor;
+ m_vecVelocityMax.y *= flScaleFactor;
+ }
+
+ Vector GetBasePosition() const
+ {
+ return m_vecBasePosition;
+ }
+
+ Vector GetBasePositionVariance() const
+ {
+ return m_vecBasePositionVariance;
+ }
+
+ float GetParticleSize() const
+ {
+ return m_flParticleSize;
+ }
+
+ float GetParticleSizeVariance() const
+ {
+ return m_flParticleSizeVariance;
+ }
+
+ float GetParticlesPerSecond() const
+ {
+ return m_flParticlesPerSecond;
+ }
+
+ float GetParticlesPerSecondVariance() const
+ {
+ return m_flParticlesPerSecondVariance;
+ }
+
+ float GetParticleLifeSpanSeconds() const
+ {
+ return m_flParticleLifeSpanSeconds;
+ }
+
+ float GetParticleLifeSpanSecondsVariance() const
+ {
+ return m_flParticleLifeSpanSecondsVariance;
+ }
+
+ Vector GetParticleInitialVelocity() const
+ {
+ return m_vecParticleInitialVelocity;
+ }
+
+ Vector GetParticleInitialVelocityVariance() const
+ {
+ return m_vecParticleInitialVelocityVariance;
+ }
+
+ Vector GetParticleVelocityMin() const
+ {
+ return m_vecVelocityMin;
+ }
+
+ Vector GetParticleVelocityMax() const
+ {
+ return m_vecVelocityMax;
+ }
+
+ Vector GetGravityAcceleration() const
+ {
+ return m_vecGravityAcceleration;
+ }
+
+ Vector GetGravityAccelerationParticleVariance() const
+ {
+ return m_vecGravityAccelerationParticleVariance;
+ }
+
+ Color GetStartColor() const
+ {
+ return m_colorStartRGBA;
+ }
+
+ Color GetStartColorVariance() const
+ {
+ return m_colorStartRGBAVariance;
+ }
+
+ Color GetEndColor() const
+ {
+ return m_colorEndRGBA;
+ }
+
+ Color GetEndColorVariance() const
+ {
+ return m_colorEndRGBAVariance;
+ }
+
+ float GetSharpness() const
+ {
+ return m_flSharpness;
+ }
+
+ float GetSharpnessVariance() const
+ {
+ return m_flSharpnessVariance;
+ }
+
+ float GetFlicker() const
+ {
+ return m_flFlicker;
+ }
+
+ float GetFlickerVariance() const
+ {
+ return m_flFlickerVariance;
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ }
+#endif
+
+private:
+
+ Vector m_vecBasePosition;
+ Vector m_vecBasePositionVariance;
+
+ float m_flParticleSize;
+ float m_flParticleSizeVariance;
+
+ float m_flParticlesPerSecond;
+ float m_flParticlesPerSecondVariance;
+
+ float m_flParticleLifeSpanSeconds;
+ float m_flParticleLifeSpanSecondsVariance;
+
+ Vector m_vecParticleInitialVelocity;
+ Vector m_vecParticleInitialVelocityVariance;
+
+ Vector m_vecVelocityMin;
+ Vector m_vecVelocityMax;
+
+ Vector m_vecGravityAcceleration;
+ Vector m_vecGravityAccelerationParticleVariance;
+
+ Color m_colorStartRGBA;
+ Color m_colorStartRGBAVariance;
+
+ Color m_colorEndRGBA;
+ Color m_colorEndRGBAVariance;
+
+ float m_flSharpness;
+ float m_flSharpnessVariance;
+
+ float m_flFlicker;
+ float m_flFlickerVariance;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a linear gradient
+//-----------------------------------------------------------------------------
+class CLinearGradient
+{
+public:
+ CLinearGradient()
+ {
+ m_StartPoint[0].SetLength( 0.0 );
+ m_StartPoint[1].SetLength( 0.0 );
+ m_EndPoint[0].SetLength( 0.0 );
+ m_EndPoint[1].SetLength( 0.0 );
+ }
+
+ CLinearGradient( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ SetGradient( StartX, StartY, EndX, EndY, vecStopColors );
+ }
+
+ void SetGradient( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_StartPoint[0] = StartX;
+ m_StartPoint[1] = StartY;
+ m_EndPoint[0] = EndX;
+ m_EndPoint[1] = EndY;
+
+ m_vecStops.AddMultipleToTail( vecStopColors.Count(), vecStopColors.Base() );
+ }
+
+ void SetControlPoints( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY )
+ {
+ m_StartPoint[0] = StartX;
+ m_StartPoint[1] = StartY;
+ m_EndPoint[0] = EndX;
+ m_EndPoint[1] = EndY;
+ }
+
+ void GetStartPoint( CUILength &startX, CUILength &startY ) const
+ {
+ startX = m_StartPoint[0];
+ startY = m_StartPoint[1];
+ }
+
+ void GetEndPoint( CUILength &endX, CUILength &endY ) const
+ {
+ endX = m_EndPoint[0];
+ endY = m_EndPoint[1];
+ }
+
+ const CUtlVector<CGradientColorStop> &AccessStopColors() const
+ {
+ return m_vecStops;
+ }
+
+ CUtlVector<CGradientColorStop> &AccessMutableStopColors()
+ {
+ return m_vecStops;
+ }
+
+ bool operator==( const CLinearGradient &rhs ) const
+ {
+ if ( m_StartPoint[0] != rhs.m_StartPoint[0] || m_StartPoint[1] != rhs.m_StartPoint[1] || m_EndPoint[0] != rhs.m_EndPoint[0] || m_EndPoint[1] != rhs.m_EndPoint[1] )
+ return false;
+
+ if ( m_vecStops.Count() != rhs.m_vecStops.Count() )
+ return false;
+
+ FOR_EACH_VEC( m_vecStops, i )
+ {
+ if ( m_vecStops[i] != rhs.m_vecStops[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ m_StartPoint[0].ScaleLengthValue( flScaleFactor );
+ m_StartPoint[1].ScaleLengthValue( flScaleFactor );
+ m_EndPoint[0].ScaleLengthValue( flScaleFactor );
+ m_EndPoint[1].ScaleLengthValue( flScaleFactor );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecStops );
+ }
+#endif
+
+private:
+
+ // Start/end point determine angle vector
+ CUILength m_StartPoint[2];
+ CUILength m_EndPoint[2];
+ CCopyableUtlVector<CGradientColorStop> m_vecStops;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a radial gradient
+//-----------------------------------------------------------------------------
+class CRadialGradient
+{
+public:
+ CRadialGradient()
+ {
+ m_Center[0].SetLength( 0.0 );
+ m_Center[1].SetLength( 0.0 );
+ m_Offset[0].SetLength( 0.0 );
+ m_Offset[1].SetLength( 0.0 );
+ m_Radius[0].SetLength( 0.0 );
+ m_Radius[1].SetLength( 0.0 );
+ }
+
+ CRadialGradient( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ SetGradient( centerX, centerY, offsetX, offsetY, radiusX, radiusY, vecStopColors );
+ }
+
+ void SetGradient( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_Center[0] = centerX;
+ m_Center[1] = centerY;
+ m_Offset[0] = offsetX;
+ m_Offset[1] = offsetY;
+ m_Radius[0] = radiusX;
+ m_Radius[1] = radiusY;
+
+ m_vecStops.AddMultipleToTail( vecStopColors.Count(), vecStopColors.Base() );
+ }
+
+ void GetCenterPoint( CUILength &centerX, CUILength &centerY ) const
+ {
+ centerX = m_Center[0];
+ centerY = m_Center[1];
+ }
+
+ void GetOffsetDistance( CUILength &offsetX, CUILength &offsetY ) const
+ {
+ offsetX = m_Offset[0];
+ offsetY = m_Offset[1];
+ }
+
+ void GetRadii( CUILength &radiusX, CUILength &radiusY ) const
+ {
+ radiusX = m_Radius[0];
+ radiusY = m_Radius[1];
+ }
+
+ void SetCenterPoint( const CUILength &x, const CUILength &y )
+ {
+ m_Center[0] = x;
+ m_Center[1] = y;
+ }
+
+ void SetOffsetDistance( const CUILength &x, const CUILength &y )
+ {
+ m_Offset[0] = x;
+ m_Offset[1] = y;
+ }
+
+ void SetRadii( const CUILength &x, const CUILength &y )
+ {
+ m_Radius[0] = x;
+ m_Radius[1] = y;
+ }
+
+ const CUtlVector<CGradientColorStop> &AccessStopColors() const
+ {
+ return m_vecStops;
+ }
+
+ CUtlVector<CGradientColorStop> &AccessMutableStopColors()
+ {
+ return m_vecStops;
+ }
+
+ bool operator==( const CRadialGradient &rhs ) const
+ {
+ if ( m_Center[0] != rhs.m_Center[0] || m_Center[1] != rhs.m_Center[1] ||
+ m_Offset[0] != rhs.m_Offset[0] || m_Offset[1] != rhs.m_Offset[1] ||
+ m_Radius[0] != rhs.m_Radius[0] || m_Radius[1] != rhs.m_Radius[1] )
+ {
+ return false;
+ }
+
+ if ( m_vecStops.Count() != rhs.m_vecStops.Count() )
+ return false;
+
+ FOR_EACH_VEC( m_vecStops, i )
+ {
+ if ( m_vecStops[i] != rhs.m_vecStops[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ m_Center[0].ScaleLengthValue( flScaleFactor );
+ m_Center[1].ScaleLengthValue( flScaleFactor );
+ m_Offset[0].ScaleLengthValue( flScaleFactor );
+ m_Offset[1].ScaleLengthValue( flScaleFactor );
+ m_Radius[0].ScaleLengthValue( flScaleFactor );
+ m_Radius[1].ScaleLengthValue( flScaleFactor );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecStops );
+ }
+#endif
+
+private:
+
+ // Start/end point determine angle vector
+ CUILength m_Center[2];
+ CUILength m_Offset[2];
+ CUILength m_Radius[2];
+ CCopyableUtlVector<CGradientColorStop> m_vecStops;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a fill color/stroke, may be a gradient
+//-----------------------------------------------------------------------------
+class CFillBrush
+{
+public:
+
+ // Types of strokes we support
+ enum EStrokeType
+ {
+ k_EStrokeTypeFillColor,
+ k_EStrokeTypeLinearGradient,
+ k_EStrokeTypeRadialGradient,
+ k_EStrokeTypeParticleSystem,
+ };
+
+ // Default constructor, sets transparent fill color
+ CFillBrush()
+ {
+ m_eType = k_EStrokeTypeFillColor;
+ m_FillColor.SetColor( 0, 0, 0, 0 );
+ }
+
+ // Constructor for standard color fill
+ CFillBrush( int r, int g, int b, int a )
+ {
+ m_eType = k_EStrokeTypeFillColor;
+ m_FillColor.SetColor( r, g, b, a );
+ }
+
+ // Constructor for linear gradient fill
+ CFillBrush( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_eType = k_EStrokeTypeLinearGradient;
+ m_LinearGradient.SetGradient( StartX, StartY, EndX, EndY, vecStopColors );
+ }
+
+ // Constructor for radial gradient
+ CFillBrush( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_eType = k_EStrokeTypeRadialGradient;
+ m_RadialGradient.SetGradient( centerX, centerY, offsetX, offsetY, radiusX, radiusY, vecStopColors );
+ }
+
+ // Constructor for particle system
+ CFillBrush( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance,
+ Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance, float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ m_eType = k_EStrokeTypeParticleSystem;
+ m_ParticleSystem.SetParticleSystem( vecBasePositon, vecBasePositionVariance, flSize, flSizeVariance, flParticlesPerSecond, flParticlesPerSecondVariance,
+ flLifeSpanSeconds, flLifeSpanSecondsVariance, vecInitialVelocity, vecInitialVelocityVariance, vecVelocityMin, vecVelocityMax,
+ vecGravityAcceleration, vecGravityAccelerationParticleVariance,
+ colorStart, colorStartVariance, colorEnd, colorEndVariance, flSharpness, flSharpnessVariance, flFlicker, flFlickerVariance );
+ }
+
+ // Get type
+ EStrokeType GetType() const { return m_eType; }
+
+ // Set to a fill color value
+ void SetToFillColor( Color color )
+ {
+ m_eType = k_EStrokeTypeFillColor;
+ m_FillColor = color;
+ }
+
+ // Get fill color for fill stroke types
+ Color GetFillColor() const
+ {
+ Assert( m_eType == k_EStrokeTypeFillColor );
+ return m_FillColor;
+ }
+
+ // Set brush to a linear gradient value
+ void SetToLinearGradient( const CUILength &startX, const CUILength &startY, const CUILength &endX, const CUILength &endY, const CUtlVector<CGradientColorStop> &vecColorStops )
+ {
+ m_eType = k_EStrokeTypeLinearGradient;
+ m_LinearGradient.SetGradient( startX, startY, endX, endY, vecColorStops );
+ }
+
+ // Set to a radial gradient value
+ void SetToRadialGradient( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_eType = k_EStrokeTypeRadialGradient;
+ m_RadialGradient.SetGradient( centerX, centerY, offsetX, offsetY, radiusX, radiusY, vecStopColors );
+ }
+
+ // Set to particle system value
+ void SetToParticleSystem( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance,
+ Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance, float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ m_eType = k_EStrokeTypeParticleSystem;
+ m_ParticleSystem.SetParticleSystem( vecBasePositon, vecBasePositionVariance, flSize, flSizeVariance, flParticlesPerSecond, flParticlesPerSecondVariance,
+ flLifeSpanSeconds, flLifeSpanSecondsVariance, vecInitialVelocity, vecInitialVelocityVariance, vecVelocityMin, vecVelocityMax, vecGravityAcceleration, vecGravityAccelerationParticleVariance,
+ colorStart, colorStartVariance, colorEnd, colorEndVariance, flSharpness, flSharpnessVariance, flFlicker, flFlickerVariance );
+ }
+
+ // Get start/end pos for linear gradient types
+ void GetStartAndEndPoints( CUILength &StartX, CUILength &StartY, CUILength &EndX, CUILength &EndY ) const
+ {
+ Assert( m_eType == k_EStrokeTypeLinearGradient );
+ m_LinearGradient.GetStartPoint( StartX, StartY );
+ m_LinearGradient.GetEndPoint( EndX, EndY );
+ }
+
+ // Access start/end pos for linear or radial gradient types
+ const CUtlVector<CGradientColorStop> &AccessStopColors() const
+ {
+ Assert( m_eType == k_EStrokeTypeLinearGradient || m_eType == k_EStrokeTypeRadialGradient );
+ if ( m_eType == k_EStrokeTypeLinearGradient )
+ return m_LinearGradient.AccessStopColors();
+
+ if ( m_eType == k_EStrokeTypeRadialGradient )
+ return m_RadialGradient.AccessStopColors();
+
+ // Otherwise this is bad, let's just return the hopefully empty linear vector
+ return m_LinearGradient.AccessStopColors();
+ }
+
+ // Get start/end pos for linear gradient types
+ void GetRadialGradientValues( CUILength &centerX, CUILength &centerY, CUILength &offsetX, CUILength &offsetY, CUILength &radiusX, CUILength &radiusY ) const
+ {
+ Assert( m_eType == k_EStrokeTypeRadialGradient );
+ m_RadialGradient.GetCenterPoint( centerX, centerY );
+ m_RadialGradient.GetOffsetDistance( offsetX, offsetY );
+ m_RadialGradient.GetRadii( radiusX, radiusY );
+ }
+
+ CParticleSystem * AccessParticleSystem()
+ {
+ Assert( m_eType == k_EStrokeTypeParticleSystem );
+ return &m_ParticleSystem;
+ }
+
+ bool Interpolate( float flActualWidth, float flActualHeight, CFillBrush &target, float flProgress );
+
+ bool operator==( const CFillBrush &rhs ) const
+ {
+ if ( m_eType != rhs.m_eType )
+ return false;
+
+ switch( m_eType )
+ {
+ case k_EStrokeTypeFillColor:
+ return m_FillColor == rhs.m_FillColor;
+ case k_EStrokeTypeLinearGradient:
+ return m_LinearGradient == rhs.m_LinearGradient;
+ case k_EStrokeTypeRadialGradient:
+ return m_RadialGradient == rhs.m_RadialGradient;
+ case k_EStrokeTypeParticleSystem:
+ return m_ParticleSystem == rhs.m_ParticleSystem;
+ default:
+ AssertMsg( false, "Invalid type on fillbrush" );
+ return false;
+ }
+ }
+
+ bool operator!=( const CFillBrush &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ if ( m_eType == k_EStrokeTypeLinearGradient )
+ m_LinearGradient.ScaleLengthValues( flScaleFactor );
+ else if ( m_eType == k_EStrokeTypeRadialGradient )
+ m_RadialGradient.ScaleLengthValues( flScaleFactor );
+ else if ( m_eType == k_EStrokeTypeParticleSystem )
+ m_ParticleSystem.ScaleLengthValues( flScaleFactor );
+
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_LinearGradient );
+ ValidateObj( m_RadialGradient );
+ ValidateObj( m_ParticleSystem );
+ }
+#endif
+private:
+
+ void ConvertToRadialGradient();
+ void ConvertToLinearGradient();
+ void NormalizeStopCount( CUtlVector<CGradientColorStop> &vec, int nStopsNeeded, Color defaultColor );
+
+ EStrokeType m_eType;
+
+ Color m_FillColor;
+ CLinearGradient m_LinearGradient;
+ CRadialGradient m_RadialGradient;
+ CParticleSystem m_ParticleSystem;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a collection of fill brushes, when filling geometry with
+// such a collection they should be applied in order and blended appropriately.
+//-----------------------------------------------------------------------------
+#define MAX_FILL_BRUSHES_PER_COLLECTION 8
+class CFillBrushCollection
+{
+public:
+
+
+ struct FillBrush_t
+ {
+ CFillBrush m_Brush;
+ float m_Opacity;
+
+ bool operator==( const FillBrush_t &rhs ) const { return (m_Brush == rhs.m_Brush && m_Opacity == rhs.m_Opacity); }
+ bool operator!=( const FillBrush_t &rhs ) const { return !(*this == rhs ); }
+ };
+
+ CFillBrushCollection() { }
+
+ // Get brush count
+ uint32 GetBrushCount() const { return m_vecFillBrushes.Count(); }
+
+ // Access brush vector directly
+ CUtlVectorFixed< FillBrush_t, MAX_FILL_BRUSHES_PER_COLLECTION > &AccessBrushes() { return m_vecFillBrushes; }
+ const CUtlVectorFixed< FillBrush_t, MAX_FILL_BRUSHES_PER_COLLECTION> &AccessBrushes() const { return m_vecFillBrushes; }
+
+ // Add brush to collection
+ void AddFillBrush( const CFillBrush &brush, float opacity = 1.0 )
+ {
+
+ int i = m_vecFillBrushes.AddToTail();
+ m_vecFillBrushes[i].m_Brush = brush;
+ m_vecFillBrushes[i].m_Opacity = opacity;
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ FOR_EACH_VEC( m_vecFillBrushes, i )
+ {
+ m_vecFillBrushes[i].m_Brush.ScaleLengthValues( flScaleFactor );
+ }
+ }
+
+ int GetNumParticleSystems()
+ {
+ int nParticleSystems = 0;
+ FOR_EACH_VEC( m_vecFillBrushes, i )
+ {
+ if ( m_vecFillBrushes[i].m_Brush.GetType() == CFillBrush::k_EStrokeTypeParticleSystem )
+ ++nParticleSystems;
+ }
+
+ return nParticleSystems;
+ }
+
+ void Clear()
+ {
+ m_vecFillBrushes.RemoveAll();
+ }
+
+ // Interpolate between two fill brushes
+ void Interpolate( float flActualWidth, float flActualHeight, const CFillBrushCollection &target, float flProgress );
+ bool operator==( const CFillBrushCollection &rhs ) const;
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecFillBrushes );
+ FOR_EACH_VEC( m_vecFillBrushes, i )
+ {
+ ValidateObj( m_vecFillBrushes[i].m_Brush );
+ }
+ }
+#endif
+
+private:
+
+ CCopyableUtlVectorFixed< FillBrush_t, MAX_FILL_BRUSHES_PER_COLLECTION > m_vecFillBrushes;
+};
+
+} // namespace panorama
+
+#endif // FILLBRUSH_H \ No newline at end of file
diff --git a/public/panorama/layout/panel2dfactory.h b/public/panorama/layout/panel2dfactory.h
new file mode 100644
index 0000000..361004d
--- /dev/null
+++ b/public/panorama/layout/panel2dfactory.h
@@ -0,0 +1,111 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANEL2DFACTORY_H
+#define PANEL2DFACTORY_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "utlsymbol.h"
+#include "tier1/utlrbtree.h"
+#include "panorama/panoramasymbol.h"
+
+
+namespace panorama
+{
+class IUIPanel;
+class IUIPanelClient;
+class IUIEngine;
+class CPanel2DFactory;
+
+#ifdef DBGFLAG_VALIDATE
+void ValidatePanel2DFactory( CValidator &validator );
+#endif
+
+void RegisterPanelFactoriesWithEngine( IUIEngine *pEngine );
+
+//-----------------------------------------------------------------------------
+// Purpose: Used by DECLARE_PANEL2D_FACTORY macro to create a linked list of instancing functions
+//-----------------------------------------------------------------------------
+typedef panorama::IUIPanelClient *(*PANEL2DCREATEFUNC)(const char *pchName, panorama::IUIPanel *parent);
+typedef CPanoramaSymbol( *PANELSYMBOLFUNC )();
+class CPanel2DFactory
+{
+public:
+ CPanel2DFactory( CPanoramaSymbol *pSym, char const *pchLayoutName, PANEL2DCREATEFUNC func, void *pChrisBoydBS, PANELSYMBOLFUNC symParentFunc );
+
+ static bool BRegisteredLocalName( CUtlSymbol symName );
+ CPanoramaSymbol BaseClassSymbol() { return m_funcSymParent(); }
+
+private:
+ friend class CUIEngine;
+ IUIPanelClient *CreatePanelInternal( const char *pchID, panorama::IUIPanel *parent );
+
+ PANELSYMBOLFUNC m_funcSymParent;
+
+ PANEL2DCREATEFUNC m_funcCreate;
+};
+
+
+// This is the macro which implements creation of each type of panel. It creates a function which instances an object of the specified type
+// It them hooks that function up to the helper list so that objects can create the elements by name, with no header file dependency, etc.
+// Params: className = name of class to create
+// layoutName = name used in the layout file
+#define REGISTER_PANEL2D_FACTORY( className, layoutName ) \
+ panorama::CPanoramaSymbol className::m_symbol; \
+ static panorama::IUIPanelClient *Create_##layoutName( const char *pchID, panorama::IUIPanel *parent ) \
+ { \
+ return new className( ToPanel2D(parent), pchID ); \
+ }; \
+ namespace panorama { className *g_##layoutName##LinkerHack = NULL; } \
+ panorama::CPanel2DFactory g_##layoutName##_Helper( &className::m_symbol, #layoutName, Create_##layoutName, panorama::g_##layoutName##LinkerHack, &className::BaseClass::GetPanelSymbol );
+
+// Can be used to register a name so it can be used as a top level panel in XML, but can't be created through a layout file
+#define REGISTER_PANEL2D( className, layoutName ) \
+ panorama::CPanoramaSymbol className::m_symbol; \
+ namespace panorama { className *g_##layoutName##LinkerHack = NULL; } \
+ panorama::CPanel2DFactory g_##layoutName##_Helper( &className::m_symbol, #layoutName, NULL, panorama::g_##layoutName##LinkerHack, &className::BaseClass::GetPanelSymbol );
+
+
+// Can be used to reserve a panel name w/o a panel class
+#define REGISTER_PANEL_NAME( layoutName ) \
+ panorama::CPanoramaSymbol k_symPanel##layoutName; \
+ panorama::CPanoramaSymbol Get_##layoutName##_Symbol() { return k_symPanel##layoutName; } \
+ panorama::CPanel2DFactory g_##layoutName##_Helper( &k_symPanel##layoutName, #layoutName, NULL, NULL, &Get_##layoutName##_Symbol );
+
+
+
+#define DECLARE_PANEL2D( className, baseClassName ) \
+public: \
+ typedef baseClassName BaseClass; \
+ typedef className ThisClass; \
+ static panorama::CPanoramaSymbol m_symbol; \
+ \
+ static panorama::CPanoramaSymbol GetPanelSymbol() { return className::m_symbol; } \
+ virtual panorama::CPanoramaSymbol GetPanelType() const { return className::m_symbol; } \
+private:
+
+
+#define DECLARE_PANEL2D_NO_BASE( className ) \
+public: \
+ typedef className ThisClass; \
+ typedef className BaseClass; \
+ static panorama::CPanoramaSymbol m_symbol; \
+ \
+ static panorama::CPanoramaSymbol GetPanelSymbol() { return className::m_symbol; } \
+ virtual panorama::CPanoramaSymbol GetPanelType() const { return className::m_symbol; } \
+private:
+
+} // namespace panorama
+
+inline uint32 HashItem( const panorama::CPanoramaSymbol &item )
+{
+ return ::HashItem( (UtlSymId_t)item );
+}
+
+
+#endif // PANEL2DFACTORY_H \ No newline at end of file
diff --git a/public/panorama/layout/stylefiletypes.h b/public/panorama/layout/stylefiletypes.h
new file mode 100644
index 0000000..418d6ad
--- /dev/null
+++ b/public/panorama/layout/stylefiletypes.h
@@ -0,0 +1,61 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_STYLEFILETYPES_H
+#define PANORAMA_STYLEFILETYPES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "../iuipanel.h"
+
+namespace panorama
+{
+class IUILayoutFile;
+class IUIPanel;
+
+//-----------------------------------------------------------------------------
+// Purpose: Validate statics
+//-----------------------------------------------------------------------------
+#ifdef DBGFLAG_VALIDATE
+ void ValidateStylePropertyFactory( CValidator &validator );
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: Used to sort styles to apply by cascade order
+//-----------------------------------------------------------------------------
+struct StyleFromFile_t;
+class CLayoutFile;
+struct CascadeStyleFileInfo_t
+{
+ const StyleFromFile_t *m_pStyleFromFile;
+ panorama::IUILayoutFile *m_pLayoutFile; // layout file
+ uint m_iStyleFile; // layout file index
+ uint m_unSelectorSpecificity; // score for this selector (high = overrides lower valued selectors)
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: All the info needed to identify a panel. Used when looking up a style w/o a IUIPanel*
+//-----------------------------------------------------------------------------
+class CPanelIdentifiers
+{
+public:
+ CPanelIdentifiers();
+ CPanelIdentifiers( IUIPanel *pPanel );
+
+ CPanoramaSymbol m_symPanelType;
+ uint m_unStyleFlags;
+ const CPanoramaSymbol *m_psymClasses;
+ uint m_csymClasses;
+ const char *m_pchID;
+ bool m_bTreatPanelAsParent;
+ IUIPanel *m_pPanel;
+};
+
+} // namespace panorama
+
+
+#endif //PANORAMA_STYLEFILETYPES_H
diff --git a/public/panorama/layout/stylesymbol.h b/public/panorama/layout/stylesymbol.h
new file mode 100644
index 0000000..c94286b
--- /dev/null
+++ b/public/panorama/layout/stylesymbol.h
@@ -0,0 +1,73 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef STYLESYMBOL_H
+#define STYLESYMBOL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#define MAX_PANORAMA_STYLE_SYMBOLS 128
+
+#include "tier0/validator.h"
+#include "utlsymbol.h"
+#include "utlvector.h"
+#ifdef SOURCE_PANORAMA_FIXME
+#include "UtlSortVector.h"
+#else
+#include "utlsortvector.h"
+#endif
+#include "utlstring.h"
+
+
+namespace panorama
+{
+
+ class CStyleProperty;
+
+ class CStyleSymbol
+ {
+ public:
+ // constructor, destructor
+ CStyleSymbol() : m_Id( 0xFF ) {}
+ CStyleSymbol( uint8 id ) : m_Id( id ) {}
+ CStyleSymbol( char const* pStr );
+ CStyleSymbol( char const* pStr, bool bCreateNew );
+ CStyleSymbol( CStyleSymbol const& sym ) : m_Id(sym.m_Id) {}
+
+ // operator=
+ CStyleSymbol& operator=( CStyleSymbol const& src ) { m_Id = src.m_Id; return *this; }
+
+ // operator==
+ bool operator==( CStyleSymbol const& src ) const { return m_Id == src.m_Id; }
+ bool operator==( char const* pStr ) const;
+
+ // operator !=
+ bool operator!=( CStyleSymbol const& src ) const { return m_Id != src.m_Id; }
+
+ // operator <
+ bool operator < (const CStyleSymbol &rhs ) const { return m_Id < rhs.m_Id; }
+
+
+ uint8 GetID() const { return m_Id; }
+
+ // Is valid?
+ bool IsValid() const { return m_Id != 0xFF; }
+
+ // Gets the string associated with the symbol
+ char const* String() const;
+
+ operator const char *() const { return String(); }
+
+ protected:
+ uint8 m_Id;
+ };
+
+ uint32 HashItem( const CStyleSymbol &item );
+
+} // namespace panorama
+
+#endif // STYLESYMBOL_H
diff --git a/public/panorama/layout/uilength.h b/public/panorama/layout/uilength.h
new file mode 100644
index 0000000..d6dad83
--- /dev/null
+++ b/public/panorama/layout/uilength.h
@@ -0,0 +1,147 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UILENGTH_H
+#define UILENGTH_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "float.h"
+#include "tier0/dbg.h"
+#include "tier1/utlvector.h"
+#include "mathlib/mathlib.h"
+#include "../panorama.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: defines
+//-----------------------------------------------------------------------------
+const float k_flFloatAuto = FLT_MAX;
+const float k_flFloatNotSet = FLT_MIN;
+
+// Sometimes we want to say "infinite width/height", but we can't use FLT_MAX as it's "auto"
+const float k_flMaxWidthOrHeight = 512000000.0f;
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents possible length values
+//-----------------------------------------------------------------------------
+class CUILength
+{
+public:
+ enum EUILengthTypes
+ {
+ k_EUILengthUnset,
+ k_EUILengthLength,
+ k_EUILengthPercent,
+ k_EUILengthFitChildren,
+ k_EUILengthFillParentFlow,
+ k_EUILengthHeightPercentage,
+ k_EUILengthWidthPercentage,
+ };
+
+ CUILength() : m_flValue( k_flFloatNotSet ), m_eType( k_EUILengthUnset ) {}
+ CUILength( float flValue, EUILengthTypes eType ) : m_flValue( flValue ), m_eType( eType ) {}
+
+ bool IsSet() const { return (m_eType != k_EUILengthUnset); }
+ bool IsLength() const { return (m_eType == k_EUILengthLength); }
+ bool IsPercent() const { return (m_eType == k_EUILengthPercent); }
+ bool IsFitChildren() const { return (m_eType == k_EUILengthFitChildren); }
+ bool IsFillParentFlow() const { return (m_eType == k_EUILengthFillParentFlow); }
+ bool IsHeightPercentage() const { return (m_eType == k_EUILengthHeightPercentage); }
+ bool IsWidthPercentage() const { return (m_eType == k_EUILengthWidthPercentage); }
+
+ float GetValue() const { return m_flValue; }
+ CUILength::EUILengthTypes GetType() const { return m_eType; }
+
+ void SetFitChildren() { Set( k_flFloatAuto, k_EUILengthFitChildren ); }
+ void SetLength( float flValue ) { Set( flValue, k_EUILengthLength ); }
+ void SetPercent( float flValue ) { Set( flValue, k_EUILengthPercent ); }
+ void SetFillParentFlow( float flWeight ) { Set( flWeight, k_EUILengthFillParentFlow ); }
+ void SetParentFlow( float flValue ) { Set( flValue, k_EUILengthFillParentFlow ); }
+ void SetHeightPercentage( float flValue ) { Set( flValue, k_EUILengthHeightPercentage ); }
+ void SetWidthPercentage( float flValue ) { Set( flValue, k_EUILengthWidthPercentage ); }
+
+ void Set( float flValue, EUILengthTypes eType )
+ {
+ m_flValue = flValue;
+ m_eType = eType;
+ }
+
+ void ConvertToLength( float flTotalLength )
+ {
+ if ( m_eType == k_EUILengthPercent )
+ Set( GetValueAsLength( flTotalLength ), k_EUILengthLength );
+ else
+ Assert( m_eType == k_EUILengthLength || m_eType == k_EUILengthUnset );
+ }
+
+ void ConvertToPercent( float flTotalLength )
+ {
+ if ( m_eType == k_EUILengthLength )
+ Set( m_flValue / flTotalLength * 100.0, k_EUILengthPercent );
+ else
+ Assert( m_eType == k_EUILengthPercent || m_eType == k_EUILengthUnset );
+ }
+
+ float GetValueAsLength( float flTotalLength ) const
+ {
+ float flRet = m_flValue;
+ if ( m_eType == k_EUILengthPercent )
+ flRet = m_flValue * flTotalLength / 100.0;
+ else
+ Assert( m_eType == k_EUILengthLength );
+
+ return flRet;
+ }
+
+ void ScaleLengthValue( float flScaleFactor )
+ {
+ if ( m_eType == k_EUILengthLength && m_flValue != k_flFloatAuto && m_flValue != k_flFloatNotSet )
+ {
+ // Don't make width/height values of 1.0 shrink, as things like 1 px horizontal rules will go invisible! Kind of hacky,
+ // but this mostly works without issue as we have so few things < 1px.
+ if ( fabsf( 1.0f - fabsf( m_flValue ) ) < 0.1f && flScaleFactor < 1.0f )
+ {
+ // Don't need to adjust
+ }
+ else
+ {
+ // If the original value was pixel aligned, try to keep that. This is important so text doesn't accumulate error layers down
+ // 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
+ // and the half pixel can be important for the shadow to balance on both sides of the layer.
+ if ( fabsf( m_flValue - (float)RoundFloatToInt( m_flValue ) ) < 0.001f )
+ m_flValue = (float)RoundFloatToInt( m_flValue * flScaleFactor );
+ else
+ m_flValue = m_flValue * flScaleFactor;
+ }
+ }
+ }
+
+ bool operator==( const CUILength &rhs ) const
+ {
+ return (m_flValue == rhs.m_flValue && m_eType == rhs.m_eType);
+ }
+
+ bool operator!=( const CUILength &rhs ) const
+ {
+ return !(*this == rhs);
+ }
+
+
+private:
+ float m_flValue;
+ EUILengthTypes m_eType;
+};
+
+// Helper for doing lerp on ui length values, converting % and such
+CUILength LerpUILength( float flProgress, CUILength start, CUILength end, float flPixelSize );
+
+} // namespace panorama
+
+#endif //UILENGTH_H \ No newline at end of file