check point
This commit is contained in:
363
framework/MaterialSkin.Core/Animations/AnimationManager.cs
Normal file
363
framework/MaterialSkin.Core/Animations/AnimationManager.cs
Normal file
@@ -0,0 +1,363 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Animations
|
||||
{
|
||||
class AnimationManager
|
||||
{
|
||||
public bool InterruptAnimation { get; set; }
|
||||
public double Increment { get; set; }
|
||||
public double SecondaryIncrement { get; set; }
|
||||
public AnimationType AnimationType { get; set; }
|
||||
public bool Singular { get; set; }
|
||||
|
||||
public delegate void AnimationFinished(object sender);
|
||||
public event AnimationFinished OnAnimationFinished;
|
||||
|
||||
public delegate void AnimationProgress(object sender);
|
||||
public event AnimationProgress OnAnimationProgress;
|
||||
|
||||
private readonly List<double> _animationProgresses;
|
||||
private readonly List<Point> _animationSources;
|
||||
private readonly List<AnimationDirection> _animationDirections;
|
||||
private readonly List<object[]> _animationDatas;
|
||||
|
||||
private const double MIN_VALUE = 0.00;
|
||||
private const double MAX_VALUE = 1.00;
|
||||
|
||||
private readonly Timer _animationTimer = new Timer { Interval = 5, Enabled = false };
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="singular">If true, only one animation is supported. The current animation will be replaced with the new one. If false, a new animation is added to the list.</param>
|
||||
public AnimationManager(bool singular = true)
|
||||
{
|
||||
_animationProgresses = new List<double>();
|
||||
_animationSources = new List<Point>();
|
||||
_animationDirections = new List<AnimationDirection>();
|
||||
_animationDatas = new List<object[]>();
|
||||
|
||||
Increment = 0.03;
|
||||
SecondaryIncrement = 0.03;
|
||||
AnimationType = AnimationType.Linear;
|
||||
InterruptAnimation = true;
|
||||
Singular = singular;
|
||||
|
||||
if (Singular)
|
||||
{
|
||||
_animationProgresses.Add(0);
|
||||
_animationSources.Add(new Point(0, 0));
|
||||
_animationDirections.Add(AnimationDirection.In);
|
||||
}
|
||||
|
||||
_animationTimer.Tick += AnimationTimerOnTick;
|
||||
}
|
||||
|
||||
private void AnimationTimerOnTick(object sender, EventArgs eventArgs)
|
||||
{
|
||||
for (var i = 0; i < _animationProgresses.Count; i++)
|
||||
{
|
||||
UpdateProgress(i);
|
||||
|
||||
if (!Singular)
|
||||
{
|
||||
if ((_animationDirections[i] == AnimationDirection.InOutIn && _animationProgresses[i] == MAX_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingIn && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingOut && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingIn;
|
||||
}
|
||||
else if (
|
||||
(_animationDirections[i] == AnimationDirection.In && _animationProgresses[i] == MAX_VALUE) ||
|
||||
(_animationDirections[i] == AnimationDirection.Out && _animationProgresses[i] == MIN_VALUE) ||
|
||||
(_animationDirections[i] == AnimationDirection.InOutOut && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationProgresses.RemoveAt(i);
|
||||
_animationSources.RemoveAt(i);
|
||||
_animationDirections.RemoveAt(i);
|
||||
_animationDatas.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((_animationDirections[i] == AnimationDirection.InOutIn && _animationProgresses[i] == MAX_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingIn && _animationProgresses[i] == MAX_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingOut && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnAnimationProgress?.Invoke(this);
|
||||
}
|
||||
|
||||
public bool IsAnimating()
|
||||
{
|
||||
return _animationTimer.Enabled;
|
||||
}
|
||||
|
||||
public void StartNewAnimation(AnimationDirection animationDirection, object[] data = null)
|
||||
{
|
||||
StartNewAnimation(animationDirection, new Point(0, 0), data);
|
||||
}
|
||||
|
||||
public void StartNewAnimation(AnimationDirection animationDirection, Point animationSource, object[] data = null)
|
||||
{
|
||||
if (!IsAnimating() || InterruptAnimation)
|
||||
{
|
||||
if (Singular && _animationDirections.Count > 0)
|
||||
{
|
||||
_animationDirections[0] = animationDirection;
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationDirections.Add(animationDirection);
|
||||
}
|
||||
|
||||
if (Singular && _animationSources.Count > 0)
|
||||
{
|
||||
_animationSources[0] = animationSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationSources.Add(animationSource);
|
||||
}
|
||||
|
||||
if (!(Singular && _animationProgresses.Count > 0))
|
||||
{
|
||||
switch (_animationDirections[_animationDirections.Count - 1])
|
||||
{
|
||||
case AnimationDirection.InOutRepeatingIn:
|
||||
case AnimationDirection.InOutIn:
|
||||
case AnimationDirection.In:
|
||||
_animationProgresses.Add(MIN_VALUE);
|
||||
break;
|
||||
case AnimationDirection.InOutRepeatingOut:
|
||||
case AnimationDirection.InOutOut:
|
||||
case AnimationDirection.Out:
|
||||
_animationProgresses.Add(MAX_VALUE);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid AnimationDirection");
|
||||
}
|
||||
}
|
||||
|
||||
if (Singular && _animationDatas.Count > 0)
|
||||
{
|
||||
_animationDatas[0] = data ?? new object[] { };
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationDatas.Add(data ?? new object[] { });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_animationTimer.Start();
|
||||
}
|
||||
|
||||
public void UpdateProgress(int index)
|
||||
{
|
||||
switch (_animationDirections[index])
|
||||
{
|
||||
case AnimationDirection.InOutRepeatingIn:
|
||||
case AnimationDirection.InOutIn:
|
||||
case AnimationDirection.In:
|
||||
IncrementProgress(index);
|
||||
break;
|
||||
case AnimationDirection.InOutRepeatingOut:
|
||||
case AnimationDirection.InOutOut:
|
||||
case AnimationDirection.Out:
|
||||
DecrementProgress(index);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("No AnimationDirection has been set");
|
||||
}
|
||||
}
|
||||
|
||||
private void IncrementProgress(int index)
|
||||
{
|
||||
_animationProgresses[index] += Increment;
|
||||
if (_animationProgresses[index] > MAX_VALUE)
|
||||
{
|
||||
_animationProgresses[index] = MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < GetAnimationCount(); i++)
|
||||
{
|
||||
if (_animationDirections[i] == AnimationDirection.InOutIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingOut) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutOut && _animationProgresses[i] != MAX_VALUE) return;
|
||||
if (_animationDirections[i] == AnimationDirection.In && _animationProgresses[i] != MAX_VALUE) return;
|
||||
}
|
||||
|
||||
_animationTimer.Stop();
|
||||
OnAnimationFinished?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void DecrementProgress(int index)
|
||||
{
|
||||
_animationProgresses[index] -= (_animationDirections[index] == AnimationDirection.InOutOut || _animationDirections[index] == AnimationDirection.InOutRepeatingOut) ? SecondaryIncrement : Increment;
|
||||
if (_animationProgresses[index] < MIN_VALUE)
|
||||
{
|
||||
_animationProgresses[index] = MIN_VALUE;
|
||||
|
||||
for (var i = 0; i < GetAnimationCount(); i++)
|
||||
{
|
||||
if (_animationDirections[i] == AnimationDirection.InOutIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingOut) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutOut && _animationProgresses[i] != MIN_VALUE) return;
|
||||
if (_animationDirections[i] == AnimationDirection.Out && _animationProgresses[i] != MIN_VALUE) return;
|
||||
}
|
||||
|
||||
_animationTimer.Stop();
|
||||
OnAnimationFinished?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
public double GetProgress()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationProgresses.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return GetProgress(0);
|
||||
}
|
||||
|
||||
public double GetProgress(int index)
|
||||
{
|
||||
if (!(index < GetAnimationCount()))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
switch (AnimationType)
|
||||
{
|
||||
case AnimationType.Linear:
|
||||
return AnimationLinear.CalculateProgress(_animationProgresses[index]);
|
||||
case AnimationType.EaseInOut:
|
||||
return AnimationEaseInOut.CalculateProgress(_animationProgresses[index]);
|
||||
case AnimationType.EaseOut:
|
||||
return AnimationEaseOut.CalculateProgress(_animationProgresses[index]);
|
||||
case AnimationType.CustomQuadratic:
|
||||
return AnimationCustomQuadratic.CalculateProgress(_animationProgresses[index]);
|
||||
default:
|
||||
throw new NotImplementedException("The given AnimationType is not implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Point GetSource(int index)
|
||||
{
|
||||
if (!(index < GetAnimationCount()))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
return _animationSources[index];
|
||||
}
|
||||
|
||||
public Point GetSource()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationSources.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return _animationSources[0];
|
||||
}
|
||||
|
||||
public AnimationDirection GetDirection()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationDirections.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return _animationDirections[0];
|
||||
}
|
||||
|
||||
public AnimationDirection GetDirection(int index)
|
||||
{
|
||||
if (!(index < _animationDirections.Count))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
return _animationDirections[index];
|
||||
}
|
||||
|
||||
public object[] GetData()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationDatas.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return _animationDatas[0];
|
||||
}
|
||||
|
||||
public object[] GetData(int index)
|
||||
{
|
||||
if (!(index < _animationDatas.Count))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
return _animationDatas[index];
|
||||
}
|
||||
|
||||
public int GetAnimationCount()
|
||||
{
|
||||
return _animationProgresses.Count;
|
||||
}
|
||||
|
||||
public void SetProgress(double progress)
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationProgresses.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
_animationProgresses[0] = progress;
|
||||
}
|
||||
|
||||
public void SetDirection(AnimationDirection direction)
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationProgresses.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
_animationDirections[0] = direction;
|
||||
}
|
||||
|
||||
public void SetData(object[] data)
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationDatas.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
_animationDatas[0] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user