diff --git a/SpineViewer/Spine/Implementations/Spine/Spine21.cs b/SpineViewer/Spine/Implementations/Spine/Spine21.cs index b599563..2142500 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine21.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine21.cs @@ -75,13 +75,19 @@ namespace SpineViewer.Spine.Implementations.Spine } } + foreach (var skin in skeletonData.Skins) + skinNames.Add(skin.Name); + animationStateData = new AnimationStateData(skeletonData); skeleton = new Skeleton(skeletonData); animationState = new AnimationState(animationStateData); foreach (var anime in skeletonData.Animations) animationNames.Add(anime.Name); - CurrentAnimation = DefaultAnimationName; + + // 取最后一个作为初始, 尽可能去显示非默认的内容 + CurrentAnimation = animationNames.Last(); + CurrentSkin = skinNames.Last(); } protected override void Dispose(bool disposing) @@ -185,6 +191,18 @@ namespace SpineViewer.Spine.Implementations.Spine } } + public override string CurrentSkin + { + get => skeleton.Skin.Name; + set + { + if (!skinNames.Contains(value)) + return; + skeleton.SetSkin(value); + Update(0); + } + } + public override RectangleF Bounds { get diff --git a/SpineViewer/Spine/Implementations/Spine/Spine36.cs b/SpineViewer/Spine/Implementations/Spine/Spine36.cs index 9bf26c9..05d31f0 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine36.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine36.cs @@ -74,13 +74,19 @@ namespace SpineViewer.Spine.Implementations.Spine } } + foreach (var skin in skeletonData.Skins) + skinNames.Add(skin.Name); + animationStateData = new AnimationStateData(skeletonData); skeleton = new Skeleton(skeletonData); animationState = new AnimationState(animationStateData); foreach (var anime in skeletonData.Animations) animationNames.Add(anime.Name); - CurrentAnimation = DefaultAnimationName; + + // 取最后一个作为初始, 尽可能去显示非默认的内容 + CurrentAnimation = animationNames.Last(); + CurrentSkin = skinNames.Last(); } protected override void Dispose(bool disposing) @@ -183,6 +189,18 @@ namespace SpineViewer.Spine.Implementations.Spine } } + public override string CurrentSkin + { + get => skeleton.Skin.Name; + set + { + if (!skinNames.Contains(value)) + return; + skeleton.SetSkin(value); + Update(0); + } + } + public override RectangleF Bounds { get diff --git a/SpineViewer/Spine/Implementations/Spine/Spine37.cs b/SpineViewer/Spine/Implementations/Spine/Spine37.cs index 6fbe301..4f49b39 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine37.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine37.cs @@ -72,6 +72,9 @@ namespace SpineViewer.Spine.Implementations.Spine } } + foreach (var skin in skeletonData.Skins) + skinNames.Add(skin.Name); + animationStateData = new AnimationStateData(skeletonData); skeleton = new Skeleton(skeletonData); animationState = new AnimationState(animationStateData); @@ -79,7 +82,9 @@ namespace SpineViewer.Spine.Implementations.Spine foreach (var anime in skeletonData.Animations) animationNames.Add(anime.Name); - CurrentAnimation = DefaultAnimationName; + // 取最后一个作为初始, 尽可能去显示非默认的内容 + CurrentAnimation = animationNames.Last(); + CurrentSkin = skinNames.Last(); } protected override void Dispose(bool disposing) @@ -190,6 +195,18 @@ namespace SpineViewer.Spine.Implementations.Spine } } + public override string CurrentSkin + { + get => skeleton.Skin.Name; + set + { + if (!skinNames.Contains(value)) + return; + skeleton.SetSkin(value); + Update(0); + } + } + public override RectangleF Bounds { get diff --git a/SpineViewer/Spine/Implementations/Spine/Spine38.cs b/SpineViewer/Spine/Implementations/Spine/Spine38.cs index 3af8db3..9b7e9b9 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine38.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine38.cs @@ -75,6 +75,9 @@ namespace SpineViewer.Spine.Implementations.Spine } } + foreach (var skin in skeletonData.Skins) + skinNames.Add(skin.Name); + animationStateData = new AnimationStateData(skeletonData); skeleton = new Skeleton(skeletonData); animationState = new AnimationState(animationStateData); @@ -82,7 +85,9 @@ namespace SpineViewer.Spine.Implementations.Spine foreach (var anime in skeletonData.Animations) animationNames.Add(anime.Name); - CurrentAnimation = DefaultAnimationName; + // 取最后一个作为初始, 尽可能去显示非默认的内容 + CurrentAnimation = animationNames.Last(); + CurrentSkin = skinNames.Last(); } protected override void Dispose(bool disposing) @@ -193,6 +198,18 @@ namespace SpineViewer.Spine.Implementations.Spine } } + public override string CurrentSkin + { + get => skeleton.Skin.Name; + set + { + if (!skinNames.Contains(value)) + return; + skeleton.SetSkin(value); + Update(0); + } + } + public override RectangleF Bounds { get diff --git a/SpineViewer/Spine/Implementations/Spine/Spine40.cs b/SpineViewer/Spine/Implementations/Spine/Spine40.cs index c405a1a..f0c6ac2 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine40.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine40.cs @@ -74,6 +74,9 @@ namespace SpineViewer.Spine.Implementations.Spine } } + foreach (var skin in skeletonData.Skins) + skinNames.Add(skin.Name); + animationStateData = new AnimationStateData(skeletonData); skeleton = new Skeleton(skeletonData); animationState = new AnimationState(animationStateData); @@ -81,7 +84,9 @@ namespace SpineViewer.Spine.Implementations.Spine foreach (var anime in skeletonData.Animations) animationNames.Add(anime.Name); - CurrentAnimation = DefaultAnimationName; + // 取最后一个作为初始, 尽可能去显示非默认的内容 + CurrentAnimation = animationNames.Last(); + CurrentSkin = skinNames.Last(); } protected override void Dispose(bool disposing) @@ -192,6 +197,18 @@ namespace SpineViewer.Spine.Implementations.Spine } } + public override string CurrentSkin + { + get => skeleton.Skin.Name; + set + { + if (!skinNames.Contains(value)) + return; + skeleton.SetSkin(value); + Update(0); + } + } + public override RectangleF Bounds { get diff --git a/SpineViewer/Spine/Implementations/Spine/Spine41.cs b/SpineViewer/Spine/Implementations/Spine/Spine41.cs index b42f7fa..6bfb7ee 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine41.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine41.cs @@ -74,6 +74,9 @@ namespace SpineViewer.Spine.Implementations.Spine } } + foreach (var skin in skeletonData.Skins) + skinNames.Add(skin.Name); + animationStateData = new AnimationStateData(skeletonData); skeleton = new Skeleton(skeletonData); animationState = new AnimationState(animationStateData); @@ -81,7 +84,9 @@ namespace SpineViewer.Spine.Implementations.Spine foreach (var anime in skeletonData.Animations) animationNames.Add(anime.Name); - CurrentAnimation = DefaultAnimationName; + // 取最后一个作为初始, 尽可能去显示非默认的内容 + CurrentAnimation = animationNames.Last(); + CurrentSkin = skinNames.Last(); } protected override void Dispose(bool disposing) @@ -192,6 +197,18 @@ namespace SpineViewer.Spine.Implementations.Spine } } + public override string CurrentSkin + { + get => skeleton.Skin.Name; + set + { + if (!skinNames.Contains(value)) + return; + skeleton.SetSkin(value); + Update(0); + } + } + public override RectangleF Bounds { get diff --git a/SpineViewer/Spine/Implementations/Spine/Spine42.cs b/SpineViewer/Spine/Implementations/Spine/Spine42.cs index e101cb0..3d6b3ae 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine42.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine42.cs @@ -74,6 +74,9 @@ namespace SpineViewer.Spine.Implementations.Spine } } + foreach (var skin in skeletonData.Skins) + skinNames.Add(skin.Name); + animationStateData = new AnimationStateData(skeletonData); skeleton = new Skeleton(skeletonData); animationState = new AnimationState(animationStateData); @@ -81,7 +84,9 @@ namespace SpineViewer.Spine.Implementations.Spine foreach (var anime in skeletonData.Animations) animationNames.Add(anime.Name); - CurrentAnimation = DefaultAnimationName; + // 取最后一个作为初始, 尽可能去显示非默认的内容 + CurrentAnimation = animationNames.Last(); + CurrentSkin = skinNames.Last(); } protected override void Dispose(bool disposing) @@ -192,6 +197,18 @@ namespace SpineViewer.Spine.Implementations.Spine } } + public override string CurrentSkin + { + get => skeleton.Skin.Name; + set + { + if (!skinNames.Contains(value)) + return; + skeleton.SetSkin(value); + Update(0); + } + } + public override RectangleF Bounds { get diff --git a/SpineViewer/Spine/Spine.cs b/SpineViewer/Spine/Spine.cs index ded889b..2ebb64a 100644 --- a/SpineViewer/Spine/Spine.cs +++ b/SpineViewer/Spine/Spine.cs @@ -287,16 +287,18 @@ namespace SpineViewer.Spine #endregion - #region 属性 | 画面 + #region 属性 | 渲染 /// /// 是否使用预乘Alpha /// - [Category("画面"), DisplayName("预乘Alpha通道")] + [Category("渲染"), DisplayName("预乘Alpha通道")] public bool UsePremultipliedAlpha { get; set; } = true; #endregion + #region 属性 | 动画 + /// /// 包含的所有动画名称 /// @@ -304,14 +306,6 @@ namespace SpineViewer.Spine public ReadOnlyCollection AnimationNames { get => animationNames.AsReadOnly(); } protected List animationNames = [EMPTY_ANIMATION]; - /// - /// 默认动画名称 - /// - [Browsable(false)] - public string DefaultAnimationName { get => animationNames.Last(); } - - #region 属性 | 动画 - /// /// 当前动画名称, 如果设置的动画不存在则忽略 /// @@ -325,6 +319,20 @@ namespace SpineViewer.Spine [Category("动画"), DisplayName("当前动画时长")] public float CurrentAnimationDuration { get => GetAnimationDuration(CurrentAnimation); } + /// + /// 包含的所有皮肤名称 + /// + [Browsable(false)] + public ReadOnlyCollection SkinNames { get => skinNames.AsReadOnly(); } + protected List skinNames = []; + + /// + /// 当前皮肤名称, 如果设置的皮肤不存在则忽略 + /// + [TypeConverter(typeof(SkinConverter))] + [Category("动画"), DisplayName("当前皮肤")] + public abstract string CurrentSkin { get; set; } + #endregion /// diff --git a/SpineViewer/Spine/TypeConverter.cs b/SpineViewer/Spine/TypeConverter.cs index 5dc3c21..5176a9f 100644 --- a/SpineViewer/Spine/TypeConverter.cs +++ b/SpineViewer/Spine/TypeConverter.cs @@ -58,4 +58,38 @@ namespace SpineViewer.Spine return base.GetStandardValues(context); } } + + public class SkinConverter : StringConverter + { + public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) + { + // 支持标准值列表 + return true; + } + + public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) + { + // 排他模式,只有下拉列表中的值可选 + return true; + } + + public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context) + { + if (context?.Instance is Spine obj) + { + return new StandardValuesCollection(obj.SkinNames); + } + else if (context?.Instance is Spine[] spines) + { + if (spines.Length > 0) + { + IEnumerable common = spines[0].SkinNames; + foreach (var spine in spines.Skip(1)) + common = common.Intersect(spine.SkinNames); + return new StandardValuesCollection(common.ToArray()); + } + } + return base.GetStandardValues(context); + } + } }