using System; using System.Collections.Generic; using Unity.UIWidgets.foundation; using Unity.UIWidgets.ui; namespace Unity.UIWidgets.animation { public abstract class Animatable { public abstract T evaluate(Animation animation); public Animation animate(Animation parent) { return new _AnimatedEvaluation(parent, this); } public Animatable chain(Animatable parent) { return new _ChainedEvaluation(parent, this); } } class _AnimatedEvaluation : AnimationWithParentMixin { internal _AnimatedEvaluation(Animation parent, Animatable evaluatable) { _parent = parent; _evaluatable = evaluatable; } public override Animation parent { get { return _parent; } } readonly Animation _parent; readonly Animatable _evaluatable; public override T value { get { return _evaluatable.evaluate(parent); } } public override string ToString() { return $"{parent}\u27A9{_evaluatable}\u27A9{value}"; } public override string toStringDetails() { return base.toStringDetails() + " " + _evaluatable; } } class _ChainedEvaluation : Animatable { internal _ChainedEvaluation(Animatable parent, Animatable evaluatable) { _parent = parent; _evaluatable = evaluatable; } readonly Animatable _parent; readonly Animatable _evaluatable; public override T evaluate(Animation animation) { float value = _parent.evaluate(animation); return _evaluatable.evaluate(new AlwaysStoppedAnimation(value)); } public override string ToString() { return $"{_parent}\u27A9{_evaluatable}"; } } public abstract class Tween : Animatable, IEquatable> { protected Tween(T begin, T end) { this.begin = begin; this.end = end; } public virtual T begin { get; set; } public virtual T end { get; set; } public abstract T lerp(float t); public override T evaluate(Animation animation) { float t = animation.value; if (t == 0.0) { return begin; } if (t == 1.0) { return end; } return lerp(t); } public override string ToString() { return $"{GetType()}({begin} \u2192 {end})"; } public bool Equals(Tween other) { if (ReferenceEquals(null, other)) { return false; } if (ReferenceEquals(this, other)) { return true; } return EqualityComparer.Default.Equals(begin, other.begin) && EqualityComparer.Default.Equals(end, other.end); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } if (ReferenceEquals(this, obj)) { return true; } if (obj.GetType() != GetType()) { return false; } return Equals((Tween) obj); } public override int GetHashCode() { unchecked { return (EqualityComparer.Default.GetHashCode(begin) * 397) ^ EqualityComparer.Default.GetHashCode(end); } } public static bool operator ==(Tween left, Tween right) { return Equals(left, right); } public static bool operator !=(Tween left, Tween right) { return !Equals(left, right); } } public class ReverseTween : Tween { public ReverseTween(Tween parent) : base(begin: parent.end, end: parent.begin) { this.parent = parent; } public readonly Tween parent; public override T lerp(float t) { return parent.lerp(1.0f - t); } } public class ColorTween : Tween { public ColorTween(Color begin = null, Color end = null) : base(begin: begin, end: end) { } public override Color lerp(float t) { return Color.lerp(begin, end, t); } } public class SizeTween : Tween { public SizeTween(Size begin = null, Size end = null) : base(begin: begin, end: end) { } public override Size lerp(float t) { return Size.lerp(begin, end, t); } } public class RectTween : Tween { public RectTween(Rect begin = null, Rect end = null) : base(begin: begin, end: end) { } public override Rect lerp(float t) { return Rect.lerp(begin, end, t); } } public class IntTween : Tween { public IntTween(int begin, int end) : base(begin: begin, end: end) { } public override int lerp(float t) { return (begin + (end - begin) * t).round(); } } public class NullableFloatTween : Tween { public NullableFloatTween(float? begin = null, float? end = null) : base(begin: begin, end: end) { } public override float? lerp(float t) { D.assert(begin != null); D.assert(end != null); return begin + (end - begin) * t; } } public class FloatTween : Tween { public FloatTween(float begin, float end) : base(begin: begin, end: end) { } public override float lerp(float t) { return begin + (end - begin) * t; } } public class StepTween : Tween { public StepTween(int begin, int end) : base(begin: begin, end: end) { } public override int lerp(float t) { return (begin + (end - begin) * t).floor(); } } public class OffsetTween : Tween { public OffsetTween(Offset begin, Offset end) : base(begin: begin, end: end) { } public override Offset lerp(float t) { return (begin + (end - begin) * t); } } class ConstantTween : Tween { public ConstantTween(T value) : base(begin: value, end: value) { } public override T lerp(float t) { return begin; } public override string ToString() { return $"{GetType()}(value: {begin})"; } } public class CurveTween : Animatable { public CurveTween(Curve curve = null) { D.assert(curve != null); this.curve = curve; } public readonly Curve curve; public override float evaluate(Animation animation) { float t = animation.value; if (t == 0.0 || t == 1.0) { D.assert(curve.transform(t).round() == t); return t; } return curve.transform(t); } public override string ToString() { return $"{GetType()}(curve: {curve})"; } } }