Animatable.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System.Linq;
  4. using Avalonia.Data;
  5. using System;
  6. using System.Reactive.Linq;
  7. using Avalonia.Collections;
  8. using Avalonia.Animation.Transitions;
  9. using System.Collections.Generic;
  10. using System.Threading;
  11. using System.Collections.Concurrent;
  12. namespace Avalonia.Animation
  13. {
  14. /// <summary>
  15. /// Base class for control which can have property transitions.
  16. /// </summary>
  17. public class Animatable : AvaloniaObject
  18. {
  19. /// <summary>
  20. /// Initializes this <see cref="Animatable"/> object.
  21. /// </summary>
  22. public Animatable()
  23. {
  24. Transitions = new Transitions.Transitions();
  25. AnimatableTimer = Timing.AnimationStateTimer
  26. .Select(p =>
  27. {
  28. if (p == PlayState.Run
  29. && this._playState == PlayState.Run)
  30. return _animationTime++;
  31. else
  32. return _animationTime;
  33. })
  34. .Publish()
  35. .RefCount();
  36. }
  37. /// <summary>
  38. /// The specific animations timer for this control.
  39. /// </summary>
  40. /// <returns></returns>
  41. public IObservable<ulong> AnimatableTimer;
  42. internal void PrepareAnimatableForAnimation()
  43. {
  44. if (!_animationsInitialized)
  45. {
  46. _animationsInitialized = true;
  47. }
  48. }
  49. bool _animationsInitialized = false;
  50. // internal ConcurrentDictionary<int, (int repeatCount, int direction)> _animationStates;
  51. internal ulong _animationTime;
  52. // internal int _iterationTokenCounter;
  53. // internal uint GetIterationToken()
  54. // {
  55. // return (uint)Interlocked.Increment(ref _iterationTokenCounter);
  56. // }
  57. /// <summary>
  58. /// Defines the <see cref="PlayState"/> property.
  59. /// </summary>
  60. public static readonly DirectProperty<Animatable, PlayState> PlayStateProperty =
  61. AvaloniaProperty.RegisterDirect<Animatable, PlayState>(
  62. nameof(PlayState),
  63. o => o.PlayState,
  64. (o, v) => o.PlayState = v);
  65. /// <summary>
  66. /// Gets or sets the state of the animation for this
  67. /// control.
  68. /// </summary>
  69. public PlayState PlayState
  70. {
  71. get { return _playState; }
  72. set { SetAndRaise(PlayStateProperty, ref _playState, value); }
  73. }
  74. private PlayState _playState = PlayState.Run;
  75. /// <summary>
  76. /// Defines the <see cref="Transitions"/> property.
  77. /// </summary>
  78. public static readonly DirectProperty<Animatable, IEnumerable<ITransition>> TransitionsProperty =
  79. AvaloniaProperty.RegisterDirect<Animatable, IEnumerable<ITransition>>(
  80. nameof(Transitions),
  81. o => o.Transitions,
  82. (o, v) => o.Transitions = v);
  83. private IEnumerable<ITransition> _transitions = new AvaloniaList<ITransition>();
  84. /// <summary>
  85. /// Gets or sets the property transitions for the control.
  86. /// </summary>
  87. public IEnumerable<ITransition> Transitions
  88. {
  89. get { return _transitions; }
  90. set { SetAndRaise(TransitionsProperty, ref _transitions, value); }
  91. }
  92. /// <summary>
  93. /// Reacts to a change in a <see cref="AvaloniaProperty"/> value in
  94. /// order to animate the change if a <see cref="ITransition"/> is set for the property.
  95. /// </summary>
  96. /// <param name="e">The event args.</param>
  97. protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e)
  98. {
  99. if (e.Priority != BindingPriority.Animation && Transitions != null)
  100. {
  101. var match = Transitions.FirstOrDefault(x => x.Property == e.Property);
  102. if (match != null)
  103. {
  104. match.Apply(this, e.OldValue, e.NewValue);
  105. }
  106. }
  107. }
  108. }
  109. }