Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3cd0b9349 | ||
|
|
1c545b8c37 | ||
|
|
d660dd1c4a | ||
|
|
9c0acf7302 | ||
|
|
415df555c7 | ||
|
|
5ef13239da | ||
|
|
13ef873650 | ||
|
|
78b9834f6c | ||
|
|
672a695b20 | ||
|
|
e9951ed79a | ||
|
|
0c16b2f104 | ||
|
|
7628075420 | ||
|
|
6f896bdaad | ||
|
|
98930db4b6 | ||
|
|
c7493372e9 |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,5 +1,21 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.15.15
|
||||
|
||||
- 增加报错信息
|
||||
- 导入后自动选中最后一项
|
||||
|
||||
## v0.15.14
|
||||
|
||||
- 将预览画面的首选项移动至上一次状态参数中
|
||||
- 增加预览画面像素的自动保存和恢复
|
||||
- 增加日志启动时的版本号输出
|
||||
|
||||
## v0.15.13
|
||||
|
||||
- 增加程序布局自动存储和还原
|
||||
- 增加部分预览画面首选项
|
||||
|
||||
## v0.15.12
|
||||
|
||||
- 增加单个模型和单个轨道的时间因子
|
||||
|
||||
@@ -30,8 +30,15 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -41,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -52,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -61,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -30,8 +30,15 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -41,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -52,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -61,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -30,8 +30,15 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -41,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -52,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -61,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -30,8 +30,15 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -41,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -52,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -61,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -30,8 +30,15 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -41,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -52,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -61,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -31,8 +31,15 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -42,8 +49,9 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -53,8 +61,9 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +71,8 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -30,10 +30,16 @@ namespace Spine.Implementations.SpineWrappers.V40
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
// 加载 skel
|
||||
try
|
||||
{
|
||||
if (Utf8Validator.IsUtf8(skelPath))
|
||||
@@ -42,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V40
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -53,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V40
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V40
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -30,10 +30,16 @@ namespace Spine.Implementations.SpineWrappers.V41
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
// 加载 skel
|
||||
try
|
||||
{
|
||||
if (Utf8Validator.IsUtf8(skelPath))
|
||||
@@ -42,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V41
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -53,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V41
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V41
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -30,10 +30,16 @@ namespace Spine.Implementations.SpineWrappers.V42
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
try { _atlas = new Atlas(atlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
_atlas = new Atlas(atlasPath, textureLoader);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
// 加载 skel
|
||||
try
|
||||
{
|
||||
if (Utf8Validator.IsUtf8(skelPath))
|
||||
@@ -42,8 +48,9 @@ namespace Spine.Implementations.SpineWrappers.V42
|
||||
{
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -53,8 +60,9 @@ namespace Spine.Implementations.SpineWrappers.V42
|
||||
{
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +70,8 @@ namespace Spine.Implementations.SpineWrappers.V42
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}", ex);
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
// 加载动画数据
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.15.12</Version>
|
||||
<Version>0.15.15</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -115,8 +115,9 @@ namespace Spine
|
||||
{
|
||||
_data = SpineObjectData.New(Version, skelPath, atlasPath, textureLoader);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load spine with version '{version}'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
@@ -17,6 +18,8 @@ namespace Spine.SpineWrappers
|
||||
ISpineObjectData,
|
||||
IDisposable
|
||||
{
|
||||
protected static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 构建版本对象
|
||||
/// </summary>
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace SpineViewer
|
||||
{
|
||||
InitializeLogConfiguration();
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
_logger.Info("Application Started");
|
||||
_logger.Info("Application Started, v{0}", Version);
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
|
||||
{
|
||||
|
||||
40
SpineViewer/Models/LastStateModel.cs
Normal file
40
SpineViewer/Models/LastStateModel.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace SpineViewer.Models
|
||||
{
|
||||
public class LastStateModel
|
||||
{
|
||||
#region 画面布局状态
|
||||
|
||||
public double WindowLeft { get; set; }
|
||||
public double WindowTop { get; set; }
|
||||
public double WindowWidth { get; set; }
|
||||
public double WindowHeight { get; set; }
|
||||
public WindowState WindowState { get; set; }
|
||||
|
||||
public double RootGridCol0Width { get; set; }
|
||||
public double ModelListRow0Height { get; set; }
|
||||
public double ExplorerGridRow0Height { get; set; }
|
||||
public double RightPanelGridRow0Height { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region 预览画面状态
|
||||
|
||||
public uint ResolutionX { get; set; } = 1500;
|
||||
public uint ResolutionY { get; set; } = 1000;
|
||||
public uint MaxFps { get; set; } = 30;
|
||||
public float Speed { get; set; } = 1f;
|
||||
public bool ShowAxis { get; set; } = true;
|
||||
public Color BackgroundColor { get; set; } = Color.FromRgb(105, 105, 105);
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -229,6 +229,8 @@
|
||||
|
||||
<s:String x:Key="Str_SpineLoadPreference">Model Loading Options</s:String>
|
||||
|
||||
<s:String x:Key="Str_RendererPreference">Preview Options</s:String>
|
||||
|
||||
<s:String x:Key="Str_AppPreference">Application Options</s:String>
|
||||
<s:String x:Key="Str_Language">Language</s:String>
|
||||
|
||||
|
||||
@@ -229,6 +229,8 @@
|
||||
|
||||
<s:String x:Key="Str_SpineLoadPreference">モデル読み込みオプション</s:String>
|
||||
|
||||
<s:String x:Key="Str_RendererPreference">プレビュー画面オプション</s:String>
|
||||
|
||||
<s:String x:Key="Str_AppPreference">アプリケーションプション</s:String>
|
||||
<s:String x:Key="Str_Language">言語</s:String>
|
||||
|
||||
|
||||
@@ -229,6 +229,8 @@
|
||||
|
||||
<s:String x:Key="Str_SpineLoadPreference">模型加载选项</s:String>
|
||||
|
||||
<s:String x:Key="Str_RendererPreference">预览画面选项</s:String>
|
||||
|
||||
<s:String x:Key="Str_AppPreference">应用程序选项</s:String>
|
||||
<s:String x:Key="Str_Language">语言</s:String>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.15.12</Version>
|
||||
<Version>0.15.15</Version>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -86,6 +86,14 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
/// </summary>
|
||||
public event NotifyCollectionChangedEventHandler? RequestSelectionChanging;
|
||||
|
||||
public void SetResolution(uint x, uint y)
|
||||
{
|
||||
var lastRes = _renderer.Resolution;
|
||||
_renderer.Resolution = new(x, y);
|
||||
if (lastRes.X != x) OnPropertyChanged(nameof(ResolutionX));
|
||||
if (lastRes.Y != y) OnPropertyChanged(nameof(ResolutionY));
|
||||
}
|
||||
|
||||
public uint ResolutionX
|
||||
{
|
||||
get => _renderer.Resolution.X;
|
||||
@@ -455,8 +463,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
set
|
||||
{
|
||||
ResolutionX = value.ResolutionX;
|
||||
ResolutionY = value.ResolutionY;
|
||||
SetResolution(value.ResolutionX, value.ResolutionY);
|
||||
CenterX = value.CenterX;
|
||||
CenterY = value.CenterY;
|
||||
Zoom = value.Zoom;
|
||||
|
||||
@@ -11,6 +11,7 @@ using SpineViewer.ViewModels.Exporters;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -45,6 +46,11 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
_customFFmpegExporterViewModel = new(_vmMain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求选中项发生变化
|
||||
/// </summary>
|
||||
public event NotifyCollectionChangedEventHandler? RequestSelectionChanging;
|
||||
|
||||
/// <summary>
|
||||
/// 单帧导出 ViewModel
|
||||
/// </summary>
|
||||
@@ -489,6 +495,19 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
{
|
||||
var sp = new SpineObjectModel(skelPath, atlasPath);
|
||||
lock (_spineObjectModels.Lock) _spineObjectModels.Add(sp);
|
||||
if (Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Reset));
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Add, sp));
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Reset));
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Add, sp));
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -505,6 +524,19 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
{
|
||||
var sp = new SpineObjectModel(cfg);
|
||||
lock (_spineObjectModels.Lock) _spineObjectModels.Add(sp);
|
||||
if (Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Reset));
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Add, sp));
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Reset));
|
||||
RequestSelectionChanging?.Invoke(this, new(NotifyCollectionChangedAction.Add, sp));
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1">
|
||||
<Grid>
|
||||
<Grid x:Name="_rootGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
<!-- 模型列表页 -->
|
||||
<TabItem Header="{DynamicResource Str_SpineObject}">
|
||||
<Grid>
|
||||
<Grid x:Name="_modelListGrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
@@ -578,7 +578,7 @@
|
||||
|
||||
<!-- 浏览页 -->
|
||||
<TabItem Header="{DynamicResource Str_Explorer}" DataContext="{Binding ExplorerListViewModel}">
|
||||
<Grid>
|
||||
<Grid x:Name="_explorerGrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
@@ -785,14 +785,14 @@
|
||||
<GridSplitter Grid.Column="1" ResizeDirection="Columns"/>
|
||||
|
||||
<Border Grid.Column="2">
|
||||
<Grid>
|
||||
<Grid x:Name="_rightPanelGrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="5*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid >
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
|
||||
@@ -3,12 +3,15 @@ using NLog;
|
||||
using NLog.Layouts;
|
||||
using NLog.Targets;
|
||||
using Spine;
|
||||
using SpineViewer.Models;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.ViewModels.MainWindow;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
@@ -26,6 +29,11 @@ namespace SpineViewer.Views;
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// 上一次状态文件保存路径
|
||||
/// </summary>
|
||||
public static readonly string LastStateFilePath = Path.Combine(Path.GetDirectoryName(Environment.ProcessPath), "laststate.json");
|
||||
|
||||
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private ListViewItem? _listViewDragSourceItem = null;
|
||||
private Point _listViewDragSourcePoint;
|
||||
@@ -38,8 +46,8 @@ public partial class MainWindow : Window
|
||||
InitializeLogConfiguration();
|
||||
_vm = new (_renderPanel);
|
||||
DataContext = _vm;
|
||||
_vm.SpineObjectListViewModel.RequestSelectionChanging += SpinesListView_RequestSelectionChanging;
|
||||
_vm.SFMLRendererViewModel.RequestSelectionChanging += SpinesListView_RequestSelectionChanging;
|
||||
|
||||
Loaded += MainWindow_Loaded;
|
||||
Closed += MainWindow_Closed;
|
||||
}
|
||||
@@ -53,8 +61,7 @@ public partial class MainWindow : Window
|
||||
_renderPanel.CanvasMouseButtonReleased += vm.CanvasMouseButtonReleased;
|
||||
|
||||
// 设置默认参数并启动渲染
|
||||
vm.ResolutionX = 1500;
|
||||
vm.ResolutionY = 1000;
|
||||
vm.SetResolution(1500, 1000);
|
||||
vm.Zoom = 0.75f;
|
||||
vm.CenterX = 0;
|
||||
vm.CenterY = 0;
|
||||
@@ -64,10 +71,14 @@ public partial class MainWindow : Window
|
||||
|
||||
// 加载首选项
|
||||
_vm.PreferenceViewModel.LoadPreference();
|
||||
|
||||
LoadLastState();
|
||||
}
|
||||
|
||||
private void MainWindow_Closed(object? sender, EventArgs e)
|
||||
{
|
||||
SaveLastState();
|
||||
|
||||
var vm = _vm.SFMLRendererViewModel;
|
||||
vm.StopRender();
|
||||
}
|
||||
@@ -100,6 +111,63 @@ public partial class MainWindow : Window
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
private void LoadLastState()
|
||||
{
|
||||
if (JsonHelper.Deserialize<LastStateModel>(LastStateFilePath, out var m, true))
|
||||
{
|
||||
Left = m.WindowLeft;
|
||||
Top = m.WindowTop;
|
||||
Width = m.WindowWidth;
|
||||
Height = m.WindowHeight;
|
||||
if (m.WindowState == WindowState.Maximized)
|
||||
{
|
||||
WindowState = WindowState.Maximized;
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowState = WindowState.Normal;
|
||||
}
|
||||
|
||||
_rootGrid.ColumnDefinitions[0].Width = new(m.RootGridCol0Width);
|
||||
_modelListGrid.RowDefinitions[0].Height = new(m.ModelListRow0Height);
|
||||
_explorerGrid.RowDefinitions[0].Height = new(m.ExplorerGridRow0Height);
|
||||
_rightPanelGrid.RowDefinitions[0].Height = new(m.RightPanelGridRow0Height);
|
||||
|
||||
_vm.SFMLRendererViewModel.SetResolution(m.ResolutionX, m.ResolutionY);
|
||||
_vm.SFMLRendererViewModel.MaxFps = m.MaxFps;
|
||||
_vm.SFMLRendererViewModel.Speed = m.Speed;
|
||||
_vm.SFMLRendererViewModel.ShowAxis = m.ShowAxis;
|
||||
_vm.SFMLRendererViewModel.BackgroundColor = m.BackgroundColor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void SaveLastState()
|
||||
{
|
||||
var m = new LastStateModel()
|
||||
{
|
||||
WindowLeft = Left,
|
||||
WindowTop = Top,
|
||||
WindowWidth = Width,
|
||||
WindowHeight = Height,
|
||||
WindowState = WindowState,
|
||||
|
||||
RootGridCol0Width = _rootGrid.ColumnDefinitions[0].ActualWidth,
|
||||
ModelListRow0Height = _modelListGrid.RowDefinitions[0].ActualHeight,
|
||||
ExplorerGridRow0Height = _explorerGrid.RowDefinitions[0].ActualHeight,
|
||||
RightPanelGridRow0Height = _rightPanelGrid.RowDefinitions[0].ActualHeight,
|
||||
|
||||
ResolutionX = _vm.SFMLRendererViewModel.ResolutionX,
|
||||
ResolutionY = _vm.SFMLRendererViewModel.ResolutionY,
|
||||
MaxFps = _vm.SFMLRendererViewModel.MaxFps,
|
||||
Speed = _vm.SFMLRendererViewModel.Speed,
|
||||
ShowAxis = _vm.SFMLRendererViewModel.ShowAxis,
|
||||
BackgroundColor = _vm.SFMLRendererViewModel.BackgroundColor,
|
||||
};
|
||||
|
||||
JsonHelper.Serialize(m, LastStateFilePath);
|
||||
}
|
||||
|
||||
#region _spinesListView 事件处理
|
||||
|
||||
private void SpinesListView_RequestSelectionChanging(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
@@ -236,9 +304,7 @@ public partial class MainWindow : Window
|
||||
IntPtr hwnd = new WindowInteropHelper(this).Handle;
|
||||
if (Win32.GetScreenResolution(hwnd, out var resX, out var resY))
|
||||
{
|
||||
var vm = _vm.SFMLRendererViewModel;
|
||||
vm.ResolutionX = resX;
|
||||
vm.ResolutionY = resY;
|
||||
_vm.SFMLRendererViewModel.SetResolution(resX, resY);
|
||||
}
|
||||
|
||||
HandyControl.Controls.IconElement.SetGeometry(_fullScreenButton, AppResource.Geo_ArrowsMinimize);
|
||||
|
||||
Reference in New Issue
Block a user