source-engine/public/panorama/layout/uilength.h
FluorescentCIAAfricanAmerican 3bf9df6b27 1
2020-04-22 12:56:21 -04:00

147 lines
4.8 KiB
C++

//=========== 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