using System;
using System.ComponentModel;
using Avalonia.Animation.Animators;
using Avalonia.Data;
using Avalonia.Reactive;
namespace Avalonia.Animation
{
///
/// Defines a KeyFrame that is used for
/// objects.
///
public class AnimatorKeyFrame : AvaloniaObject
{
public static readonly DirectProperty ValueProperty =
AvaloniaProperty.RegisterDirect(nameof(Value), k => k.Value, (k, v) => k.Value = v);
public AnimatorKeyFrame()
{
}
public AnimatorKeyFrame(Type animatorType, Cue cue)
{
AnimatorType = animatorType;
Cue = cue;
KeySpline = null;
}
public AnimatorKeyFrame(Type animatorType, Cue cue, KeySpline keySpline)
{
AnimatorType = animatorType;
Cue = cue;
KeySpline = keySpline;
}
internal bool isNeutral;
public Type AnimatorType { get; }
public Cue Cue { get; }
public KeySpline KeySpline { get; }
public AvaloniaProperty Property { get; private set; }
private object _value;
public object Value
{
get => _value;
set => SetAndRaise(ValueProperty, ref _value, value);
}
public IDisposable BindSetter(IAnimationSetter setter, Animatable targetControl)
{
Property = setter.Property;
var value = setter.Value;
if (value is IBinding binding)
{
return this.Bind(ValueProperty, binding, targetControl);
}
else
{
return this.Bind(ValueProperty, ObservableEx.SingleValue(value).ToBinding(), targetControl);
}
}
public T GetTypedValue()
{
var typeConv = TypeDescriptor.GetConverter(typeof(T));
if (Value == null)
{
throw new ArgumentNullException($"KeyFrame value can't be null.");
}
if(Value is T typedValue)
{
return typedValue;
}
if (!typeConv.CanConvertTo(Value.GetType()))
{
throw new InvalidCastException($"KeyFrame value doesnt match property type.");
}
return (T)typeConv.ConvertTo(Value, typeof(T));
}
}
}