347 lines
8.0 KiB
C#
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
|
|
}
|
|
}
|