This commit is contained in:
ww-rm
2025-04-05 10:10:04 +08:00
parent 153d3603d2
commit 6f032bdd05
3 changed files with 36 additions and 17 deletions

View File

@@ -46,14 +46,12 @@ namespace SpineViewer.Spine
/// <summary> /// <summary>
/// 轨道属性描述符, 实现对属性的读取和赋值 /// 轨道属性描述符, 实现对属性的读取和赋值
/// </summary> /// </summary>
/// <param name="spine">关联的 Spine 对象</param>
/// <param name="i">轨道索引</param> /// <param name="i">轨道索引</param>
public class TrackWrapperPropertyDescriptor(Spine spine, int i) : PropertyDescriptor($"Track{i}", [new DisplayNameAttribute($"轨道 {i}")]) public class TrackWrapperPropertyDescriptor(int i) : PropertyDescriptor($"Track{i}", [new DisplayNameAttribute($"轨道 {i}")])
{ {
private readonly Spine spine = spine;
private readonly int idx = i; private readonly int idx = i;
public override Type ComponentType => typeof(AnimationTracksType); public override Type ComponentType => typeof(AnimationTracks);
public override bool IsReadOnly => false; public override bool IsReadOnly => false;
public override Type PropertyType => typeof(TrackWrapper); public override Type PropertyType => typeof(TrackWrapper);
public override bool CanResetValue(object component) => false; public override bool CanResetValue(object component) => false;
@@ -63,14 +61,23 @@ namespace SpineViewer.Spine
/// <summary> /// <summary>
/// 得到一个轨道包装类, 允许用户查看或者修改具体的属性值, 这个地方决定了在面板上看到的是一个对象及其属性 /// 得到一个轨道包装类, 允许用户查看或者修改具体的属性值, 这个地方决定了在面板上看到的是一个对象及其属性
/// </summary> /// </summary>
public override object? GetValue(object? component) => new TrackWrapper(spine, idx); public override object? GetValue(object? component)
{
if (component is AnimationTracks tracks)
return tracks.GetTrackWrapper(idx);
return null;
}
/// <summary> /// <summary>
/// 允许通过字符串赋值修改该轨道的动画, 这里决定了当其他地方的调用 (比如 Converter) 通过 value 来设置属性值的时候应该怎么处理 /// 允许通过字符串赋值修改该轨道的动画, 这里决定了当其他地方的调用 (比如 Converter) 通过 value 来设置属性值的时候应该怎么处理
/// </summary> /// </summary>
public override void SetValue(object? component, object? value) public override void SetValue(object? component, object? value)
{ {
if (value is string s) spine.SetAnimation(idx, s); if (component is AnimationTracks tracks)
{
if (value is string s)
tracks.Spine.SetAnimation(idx, s); // tracks.SetTrackWrapper(idx, s);
}
} }
} }
@@ -78,10 +85,12 @@ namespace SpineViewer.Spine
/// AnimationTracks 动态类型包装类, 用于提供对 Spine 对象多轨道动画的访问能力, 不同轨道将动态生成属性 /// AnimationTracks 动态类型包装类, 用于提供对 Spine 对象多轨道动画的访问能力, 不同轨道将动态生成属性
/// </summary> /// </summary>
/// <param name="spine">关联的 Spine 对象</param> /// <param name="spine">关联的 Spine 对象</param>
public class AnimationTracksType(Spine spine) : ICustomTypeDescriptor public class AnimationTracks(Spine spine) : ICustomTypeDescriptor
{ {
private readonly Dictionary<int, TrackWrapperPropertyDescriptor> pdCache = []; private static readonly Dictionary<int, TrackWrapperPropertyDescriptor> pdCache = [];
public Spine Spine { get; } = spine; public Spine Spine { get; } = spine;
private readonly Dictionary<int, TrackWrapper> trackWrapperProperties = [];
// XXX: 必须实现 ICustomTypeDescriptor 接口, 不能继承 CustomTypeDescriptor, 似乎继承下来的东西会有问题, 导致某些调用不正确 // XXX: 必须实现 ICustomTypeDescriptor 接口, 不能继承 CustomTypeDescriptor, 似乎继承下来的东西会有问题, 导致某些调用不正确
@@ -102,12 +111,22 @@ namespace SpineViewer.Spine
foreach (var i in Spine.GetTrackIndices()) foreach (var i in Spine.GetTrackIndices())
{ {
if (!pdCache.ContainsKey(i)) if (!pdCache.ContainsKey(i))
pdCache[i] = new TrackWrapperPropertyDescriptor(Spine, i); pdCache[i] = new TrackWrapperPropertyDescriptor(i);
props.Add(pdCache[i]); props.Add(pdCache[i]);
} }
return new PropertyDescriptorCollection(props.ToArray()); return new PropertyDescriptorCollection(props.ToArray());
} }
/// <summary>
/// 访问 TrackWrapper 属性 <c>AnimationTracks.Track{i}</c>
/// </summary>
public TrackWrapper GetTrackWrapper(int i)
{
if (!trackWrapperProperties.ContainsKey(i))
trackWrapperProperties[i] = new TrackWrapper(Spine, i);
return trackWrapperProperties[i];
}
/// <summary> /// <summary>
/// 在属性面板悬停可以按轨道顺序显示动画名称 /// 在属性面板悬停可以按轨道顺序显示动画名称
/// </summary> /// </summary>
@@ -115,10 +134,10 @@ namespace SpineViewer.Spine
public override bool Equals(object? obj) public override bool Equals(object? obj)
{ {
if (obj is AnimationTracksType tracks) return ToString() == tracks.ToString(); if (obj is AnimationTracks tracks) return ToString() == tracks.ToString();
return base.Equals(obj); return base.Equals(obj);
} }
public override int GetHashCode() => (typeof(AnimationTracksType).FullName + ToString()).GetHashCode(); public override int GetHashCode() => (typeof(AnimationTracks).FullName + ToString()).GetHashCode();
} }
} }

View File

@@ -242,7 +242,7 @@ namespace SpineViewer.Spine
[Editor(typeof(AnimationTracksEditor), typeof(UITypeEditor))] [Editor(typeof(AnimationTracksEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))] [TypeConverter(typeof(ExpandableObjectConverter))]
[Category("[3] "), DisplayName("")] [Category("[3] "), DisplayName("")]
public AnimationTracksType AnimationTracks { get; private set; } public AnimationTracks AnimationTracks { get; private set; }
/// <summary> /// <summary>
/// 包含的所有皮肤名称 /// 包含的所有皮肤名称

View File

@@ -89,14 +89,14 @@ namespace SpineViewer.Spine
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context) public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context)
{ {
if (context.Instance is AnimationTracksType animTrack) if (context.Instance is AnimationTracks tracks)
{ {
return new StandardValuesCollection(animTrack.Spine.AnimationNames); return new StandardValuesCollection(tracks.Spine.AnimationNames);
} }
else if (context.Instance is object[] instances && instances.All(x => x is AnimationTracksType)) else if (context.Instance is object[] instances && instances.All(x => x is AnimationTracks))
{ {
// XXX: 这里不知道为啥总是会得到 object[] 类型而不是具体的 AnimationTracksType[] 类型 // XXX: 这里不知道为啥总是会得到 object[] 类型而不是具体的类型
var animTracks = instances.Cast<AnimationTracksType>().ToArray(); var animTracks = instances.Cast<AnimationTracks>().ToArray();
if (animTracks.Length > 0) if (animTracks.Length > 0)
{ {
IEnumerable<string> common = animTracks[0].Spine.AnimationNames; IEnumerable<string> common = animTracks[0].Spine.AnimationNames;