Files
2024-02-23 07:03:56 -05:00

347 lines
8.0 KiB
C#

/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Xceed.Wpf.Toolkit.Core.Utilities;
using Xceed.Wpf.Toolkit.Core;
namespace Xceed.Wpf.Toolkit.Media.Animation
{
[TypeConverter( typeof( AnimationRateConverter ) )]
[StructLayout( LayoutKind.Explicit )]
public struct AnimationRate
{
#region Static Fields
private static AnimationRate _default = new AnimationRate( true );
#endregion
#region Constructors
public AnimationRate( TimeSpan duration )
{
if( duration < TimeSpan.Zero )
{
throw new ArgumentException( ErrorMessages.GetMessage( ErrorMessages.NegativeTimeSpanNotSupported ) );
}
_speed = 0d;
_duration = duration.Ticks;
_rateType = RateType.TimeSpan;
}
public AnimationRate( double speed )
{
if( DoubleHelper.IsNaN( speed ) || speed < 0d )
{
throw new ArgumentException( ErrorMessages.GetMessage( ErrorMessages.NegativeSpeedNotSupported ) );
}
_duration = 0;
_speed = speed;
_rateType = RateType.Speed;
}
private AnimationRate( bool ignore )
{
_duration = 0;
_speed = double.NaN;
_rateType = RateType.Speed;
}
#endregion
#region Default Property
public static AnimationRate Default
{
get
{
return _default;
}
}
#endregion
#region HasDuration Property
public bool HasDuration
{
get
{
return ( _rateType == RateType.TimeSpan );
}
}
#endregion
#region Duration Property
public TimeSpan Duration
{
get
{
if( this.HasDuration )
return TimeSpan.FromTicks( _duration );
throw new InvalidOperationException(
string.Format(
ErrorMessages.GetMessage( ErrorMessages.InvalidRatePropertyAccessed ),
"Duration",
this,
"Speed" ) );
}
}
#endregion
#region HasSpeed Property
public bool HasSpeed
{
get
{
return ( _rateType == RateType.Speed );
}
}
#endregion
#region Speed Property
public double Speed
{
get
{
if( this.HasSpeed )
return _speed;
throw new InvalidOperationException(
string.Format(
ErrorMessages.GetMessage( ErrorMessages.InvalidRatePropertyAccessed ),
"Speed",
this,
"Duration" ) );
}
}
#endregion
public AnimationRate Add( AnimationRate animationRate )
{
return this + animationRate;
}
public override bool Equals( Object value )
{
if( value == null )
return false;
if( value is AnimationRate )
return this.Equals( ( AnimationRate )value );
return false;
}
public bool Equals( AnimationRate animationRate )
{
if( this.HasDuration )
{
if( animationRate.HasDuration )
return _duration == animationRate._duration;
return false;
}
else // HasSpeed
{
if( animationRate.HasSpeed )
{
if( DoubleHelper.IsNaN( _speed ) )
return DoubleHelper.IsNaN( animationRate._speed );
return _speed == animationRate._speed;
}
return false;
}
}
public static bool Equals( AnimationRate t1, AnimationRate t2 )
{
return t1.Equals( t2 );
}
public override int GetHashCode()
{
if( this.HasDuration )
return _duration.GetHashCode();
return _speed.GetHashCode();
}
public AnimationRate Subtract( AnimationRate animationRate )
{
return this - animationRate;
}
public override string ToString()
{
if( this.HasDuration )
return TypeDescriptor.GetConverter( _duration ).ConvertToString( _duration );
return TypeDescriptor.GetConverter( _speed ).ConvertToString( _speed );
}
#region Operators Methods
public static implicit operator AnimationRate( TimeSpan duration )
{
if( duration < TimeSpan.Zero )
throw new ArgumentException( ErrorMessages.GetMessage( ErrorMessages.NegativeTimeSpanNotSupported ) );
return new AnimationRate( duration );
}
public static implicit operator AnimationRate( double speed )
{
if( DoubleHelper.IsNaN( speed ) || speed < 0 )
throw new ArgumentException( ErrorMessages.GetMessage( ErrorMessages.NegativeSpeedNotSupported ) );
return new AnimationRate( speed );
}
public static implicit operator AnimationRate( int speed )
{
if( DoubleHelper.IsNaN( speed ) || speed < 0 )
throw new ArgumentException( ErrorMessages.GetMessage( ErrorMessages.NegativeSpeedNotSupported ) );
return new AnimationRate( ( double )speed );
}
public static AnimationRate operator +( AnimationRate t1, AnimationRate t2 )
{
if( t1.HasDuration && t2.HasDuration )
return new AnimationRate( t1._duration + t2._duration );
if( t1.HasSpeed && t2.HasSpeed )
return new AnimationRate( t1._speed + t2._speed );
return ( AnimationRate )0d;
}
public static AnimationRate operator -( AnimationRate t1, AnimationRate t2 )
{
if( t1.HasDuration && t2.HasDuration )
return new AnimationRate( t1._duration - t2._duration );
if( t1.HasSpeed && t2.HasSpeed )
return new AnimationRate( t1._speed - t2._speed );
return ( AnimationRate )0d;
}
public static bool operator ==( AnimationRate t1, AnimationRate t2 )
{
return t1.Equals( t2 );
}
public static bool operator !=( AnimationRate t1, AnimationRate t2 )
{
return !( t1.Equals( t2 ) );
}
public static bool operator >( AnimationRate t1, AnimationRate t2 )
{
if( t1.HasDuration && t2.HasDuration )
return t1._duration > t2._duration;
if( t1.HasSpeed && t2.HasSpeed )
return ( t1._speed > t2._speed ) && !DoubleHelper.AreVirtuallyEqual( t1._speed, t2._speed );
// arbitrary: assume a Speed is greater than a Duration
return t1.HasSpeed;
}
public static bool operator >=( AnimationRate t1, AnimationRate t2 )
{
return !( t1 < t2 );
}
public static bool operator <( AnimationRate t1, AnimationRate t2 )
{
if( t1.HasDuration && t2.HasDuration )
return t1._duration < t2._duration;
if( t1.HasSpeed && t2.HasSpeed )
return ( t1._speed < t2._speed ) && !DoubleHelper.AreVirtuallyEqual( t1._speed, t2._speed );
// arbitrary: assume a Speed is greater than a Duration
return t1.HasDuration;
}
public static bool operator <=( AnimationRate t1, AnimationRate t2 )
{
return !( t1 > t2 );
}
public static int Compare( AnimationRate t1, AnimationRate t2 )
{
if( t1 < t2 )
return -1;
if( t1 > t2 )
return 1;
// Neither is greater than the other
return 0;
}
public static AnimationRate Plus( AnimationRate animationRate )
{
return animationRate;
}
public static AnimationRate operator +( AnimationRate animationRate )
{
return animationRate;
}
#endregion
#region Private Fields
[FieldOffset( 0 )]
long _duration;
[FieldOffset( 0 )]
double _speed;
[FieldOffset( 8 )]
RateType _rateType;
#endregion
#region RateType Nested Type
private enum RateType
{
TimeSpan,
Speed,
}
#endregion
}
}