Editor proxy property that wraps a SerializedProperty to present a length value in meters while the underlying property stores inches. It converts values on get and set for float, double and string types and delegates other types to the wrapped property.
using Sandbox;
namespace Metrify;
internal sealed class MeterFloatProperty : SerializedProperty.Proxy
{
private readonly SerializedProperty _target;
protected override SerializedProperty ProxyTarget => _target;
public MeterFloatProperty( SerializedProperty target )
{
_target = target;
}
public override T GetValue<T>( T defaultValue = default )
{
if ( typeof( T ) == typeof( float ) || typeof( T ) == typeof( double ) ||
typeof( T ) == typeof( string ) || typeof( T ) == typeof( object ) )
{
var meters = Units.ToMeters( _target.GetValue<float>() );
if ( typeof( T ) == typeof( float ) ) return (T)(object)meters;
if ( typeof( T ) == typeof( double ) ) return (T)(object)(double)meters;
if ( typeof( T ) == typeof( string ) ) return (T)(object)meters.ToString( "0.###" );
return (T)(object)meters;
}
return _target.GetValue( defaultValue );
}
public override void SetValue<T>( T value )
{
switch ( value )
{
case float meters:
_target.SetValue( Units.ToInches( meters ) );
return;
case double meters:
_target.SetValue( Units.ToInches( (float)meters ) );
return;
case string text when float.TryParse( text, out var meters ):
_target.SetValue( Units.ToInches( meters ) );
return;
}
_target.SetValue( value );
}
}