324 lines
8.5 KiB
C#
324 lines
8.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Windows;
|
|
|
|
namespace HandyControl.Media.Animation
|
|
{
|
|
public class GeometryKeyFrameCollection : Freezable, IList
|
|
{
|
|
private List<GeometryKeyFrame> _keyFrames;
|
|
|
|
private static GeometryKeyFrameCollection s_emptyCollection;
|
|
|
|
public GeometryKeyFrameCollection()
|
|
{
|
|
_keyFrames = new List<GeometryKeyFrame>(2);
|
|
}
|
|
|
|
public static GeometryKeyFrameCollection Empty
|
|
{
|
|
get
|
|
{
|
|
if (s_emptyCollection == null)
|
|
{
|
|
var emptyCollection = new GeometryKeyFrameCollection
|
|
{
|
|
_keyFrames = new List<GeometryKeyFrame>(0)
|
|
};
|
|
|
|
emptyCollection.Freeze();
|
|
|
|
s_emptyCollection = emptyCollection;
|
|
}
|
|
|
|
return s_emptyCollection;
|
|
}
|
|
}
|
|
|
|
public new GeometryKeyFrameCollection Clone() => (GeometryKeyFrameCollection)base.Clone();
|
|
|
|
protected override Freezable CreateInstanceCore() => new GeometryKeyFrameCollection();
|
|
|
|
protected override void CloneCore(Freezable sourceFreezable)
|
|
{
|
|
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
|
|
base.CloneCore(sourceFreezable);
|
|
|
|
var count = sourceCollection._keyFrames.Count;
|
|
|
|
_keyFrames = new List<GeometryKeyFrame>(count);
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].Clone();
|
|
_keyFrames.Add(keyFrame);
|
|
OnFreezablePropertyChanged(null, keyFrame);
|
|
}
|
|
}
|
|
|
|
protected override void CloneCurrentValueCore(Freezable sourceFreezable)
|
|
{
|
|
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
|
|
base.CloneCurrentValueCore(sourceFreezable);
|
|
|
|
var count = sourceCollection._keyFrames.Count;
|
|
|
|
_keyFrames = new List<GeometryKeyFrame>(count);
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].CloneCurrentValue();
|
|
_keyFrames.Add(keyFrame);
|
|
OnFreezablePropertyChanged(null, keyFrame);
|
|
}
|
|
}
|
|
|
|
protected override void GetAsFrozenCore(Freezable sourceFreezable)
|
|
{
|
|
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
|
|
base.GetAsFrozenCore(sourceFreezable);
|
|
|
|
var count = sourceCollection._keyFrames.Count;
|
|
|
|
_keyFrames = new List<GeometryKeyFrame>(count);
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].GetAsFrozen();
|
|
_keyFrames.Add(keyFrame);
|
|
OnFreezablePropertyChanged(null, keyFrame);
|
|
}
|
|
}
|
|
|
|
protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable)
|
|
{
|
|
var sourceCollection = (GeometryKeyFrameCollection)sourceFreezable;
|
|
base.GetCurrentValueAsFrozenCore(sourceFreezable);
|
|
|
|
var count = sourceCollection._keyFrames.Count;
|
|
|
|
_keyFrames = new List<GeometryKeyFrame>(count);
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var keyFrame = (GeometryKeyFrame)sourceCollection._keyFrames[i].GetCurrentValueAsFrozen();
|
|
_keyFrames.Add(keyFrame);
|
|
OnFreezablePropertyChanged(null, keyFrame);
|
|
}
|
|
}
|
|
|
|
protected override bool FreezeCore(bool isChecking)
|
|
{
|
|
var canFreeze = base.FreezeCore(isChecking);
|
|
|
|
for (var i = 0; i < _keyFrames.Count && canFreeze; i++)
|
|
{
|
|
canFreeze &= Freeze(_keyFrames[i], isChecking);
|
|
}
|
|
|
|
return canFreeze;
|
|
}
|
|
|
|
public IEnumerator GetEnumerator()
|
|
{
|
|
ReadPreamble();
|
|
|
|
return _keyFrames.GetEnumerator();
|
|
}
|
|
|
|
void ICollection.CopyTo(Array array, int index)
|
|
{
|
|
ReadPreamble();
|
|
|
|
((ICollection)_keyFrames).CopyTo(array, index);
|
|
}
|
|
|
|
public void CopyTo(GeometryKeyFrame[] array, int index)
|
|
{
|
|
ReadPreamble();
|
|
|
|
_keyFrames.CopyTo(array, index);
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get
|
|
{
|
|
ReadPreamble();
|
|
|
|
return _keyFrames.Count;
|
|
}
|
|
}
|
|
|
|
public object SyncRoot
|
|
{
|
|
get
|
|
{
|
|
ReadPreamble();
|
|
|
|
return ((ICollection)_keyFrames).SyncRoot;
|
|
}
|
|
}
|
|
|
|
public bool IsSynchronized
|
|
{
|
|
get
|
|
{
|
|
ReadPreamble();
|
|
|
|
return IsFrozen || Dispatcher != null;
|
|
}
|
|
}
|
|
|
|
int IList.Add(object keyFrame) => Add((GeometryKeyFrame)keyFrame);
|
|
|
|
public int Add(GeometryKeyFrame keyFrame)
|
|
{
|
|
if (keyFrame == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(keyFrame));
|
|
}
|
|
|
|
WritePreamble();
|
|
|
|
OnFreezablePropertyChanged(null, keyFrame);
|
|
_keyFrames.Add(keyFrame);
|
|
|
|
WritePostscript();
|
|
|
|
return _keyFrames.Count - 1;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
WritePreamble();
|
|
|
|
if (_keyFrames.Count <= 0) return;
|
|
|
|
foreach (var frame in _keyFrames)
|
|
{
|
|
OnFreezablePropertyChanged(frame, null);
|
|
}
|
|
|
|
_keyFrames.Clear();
|
|
|
|
WritePostscript();
|
|
}
|
|
|
|
bool IList.Contains(object keyFrame) => Contains((GeometryKeyFrame)keyFrame);
|
|
|
|
public bool Contains(GeometryKeyFrame keyFrame)
|
|
{
|
|
ReadPreamble();
|
|
|
|
return _keyFrames.Contains(keyFrame);
|
|
}
|
|
|
|
int IList.IndexOf(object keyFrame) => IndexOf((GeometryKeyFrame)keyFrame);
|
|
|
|
public int IndexOf(GeometryKeyFrame keyFrame)
|
|
{
|
|
ReadPreamble();
|
|
|
|
return _keyFrames.IndexOf(keyFrame);
|
|
}
|
|
|
|
void IList.Insert(int index, object keyFrame) => Insert(index, (GeometryKeyFrame)keyFrame);
|
|
|
|
public void Insert(int index, GeometryKeyFrame keyFrame)
|
|
{
|
|
if (keyFrame == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(keyFrame));
|
|
}
|
|
|
|
WritePreamble();
|
|
|
|
OnFreezablePropertyChanged(null, keyFrame);
|
|
_keyFrames.Insert(index, keyFrame);
|
|
|
|
WritePostscript();
|
|
}
|
|
|
|
void IList.Remove(object keyFrame) => Remove((GeometryKeyFrame)keyFrame);
|
|
|
|
public void Remove(GeometryKeyFrame keyFrame)
|
|
{
|
|
WritePreamble();
|
|
|
|
if (_keyFrames.Contains(keyFrame))
|
|
{
|
|
OnFreezablePropertyChanged(keyFrame, null);
|
|
_keyFrames.Remove(keyFrame);
|
|
|
|
WritePostscript();
|
|
}
|
|
}
|
|
|
|
public void RemoveAt(int index)
|
|
{
|
|
WritePreamble();
|
|
|
|
OnFreezablePropertyChanged(_keyFrames[index], null);
|
|
_keyFrames.RemoveAt(index);
|
|
|
|
WritePostscript();
|
|
}
|
|
|
|
object IList.this[int index]
|
|
{
|
|
get => this[index];
|
|
set => this[index] = (GeometryKeyFrame)value;
|
|
}
|
|
|
|
public GeometryKeyFrame this[int index]
|
|
{
|
|
get
|
|
{
|
|
ReadPreamble();
|
|
|
|
return _keyFrames[index];
|
|
}
|
|
set
|
|
{
|
|
if (value == null)
|
|
{
|
|
throw new ArgumentNullException(string.Format(CultureInfo.InvariantCulture, "DoubleKeyFrameCollection[{0}]", index));
|
|
}
|
|
|
|
WritePreamble();
|
|
|
|
if (value != _keyFrames[index])
|
|
{
|
|
OnFreezablePropertyChanged(_keyFrames[index], value);
|
|
_keyFrames[index] = value;
|
|
|
|
WritePostscript();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsReadOnly
|
|
{
|
|
get
|
|
{
|
|
ReadPreamble();
|
|
|
|
return IsFrozen;
|
|
}
|
|
}
|
|
|
|
public bool IsFixedSize
|
|
{
|
|
get
|
|
{
|
|
ReadPreamble();
|
|
|
|
return IsFrozen;
|
|
}
|
|
}
|
|
}
|
|
}
|